Adapt your extension for Googlebook OS

Googlebook OS is an operating system for Googlebook devices, built on the Android technology stack and paired with desktop foundations from ChromeOS. Googlebooks support the same WebExtensions platform that exists on Windows, macOS, and ChromeOS, but there are some differences with how they run there.

  • Platform detection is rarely needed, but existing checks can misfire because extension APIs report android while the user agent reports ChromeOS.
  • Native messaging isn't available yet, but it is being worked on. Expect it to route messages to an installed Android app rather than a desktop executable.
  • Keyboard shortcuts use Linux keybindings rather than chromeos entries.
  • SharedArrayBuffer requires opting into cross-origin isolation, and must run in an extension page or offscreen document rather than a service worker.
  • ChromeOS-only APIs aren't supported on Googlebook OS, even though the user agent reports Chrome OS. Extensions that declare these permissions still install, but the API namespaces are undefined at runtime.
  • browser.system.storage isn't supported on Googlebook OS, so the API namespace is undefined at runtime.

Platform detection

Most extensions don't need to detect Googlebook OS. Follow standard web development best practices, such as feature detection and responsive design, rather than checking which operating system the browser runs on.

If your extension already checks the operating system, extension APIs and the user agent return different platforms on Googlebook OS.

  • chrome.runtime.getPlatformInfo().os returns 'android'. If your extension shares code with mobile browsers and assumes 'android' means a phone, Googlebook users will get your mobile UI on a laptop.
  • navigator.userAgent contains CrOS. For general page layout, matching a Chromebook works well. However, navigator.userAgentData.platform returns 'Android', and if your extension checks the user agent to show ChromeOS keyboard shortcut hints (such as the Search key) or to call ChromeOS-only APIs, those checks will misfire on a Googlebook.

The following table compares these signals across platforms.

Signal Googlebook OS Android phone Chromebook Windows, macOS, Linux
runtime.getPlatformInfo().os android android cros mac, win, linux
navigator.userAgentData.platform Android Android Chrome OS Windows, macOS, Linux
navigator.userAgentData.mobile false true false false

In contrast, navigator.userAgent returns an identical reduced user-agent string on both Googlebook OS and ChromeOS, because both platforms report the frozen X11; CrOS x86_64 14541.0.0 platform token.

// Googlebook OS
Mozilla/5.0 (X11; CrOS x86_64 14541.0.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/157.0.0.0 Safari/537.36
// ChromeOS
Mozilla/5.0 (X11; CrOS x86_64 14541.0.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/157.0.0.0 Safari/537.36

As with all web development, platform detection can be unreliable, so only use it when you can't use feature detection to test directly for what you need. If you do need to distinguish Googlebook OS from both an Android phone and a Chromebook, it is possible by combining runtime.getPlatformInfo() with the mobile hint from User-Agent Client Hints.

async function getPlatform() {
  const { os, arch } = await chrome.runtime.getPlatformInfo();
  // userAgentData is undefined in browsers that don't implement User-Agent
  // Client Hints, so read mobile defensively.
  const mobile = navigator.userAgentData?.mobile;
  return {
    os,
    arch,
    isGooglebook: os === 'android' && mobile === false,
    isPhone: os === 'android' && mobile !== false
  };
}

While this particular combination of string comparisons does uniquely point to Googlebook OS devices at the time of product launch, that may not always be the case. As more devices start to ship out over time, in a multitude of form factors there may come a time where some Googlebook OS devices don't match that detection.

To detect Googlebooks from web pages or on the server using client hints, see Identify Googlebooks.

Native messaging

Native messaging isn't available yet on Googlebook OS, but it is being worked on. Expect it to have extensions communicating with installed Android apps rather than local desktop executables. For now, extensions that declare the nativeMessaging permission still install and run on Googlebook OS, but connection attempts fail. Make sure your extension handles connection failures gracefully and falls back to a web-based workflow when the native host is unavailable. Follow issue 555299632 for updates.

Keyboard shortcuts

commands shortcuts follow the same rules as Chrome on Linux. Chrome reads the linux entry of suggested_key on Googlebook OS, so shortcuts defined under chromeos don't apply. Search key combinations don't work either, as there is no "Search" key on Googlebook OS devices.

SharedArrayBuffer

On Windows, macOS, Linux, and ChromeOS, extensions can use SharedArrayBuffer automatically in any context. On Googlebook OS, extensions must explicitly opt into cross-origin isolation in manifest.json to use SharedArrayBuffer.

Opting into cross-origin isolation enables SharedArrayBuffer in extension documents such as popups, options pages, and offscreen documents. However, it doesn't enable SharedArrayBuffer in extension service workers, because Chrome doesn't yet support cross-origin isolation for service workers (issue 40150182). If your background logic relies on SharedArrayBuffer (for example, to run threaded WebAssembly), run that code in an offscreen document instead of your service worker.

ChromeOS-only APIs

APIs marked ChromeOS only in the Chrome Extensions API reference (such as documentScan, fileSystemProvider, vpnProvider, and printing) aren't supported on Googlebook OS, even though navigator.userAgent includes CrOS. Extensions that declare these permissions still install and run, but the API namespaces are undefined at runtime. Check that an API namespace exists before calling it rather than relying on user-agent detection.

browser.system.storage

The browser.system.storage API isn't supported on Googlebook OS. Extensions that declare the system.storage permission in manifest.json still install and run, but the namespace is undefined at runtime. Check whether the API is defined before calling getInfo(), ejectDevice(), or registering storage listeners.