dvWebImplementedBindings top-level constant
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',
};