dvWebImplementedBindings top-level constant

Set<String> const dvWebImplementedBindings

What a browser can genuinely do, given a browser that has the API.

Membership here is a fact about the web platform, not about the tab this is running in. Web NFC, Web Bluetooth and the Contact Picker are Chromium only; the Generic Sensor API needs hardware; Geolocation and the camera are permission-gated. Registration is decided at runtime by probing for the API, and a browser that lacks it leaves the name unregistered so DVNativeBridge.isRegistered keeps telling the truth. Read dvWebUnconditionalBindings for the ones that need no probe.

Implementation

const Set<String> dvWebImplementedBindings = <String>{
  // Fullscreen, Keyboard Lock and Pointer Lock, each needing a user gesture
  // and reported refused, with the browser's reason, when it is absent.
  'kiosk.enforce',
  'kiosk.release',

  // The Fullscreen API on its own, which is what a page that only wants the
  // whole screen is asking for. Registered so isRegistered stops saying the
  // browser cannot go fullscreen while the kiosk path does exactly that.
  'display.enterFullscreen',
  'display.exitFullscreen',

  // navigator.clipboard, which needs a secure context and a user gesture for
  // reads — the failure is reported rather than swallowed.
  'clipboard.copy',
  'clipboard.paste',

  // window.screen.
  'screen.geometry',

  // The Notification API, subject to permission.
  'notifications.sendLocal',

  // Web Push: the PushManager subscription and the messages the generated
  // service worker forwards. Registered only where the browser has the Push
  // API, and only answering once notifications are granted.
  'push.token',
  'push.unsubscribe',
  'push.drainMessages',

  // navigator.share, which Firefox on the desktop does not have. Probed, so
  // that browser leaves the name unregistered rather than throwing a
  // TypeError from inside the binding.
  'share.text',

  // navigator.vibrate. One primitive serves all three: the web has no notion
  // of impact weight, so the distinction is expressed as duration. Safari
  // has no vibrate at all, on any device.
  'haptics.vibrate',
  'haptics.lightVibrate',
  'haptics.impact',

  // document.title.
  'window.setTitle',

  // The browser's own install dialog, and the answer the person gave it.
  'install.prompt',

  // The URL the tab was opened with. A deep link on the web is the address
  // bar, which is the one target where this needs no plumbing at all.
  'deepLinks.initial',

  // Three availability questions the browser can answer, through
  // PublicKeyCredential, navigator.bluetooth and NDEFReader. Each answers
  // false when the browser lacks the API, which is a true statement about
  // the platform rather than a plausible default.
  'biometrics.canAuthenticate',
  'bluetooth.isEnabled',
  'nfc.isAvailable',

  // WebAuthn with userVerification required, which is the browser's platform
  // biometric flow. It throws when there is no authenticator or the person
  // declines; it never reports success it did not get.
  'biometrics.authenticate',

  // The Geolocation API. Denial is a DVWebPermissionDenied rather than a
  // pair of zeroes, because 0,0 is in the Gulf of Guinea and looks like an
  // answer.
  'location.current',

  // The Permissions API for reading a state, and each capability's own
  // request path for asking. There is no navigator.permissions.request();
  // the browser makes you ask through the API you want.
  'permissions.isGranted',
  'permissions.request',

  // <input type="file">, which every browser has had for twenty years. The
  // picked files come back as bytes rather than as paths — see the note on
  // dialogs.openFile below for why a fabricated path would be worse.
  'media.pick',

  // Drops onto the page: File objects arrive with their bytes in
  // DVDropEvent.files (a page is never given a path), text as text.
  'dragDrop.accept',
  'dragDrop.stop',

  // The origin-private file system, through navigator.storage.getDirectory.
  // A real filesystem with real paths, private to the origin, and present in
  // Chrome, Firefox and Safari.
  'files.readBytes',
  'files.writeBytes',
  'files.delete',

  // getUserMedia, one frame, encoded by a canvas. ImageCapture would give a
  // better frame and is Chromium-only, so it is used when it is there.
  'camera.takePhoto',

  // The Generic Sensor API. Chromium only, and only where the hardware is.
  'sensors.accelerometer',
  'sensors.gyroscope',

  // The Contact Picker API: Chrome on Android, and nowhere else at all.
  'contacts.getContacts',

  // Web NFC, which is also Chrome on Android alone.
  'nfc.readTag',
  'nfc.writeTag',

  // Web Bluetooth. What it has is a chooser and the devices already granted
  // through one; what it has no concept of is an adapter or a pairing, so
  // those two names are in the unavailable list with their reasons.
  'bluetooth.scanDevices',
  'bluetooth.devices',
  'bluetooth.connect',
  'bluetooth.disconnect',
  'bluetooth.forget',

  // What the browser will say about the machine: cores, memory, storage,
  // the battery and the network. Less than sysfs gives, and honest about
  // which parts this browser withheld.
  'device.capabilityManifest',
  'device.health',
  'device.diagnostics.collect',

  // window.alert, which is the browser's message dialog whether or not
  // anybody likes it.
  'dialogs.message',
};