Skip to content
Visor Developers

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.