// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
module ash.bluetooth_config.mojom;
import "mojo/public/mojom/base/string16.mojom";
import "url/mojom/url.mojom";
// The maximum number of characters a Bluetooth device's nickname can be set
// to.
const uint8 kDeviceNicknameCharacterLimit = 32;
// State of Bluetooth on the device.
enum BluetoothSystemState {
// Device does not have access to Bluetooth.
kUnavailable,
// Bluetooth is turned off.
kDisabled,
// Bluetooth is in the process of turning off.
kDisabling,
// Bluetooth is turned on.
kEnabled,
// Bluetooth is in the process of turning on.
kEnabling
};
// State of whether Bluetooth can be modified.
enum BluetoothModificationState {
// Bluetooth cannot be turned on/off, and devices cannot be connected. E.g.,
// the current session may belong to a secondary user, or the screen is
// locked.
kCannotModifyBluetooth,
// Bluetooth settings can be modified as part of the current session.
kCanModifyBluetooth
};
// Bluetooth device type, derived from the device's ClassOfDevice attribute.
enum DeviceType {
kUnknown,
kComputer,
kPhone,
kHeadset,
kVideoCamera,
kGameController,
kKeyboard,
kKeyboardMouseCombo,
kMouse,
kTablet
};
// Audio capability, derived from the device's ClassOfDevice attribute.
enum AudioOutputCapability {
// Cannot provide audio output.
kNotCapableOfAudioOutput,
// Can output audio (e.g., Bluetooth headset).
kCapableOfAudioOutput
};
enum DeviceConnectionState {
kNotConnected,
kConnecting,
kConnected
};
struct BatteryProperties {
// From 0 to 100.
uint8 battery_percentage;
};
// Battery info belonging to a device. Contains an optional "default" set of
// properties, and may contain information about multiple batteries per device
// (e.g., Pixel Buds include battery info about the left earbud, right earbud,
// and case).
struct DeviceBatteryInfo {
BatteryProperties? default_properties;
BatteryProperties? left_bud_info;
BatteryProperties? right_bud_info;
BatteryProperties? case_info;
};
// True Wireless image info belonging to a device. Contains fields for
// True Wireless images (stored as base64-encoded data URLs) for the left
// earbud, right earbud, and case.
struct TrueWirelessImageInfo {
url.mojom.Url left_bud_image_url;
url.mojom.Url right_bud_image_url;
url.mojom.Url case_image_url;
};
// Image info belonging to a device. Contains an optional default image (stored
// as a base64-encoded data URL) as well as optional True Wireless images.
struct DeviceImageInfo {
url.mojom.Url? default_image_url;
TrueWirelessImageInfo? true_wireless_images;
};
// Properties belonging to a Bluetooth device.
struct BluetoothDeviceProperties {
// Unique identifier for this device, which is stable across device reboots.
string id;
// The Bluetooth address of this device.
string address;
// Publicly-visible name provided by the device. If no name is provided by
// the device, the device address is used as a name.
mojo_base.mojom.String16 public_name;
// Device type, derived from the ClassOfDevice attribute for the device.
DeviceType device_type;
// Audio output capability of the device; note that this capability is
// independent of the device type.
AudioOutputCapability audio_capability;
// Null if no battery information is available for the device.
DeviceBatteryInfo? battery_info;
// Null if no device images are available for the device.
DeviceImageInfo? image_info;
DeviceConnectionState connection_state;
// Indicates if the device is blocked by an admin policy.
bool is_blocked_by_policy;
};
// Fast Pairable Device's current pairing state. No success state is necessary,
// as a paired Fast Pair device becomes a standard Paired device.
enum FastPairableDevicePairingState {
kReady,
kPairing,
kError
};
// Properties belonging to a Bluetooth device which has been paired to this
// Chrome OS device.
struct PairedBluetoothDeviceProperties {
BluetoothDeviceProperties device_properties;
// Nickname for this device as provided by the user. Local to the device
// (i.e., other devices do not have access to this name). Null if the
// device has not been nicknamed by the user.
string? nickname;
// The existence of this field denotes this device is a Fast Pairable
// device, i.e. one that is linked to the user's account but not paired to
// this Chromebook. Used to communicate the pairing state to the UI.
FastPairableDevicePairingState? fast_pairable_device_pairing_state;
};
// Describes the high-level status of system Bluetooth.
struct BluetoothSystemProperties {
BluetoothSystemState system_state;
BluetoothModificationState modification_state;
// List of paired devices. UI surfaces should display devices in the order
// indicated by this array.
array<PairedBluetoothDeviceProperties> paired_devices;
// Devices detected by Fast Pair that are available to pair.
array<PairedBluetoothDeviceProperties> fast_pairable_devices;
};
// Observer for changes to Bluetooth system properties.
interface SystemPropertiesObserver {
// Invoked whenever any property changes, including whenever a property of a
// paired device changes (e.g., from connected to disconnected).
OnPropertiesUpdated(BluetoothSystemProperties properties);
};
// Observer for changes to Bluetooth device status.
// Clients include:
// * Ash system UI; implemented in C++ as part of the browser process
interface BluetoothDeviceStatusObserver {
// Invoked when a device has been newly-paired.
OnDevicePaired(PairedBluetoothDeviceProperties device);
// Invoked when a device has been connected.
OnDeviceConnected(PairedBluetoothDeviceProperties device);
// Invoked when a device has been disconnected.
OnDeviceDisconnected(PairedBluetoothDeviceProperties device);
};
// Observer for changes to starting/stopping Discovery Sessions.
interface DiscoverySessionStatusObserver {
// Invoked when the number of discovery sessions changes from 0 to 1
// or vice versa.
OnHasAtLeastOneDiscoverySessionChanged(
bool has_at_least_one_discovery_session);
};
// Provided to the pairing UI to handle keys that have been entered
// on the user's keyboard during a pairing attempt which requires
// that the user types in a PIN or passkey.
//
// Not all keyboard support providing "key entered" events, so it
// is possible that KeyEnteredHandlers never have their functions
// invoked.
interface KeyEnteredHandler {
// Invoked when the user has typed a portion of the PIN or
// passkey. For example, if the PIN is "987654" and the user types
// "9" and "8", HandleKeyEntered(1) and HandleKeyEntered(2) would
// be called.
HandleKeyEntered(uint8 num_keys_entered);
};
// Provided by the pairing UI to handle pairing requests of
// different types.
interface DevicePairingDelegate {
// Requests that a PIN be provided to complete pairing.
RequestPinCode() => (string pin_code);
// Requests that a passkey be provided to complete pairing.
RequestPasskey() => (string passkey);
// Requests that |pin_code| be displayed to the user, who should
// enter the PIN via a Bluetooth keyboard.
DisplayPinCode(string pin_code,
pending_receiver<KeyEnteredHandler> handler);
// Requests that |passkey| be displayed to the user, who should
// enter the passkey via a Bluetooth keyboard.
DisplayPasskey(string passkey,
pending_receiver<KeyEnteredHandler> handler);
// Requests that |passkey| be displayed to the user, who should
// confirm or reject a pairing request. Returns whether or not the
// user confirmed the passkey.
ConfirmPasskey(string passkey) => (bool confirmed);
// Requests that the user is asked to confirm or reject a pairing
// request. Returns whether or not the user confirmed the pairing.
AuthorizePairing() => (bool confirmed);
};
// Result of a pairing attempt.
enum PairingResult {
// Pairing succeeded.
kSuccess,
// Authentication failed, either due to an incorrect PIN/passkey or
// due to the remote device canceling authentication.
kAuthFailed,
// Pairing failed due to a reason other than authentication issues.
kNonAuthFailure
};
// Handles requests to pair to a device.
interface DevicePairingHandler {
// Attempts to pair to the device with ID |device_id|. Pairing often
// requires additional interaction from the user, so callers must
// provide a |delegate| which handles requests for these interactions.
// For example, pairing a Bluetooth keyboard usually requires that
// users type in a PIN.
//
// |result| is returned when the pairing attempt completes. It is
// possible that |result| is returned before any delegate function
// is invoked.
// Only one pairing request should be made at a time. If a second request
// is made while a request is pending the second request will return with
// mojom::PairingResult::kNonAuthFailure.
PairDevice(
string device_id,
pending_remote<DevicePairingDelegate> delegate) =>
(PairingResult result);
// Returns the device with address |device_address|. This can be used
// to find the ID of a device where only its address is known in order
// to pair with it. Returns null if no device was found. Devices
// returned here may not be found in BluetoothDiscoveryDelegate's
// discovered devices list as this method retrieves the devices from the
// adapter directly without any filtering.
FetchDevice(string device_address) => (BluetoothDeviceProperties? device);
};
// Allows clients of Bluetooth discovery to be notified of the progress of a
// discovery session.
interface BluetoothDiscoveryDelegate {
// Invoked when discovery has started.
// |handler| can be used to initiate pairing to a discovered device.
OnBluetoothDiscoveryStarted(
pending_remote<DevicePairingHandler> handler);
// Invoked when discovery has stopped. This can occur for a variety of
// reasons, including:
// * Discovery was attempted while Bluetooth was not enabled.
// * Bluetooth was turned off while the discovery session was active.
// * Internal errors while discovering.
OnBluetoothDiscoveryStopped();
// Invoked when the devices list changes. This function is called whenever
// a device is added, removed, or updated in the list. When a client first
// begins discovery, this function is immediately called.
OnDiscoveredDevicesListChanged(
array<BluetoothDeviceProperties> discovered_devices);
};
// Provides Bluetooth metadata and controls. Embedded in the browser process.
//
// Clients include:
// * Ash system UI; implemented in C++ as part of the browser process
// * WebUI such as chrome://os-settings; implemented in JS as part of renderer
// processes
interface CrosBluetoothConfig {
// Invokes OnPropertiesUpdated() with initial set of properties when observer
// is first added, then again whenever properties are updated. To stop
// observing, disconnect |observer|.
ObserveSystemProperties(pending_remote<SystemPropertiesObserver> observer);
// Invokes OnDevicePaired() when a device is newly paired, connected or
// disconnected. To stop observing, disconnect |observer|.
ObserveDeviceStatusChanges(
pending_remote<BluetoothDeviceStatusObserver> observer);
// Invokes OnHasAtLeastOneDiscoverySessionChanged() when the number of
// discovery sessions changes from 0 to 1 or vice versa. To stop observing,
// disconnect |observer|.
ObserveDiscoverySessionStatusChanges(
pending_remote<DiscoverySessionStatusObserver> observer);
// Turns Bluetooth on or off. If Bluetooth is unavailable or if it is
// not currently modifiable, this function is a no-op.
SetBluetoothEnabledState(bool enabled);
// Turns Bluetooth on without persisting the enabled state to prefs.
SetBluetoothEnabledWithoutPersistence();
// If |is_using_bluetooth| is false, restores the Bluetooth enabled
// state that was last persisted to local state. If |is_using_bluetooth|
// is true, this function is a no-op. |is_using_bluetooth| should be set
// to true if there is at least one HID that is connected via Bluetooth,
// and false otherwise.
SetBluetoothHidDetectionInactive(bool is_using_bluetooth);
// Starts a discovery session, during which time it will be possible
// to find new devices and pair them. To stop discovery, disconnect
// |delegate|.
StartDiscovery(pending_remote<BluetoothDiscoveryDelegate> delegate);
// Initiates a connection to the device with ID |device_id|.
Connect(string device_id) => (bool success);
// Initiates a disconnection from the device with ID |device_id|.
Disconnect(string device_id) => (bool success);
// Forgets the device with ID |device_id|, which in practice means
// un-pairing from the device.
Forget(string device_id) => (bool success);
// Sets a |nickname| for the device with ID |device_id|. The nickname is
// visible to all users of the device.
SetDeviceNickname(string device_id, string nickname);
};