Scopes and consent
An app can use only what the person allowed. Visor checks every call and every stream against the app's scopes, which the person grants on Visor's consent screen. Nothing else is needed: no setting to turn on, no Developer mode.
The scopes
| Scope | Lets the app | Methods and topics |
|---|---|---|
state |
See whether the glasses are connected, worn and charged | glasses.status |
pairs |
See every pair set up in Visor, with names and looks, and choose which one Visor connects to | glasses.pairs, glasses.select |
inputs |
Know when the wearer taps or swipes the touchpad or presses a button | glasses.inputs |
motion |
Read how the glasses and the band move | glasses.motion, band.motion |
microphone |
Turn what the glasses' microphones hear into text | voice.transcripts |
camera |
Take photos and videos, and copy them to the phone | camera.*, captures.* |
band |
Read the Neural Band's gestures and make it vibrate | band.status, band.gestures, band.buzz |
display |
Show layouts, cards of the app's own and the teleprompter on the Display | display.* |
voice |
Answer the questions the wearer asks that name the app | voice.* |
assistant |
Give the assistant tools it can use while it answers | assistant.* |
notify |
Show notifications on the Display | notify.* |
settings |
Read the glasses' settings and change the everyday ones | settings.* |
conversations |
Read what the wearer asks the assistant and what it answers | assistant.turns, assistant.history |
raw |
Send and read the glasses' own protocol messages, for research; only with Developer mode on | raw.* |
kit.hello needs no scope. Later releases add scopes; an app built against an older VDK never sees them unless
it asks for them by id.
Asking
RequestScopes opens Visor's consent screen over your app. The screen names your app, as the launcher shows it,
and lists only the scopes it does not hold yet. The person allows all of them or none: Allow keeps them,
Only this time gives them until your app closes its last connection to Visor (DAT's Allow once), and Don't
allow gives none.
val ask = registerForActivityResult(RequestScopes()) { held -> }
ask.launch(setOf(Scope.CAMERA, Scope.BAND))
The result is every scope your app holds once the person is done, also when they just go back. A scope this Visor does not know is never granted, so it is missing from the result.
Launching throws ActivityNotFoundException when Visor is not installed. Check Visor.isInstalled(context)
first.
When a scope is missing
A call that needs a scope the app does not hold fails with scope_denied, and KitException.scope names the
scope:
catch (e: KitException) {
if (e.code == ErrorCode.SCOPE_DENIED) ask.launch(setOf(e.scope!!))
}
A stream started without its scope ends at once with the same failure. Collect it again after the person allows it.
Taking scopes back
The person sees every app that holds scopes in Visor, under Settings, Advanced settings, Apps with access, and can remove an app's access there. When that happens:
- the app's open streams end with
scope_denied; - its next calls fail the same way;
- calls already running finish.
Programs and web apps
Programs on the network door and web apps on the Display do not use the consent
screen: the person picks their scopes in Visor, when they make a network client, or in Settings > Web apps for a
web app. Their calls fail with scope_denied the same way, and taking a scope back ends their streams at once.
Who an app is
Visor learns which app calls from Android, by the calling uid, and ties each grant to the app's package and to the certificate it is signed with. If a different app is later installed under the same package name with another certificate, it holds nothing. Your debug and release builds are signed with different certificates, so each one asks for its own grant.
While you develop
visor grant and visor revoke set an app's scopes from your computer, without the consent screen:
visor grant com.example.app camera band
visor revoke com.example.app band
visor apps
See Testing.