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](https://developer.chrome.com/docs/extensions/how-to/googlebook.md.txt#identity) is rarely needed, but existing checks can misfire because extension APIs report `android` while the user agent reports ChromeOS.
- [Native messaging](https://developer.chrome.com/docs/extensions/how-to/googlebook.md.txt#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](https://developer.chrome.com/docs/extensions/how-to/googlebook.md.txt#commands) use Linux keybindings rather than `chromeos` entries.
- [`SharedArrayBuffer`](https://developer.chrome.com/docs/extensions/how-to/googlebook.md.txt#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](https://developer.chrome.com/docs/extensions/how-to/googlebook.md.txt#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`](https://developer.chrome.com/docs/extensions/how-to/googlebook.md.txt#system-storage) isn't supported on Googlebook OS, so the API namespace is `undefined` at runtime.

> [!NOTE]
> **Note:** This guide covers Chrome extensions. If you also build an Android app, see [Googlebook on Android
> Developers](https://developer.android.com/googlebook).

## 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](https://www.chromium.org/updates/ua-reduction/) on both Googlebook OS
and ChromeOS, because both platforms report the frozen `X11; CrOS x86_64
14541.0.0` platform token.

```text
// 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()`](https://developer.chrome.com/docs/extensions/reference/api/runtime.md.txt#method-getPlatformInfo)
with the `mobile` hint from [User-Agent Client
Hints](https://developer.mozilla.org/docs/Web/API/User-Agent_Client_Hints_API).

```javascript
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](https://developer.chrome.com/docs/android/identify-googlebooks.md.txt).

## Native messaging

[Native messaging](https://developer.chrome.com/docs/extensions/develop/concepts/native-messaging.md.txt) 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](https://crbug.com/555299632) for updates.

## Keyboard shortcuts

[`commands`](https://developer.chrome.com/docs/extensions/reference/api/commands.md.txt) 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](https://developer.chrome.com/docs/extensions/develop/concepts/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](https://developer.chrome.com/docs/extensions/reference/api/offscreen). However, it doesn't enable
`SharedArrayBuffer` in extension service workers, because Chrome doesn't yet
support cross-origin isolation for service workers ([issue
40150182](https://crbug.com/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](https://developer.chrome.com/docs/extensions/reference/api.md.txt) 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`](https://developer.chrome.com/docs/extensions/reference/api/system/storage.md.txt)
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.