blob: b2746bd3817b6d3a295f13364184b6a1d4b66f04 [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2016 The Chromium Authors
ortunoad6b0fea2016-03-31 18:49:112// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CONTENT_BROWSER_BLUETOOTH_WEB_BLUETOOTH_SERVICE_IMPL_H_
6#define CONTENT_BROWSER_BLUETOOTH_WEB_BLUETOOTH_SERVICE_IMPL_H_
7
ortunobc3bce12016-04-15 21:22:558#include <memory>
Arthur Sonzognic686e8f2024-01-11 08:36:379#include <optional>
ortunobc3bce12016-04-15 21:22:5510#include <string>
Ovidio Henriquez278801c22020-03-10 21:52:0111#include <unordered_map>
ortunobc3bce12016-04-15 21:22:5512#include <vector>
13
Avi Drissmanadac21992023-01-11 23:46:3914#include "base/functional/callback.h"
Jun Caie27db6b2019-06-05 03:52:1515#include "base/gtest_prod_util.h"
Andy Paicu1d7fc172021-01-20 18:29:4516#include "base/scoped_observation.h"
Chris Mumford4d1cf30782021-10-05 23:02:4717#include "build/build_config.h"
ortunoad6b0fea2016-03-31 18:49:1118#include "content/browser/bad_message.h"
Chris Mumford02de39b2021-05-06 15:28:5919#include "content/browser/bluetooth/web_bluetooth_pairing_manager_delegate.h"
Matt Reynolds8cca57d52025-02-20 18:20:5920#include "content/browser/renderer_host/render_frame_host_impl.h"
ortunoad6b0fea2016-03-31 18:49:1121#include "content/common/content_export.h"
Andy Paicu1d7fc172021-01-20 18:29:4522#include "content/public/browser/bluetooth_delegate.h"
Jun Cai149002e2019-05-09 23:13:0723#include "content/public/browser/bluetooth_scanning_prompt.h"
Daniel Chengd6978b062023-11-16 00:11:3824#include "content/public/browser/document_user_data.h"
ortunobc3bce12016-04-15 21:22:5525#include "content/public/browser/web_contents_observer.h"
26#include "device/bluetooth/bluetooth_adapter.h"
Henrique Ferreirodb47b3e2019-09-11 14:29:3927#include "mojo/public/cpp/bindings/associated_remote.h"
28#include "mojo/public/cpp/bindings/pending_associated_remote.h"
29#include "mojo/public/cpp/bindings/pending_receiver.h"
30#include "mojo/public/cpp/bindings/receiver.h"
Julie Jeongeun Kim4f1b5aa2019-05-08 01:32:0931#include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom.h"
ortunoad6b0fea2016-03-31 18:49:1132
33namespace url {
34class Origin;
35} // namespace url
36
Lei Zhang5874c7e2021-07-16 01:39:4937namespace device {
38class BluetoothDiscoverySession;
39class BluetoothGattConnection;
40class BluetoothGattNotifySession;
41class BluetoothRemoteGattCharacteristic;
42class BluetoothUUID;
43} // namespace device
44
ortunoad6b0fea2016-03-31 18:49:1145namespace content {
46
Lei Zhang5874c7e2021-07-16 01:39:4947class BluetoothAllowedDevices;
ortunob6374dd82016-05-27 03:04:0748class BluetoothDeviceChooserController;
Jun Cai149002e2019-05-09 23:13:0749class BluetoothDeviceScanningPromptController;
juncai00441ebd2017-01-09 19:14:5150struct CacheQueryResult;
ortunob6c45d4f2016-05-07 04:19:4251class FrameConnectedBluetoothDevices;
juncai5fbf7e62017-03-23 21:21:5652struct GATTNotifySessionAndCharacteristicClient;
ortunoad6b0fea2016-03-31 18:49:1153class RenderProcessHost;
Chris Mumford4d1cf30782021-10-05 23:02:4754class WebBluetoothPairingManager;
ortunoad6b0fea2016-03-31 18:49:1155
Md. Hasanur Rashid28c84952020-01-05 11:36:3656bool HasValidFilter(
Arthur Sonzognic686e8f2024-01-11 08:36:3757 const std::optional<std::vector<blink::mojom::WebBluetoothLeScanFilterPtr>>&
58 filters);
Doug Turner9b931de2019-01-08 18:22:3759
ortunoad6b0fea2016-03-31 18:49:1160// Implementation of Mojo WebBluetoothService located in
Sina Firoozabadi36a29bc2023-03-08 02:29:3661// third_party/blink/renderer/modules/bluetooth.
ortunoad6b0fea2016-03-31 18:49:1162// It handles Web Bluetooth API requests coming from Blink / renderer
63// process and uses the platform abstraction of device/bluetooth.
64// WebBluetoothServiceImpl is not thread-safe and should be created on the
65// UI thread as required by device/bluetooth.
66// This class is instantiated on-demand via Mojo's ConnectToRemoteService
67// from the renderer when the first Web Bluetooth API request is handled.
ortuno77bb42c2016-08-01 18:41:0968class CONTENT_EXPORT WebBluetoothServiceImpl
Daniel Chengd6978b062023-11-16 00:11:3869 : public blink::mojom::WebBluetoothService,
70 public DocumentUserData<WebBluetoothServiceImpl>,
ortuno77bb42c2016-08-01 18:41:0971 public WebContentsObserver,
Andy Paicu1d7fc172021-01-20 18:29:4572 public device::BluetoothAdapter::Observer,
Chris Mumford02de39b2021-05-06 15:28:5973 public BluetoothDelegate::FramePermissionObserver,
74 public WebBluetoothPairingManagerDelegate {
ortunoad6b0fea2016-03-31 18:49:1175 public:
Chris Mumford02de39b2021-05-06 15:28:5976 static blink::mojom::WebBluetoothResult TranslateConnectErrorAndRecord(
77 device::BluetoothDevice::ConnectErrorCode error_code);
78
Daniel Chengd6978b062023-11-16 00:11:3879 // Binds `receiver` to `WebBluetoothServiceImpl` for the currently active
80 // document for `render_frame_host`, if no security checks fail. See
81 // `DocumentUserData` for additional details about lifetime.
82 static void BindIfAllowed(
83 RenderFrameHost* render_frame_host,
84 mojo::PendingReceiver<blink::mojom::WebBluetoothService> receiver);
85
86 // Wrapper around `BindIfAllowed()` that also returns the created
87 // WebBluetoothServiceImpl, if any.
88 static WebBluetoothServiceImpl* CreateForTesting(
Henrique Ferreirodb47b3e2019-09-11 14:29:3989 RenderFrameHost* render_frame_host,
90 mojo::PendingReceiver<blink::mojom::WebBluetoothService> receiver);
Peter Boström828b9022021-09-21 02:28:4391
Gabriel Britobf12a4e2022-02-03 21:46:3392 // Calling this methods prevents WebBluetoothServiceImpl from clearing up its
93 // WatchAdvertisement clients when the window either loses focus or becomes
94 // hidden or occluded. This method is meant to be called from browser tests to
95 // prevent flakiness.
96 static void IgnoreVisibilityRequirementsForTesting();
97
Daniel Chengd6978b062023-11-16 00:11:3898 ~WebBluetoothServiceImpl() override;
99
Peter Boström828b9022021-09-21 02:28:43100 WebBluetoothServiceImpl(const WebBluetoothServiceImpl&) = delete;
101 WebBluetoothServiceImpl& operator=(const WebBluetoothServiceImpl&) = delete;
102
Daniel Chengd6978b062023-11-16 00:11:38103 // Prefer `receiver_.ReportBadMessage()` in new code. Existing callers should
104 // be migrated as well.
105 void ReceivedBadMessage(bad_message::BadMessageReason reason);
ortunob6374dd82016-05-27 03:04:07106
Ovidio Henriquez62154472019-08-21 14:45:11107 // Checks the current requesting and embedding origins as well as the policy
108 // or global Web Bluetooth block to determine if Web Bluetooth is allowed.
109 // Returns |SUCCESS| if Bluetooth is allowed.
110 blink::mojom::WebBluetoothResult GetBluetoothAllowed();
111
juncai87d09292016-09-15 04:02:53112 // Returns whether the device is paired with the |render_frame_host_|'s
113 // GetLastCommittedOrigin().
114 bool IsDevicePaired(const std::string& device_address);
115
Jun Cai149002e2019-05-09 23:13:07116 // Informs each client in |scanning_clients_| of the user's permission
117 // decision.
118 void OnBluetoothScanningPromptEvent(
119 BluetoothScanningPrompt::Event event,
120 BluetoothDeviceScanningPromptController* prompt_controller);
121
Andy Paicu1d7fc172021-01-20 18:29:45122 // BluetoothDelegate::FramePermissionObserverimplementation:
Andy Paicu13f3f462021-03-09 12:14:56123 void OnPermissionRevoked(const url::Origin& origin) override;
Andy Paicu1d7fc172021-01-20 18:29:45124 content::RenderFrameHost* GetRenderFrameHost() override;
125
Chris Mumford4d1cf30782021-10-05 23:02:47126#if PAIR_BLUETOOTH_ON_DEMAND()
127 void SetPairingManagerForTesting(
128 std::unique_ptr<WebBluetoothPairingManager> pairing_manager);
129#endif // PAIR_BLUETOOTH_ON_DEMAND()
130
ortunoad6b0fea2016-03-31 18:49:11131 private:
Daniel Chengd6978b062023-11-16 00:11:38132 friend DocumentUserData;
Claudio DeSouza3b4ad052021-11-23 02:32:43133
Daniel Chengd6978b062023-11-16 00:11:38134 DOCUMENT_USER_DATA_KEY_DECL();
135
136 // `render_frame_host`: The RFH of the document that owns this instance.
137 explicit WebBluetoothServiceImpl(RenderFrameHost* render_frame_host);
Claudio DeSouza3b4ad052021-11-23 02:32:43138
Reilly Granta255d1be2019-11-14 07:01:05139 FRIEND_TEST_ALL_PREFIXES(WebBluetoothServiceImplTest,
Claudio DeSouza3b4ad052021-11-23 02:32:43140 DestroyedDuringRequestDevice);
Ovidio Henriquez00defd22019-12-12 22:49:56141 FRIEND_TEST_ALL_PREFIXES(WebBluetoothServiceImplTest,
Claudio DeSouza3b4ad052021-11-23 02:32:43142 DestroyedDuringRequestScanningStart);
Jun Cai10d96962019-06-18 21:51:39143 FRIEND_TEST_ALL_PREFIXES(WebBluetoothServiceImplTest, PermissionAllowed);
144 FRIEND_TEST_ALL_PREFIXES(WebBluetoothServiceImplTest,
145 PermissionPromptCanceled);
Jun Caie27db6b2019-06-05 03:52:15146 FRIEND_TEST_ALL_PREFIXES(WebBluetoothServiceImplTest,
147 BluetoothScanningPermissionRevokedWhenTabHidden);
148 FRIEND_TEST_ALL_PREFIXES(WebBluetoothServiceImplTest,
149 BluetoothScanningPermissionRevokedWhenTabOccluded);
Jun Caia1f8bf25d92019-06-07 19:06:53150 FRIEND_TEST_ALL_PREFIXES(WebBluetoothServiceImplTest,
151 BluetoothScanningPermissionRevokedWhenBlocked);
Ovidio Henriquez5bfc18162020-03-24 16:17:27152 FRIEND_TEST_ALL_PREFIXES(WebBluetoothServiceImplTest,
153 BluetoothScanningPermissionRevokedWhenFocusIsLost);
Chris Mumford6627ae42021-05-03 18:54:40154 FRIEND_TEST_ALL_PREFIXES(WebBluetoothServiceImplTest,
155 ReadCharacteristicValueErrorWithValueIgnored);
Julie Jeongeun Kim8a889c762021-07-15 08:41:26156 FRIEND_TEST_ALL_PREFIXES(WebBluetoothServiceImplBrowserTest,
157 NoShowBluetoothScanningPromptInPrerendering);
Chris Mumforde6fa96a42021-07-20 00:15:14158 FRIEND_TEST_ALL_PREFIXES(WebBluetoothServiceImplTest,
159 DeferredStartNotifySession);
Jack Hsiehadebefb2022-02-15 18:57:53160 FRIEND_TEST_ALL_PREFIXES(WebBluetoothServiceImplTest, DeviceDisconnected);
161 FRIEND_TEST_ALL_PREFIXES(WebBluetoothServiceImplTest,
162 DeviceGattServicesDiscoveryTimeout);
Alvin Jif4c234d412023-08-23 16:58:54163 FRIEND_TEST_ALL_PREFIXES(WebBluetoothServiceImplTest,
164 TwoWatchAdvertisementsReqSuccess);
165 FRIEND_TEST_ALL_PREFIXES(WebBluetoothServiceImplTest,
166 TwoWatchAdvertisementsReqFail);
167 FRIEND_TEST_ALL_PREFIXES(WebBluetoothServiceImplTest,
168 SecWatchAdvertisementsReqAfterFirstSuccess);
Alex N. Josed1930d82024-08-13 21:36:07169 FRIEND_TEST_ALL_PREFIXES(WebBluetoothServiceImplTestWithBaseAdapter,
170 EmulatedAdapterRemovalRestoresOriginalAdapter);
Alex N. Josea036a382024-08-15 23:29:13171 FRIEND_TEST_ALL_PREFIXES(WebBluetoothServiceImplTest,
172 ServiceDestroyedDuringAdapterAcquisition);
Alvin Jif4c234d412023-08-23 16:58:54173
Chris Mumford4d1cf30782021-10-05 23:02:47174#if PAIR_BLUETOOTH_ON_DEMAND()
Alvin Ji40288acb2022-05-23 18:18:40175 FRIEND_TEST_ALL_PREFIXES(WebBluetoothServiceImplTest,
Chris Mumford4d1cf30782021-10-05 23:02:47176 ReadCharacteristicValueNotAuthorized);
Alvin Ji40288acb2022-05-23 18:18:40177 FRIEND_TEST_ALL_PREFIXES(WebBluetoothServiceImplTest,
Reilly Grant12e53d92022-01-13 00:58:37178 IncompletePairingOnShutdown);
Chris Mumford4d1cf30782021-10-05 23:02:47179#endif // PAIR_BLUETOOTH_ON_DEMAND()
Julie Jeongeun Kim8a889c762021-07-15 08:41:26180
ortuno77bb42c2016-08-01 18:41:09181 friend class FrameConnectedBluetoothDevicesTest;
Jun Caie27db6b2019-06-05 03:52:15182 friend class WebBluetoothServiceImplTest;
Alex N. Josed1930d82024-08-13 21:36:07183 friend class WebBluetoothServiceImplTestWithBaseAdapter;
184
tzikcf7bcd652017-06-15 04:19:30185 using PrimaryServicesRequestCallback =
186 base::OnceCallback<void(device::BluetoothDevice*)>;
Jun Cai732a05e32019-05-29 19:34:19187 using ScanFilters = std::vector<blink::mojom::WebBluetoothLeScanFilterPtr>;
ortuno67acd832016-04-30 00:13:22188
Ovidio Henriquez887bb132020-06-04 21:45:55189 class AdvertisementClient;
190 class WatchAdvertisementsClient;
191 class ScanningClient;
Chris Mumforde6fa96a42021-07-20 00:15:14192 struct DeferredStartNotificationData;
Doug Turner9b931de2019-01-08 18:22:37193
Daniel Chengd6978b062023-11-16 00:11:38194 // Returns false if `this` is already bound.
195 bool Bind(mojo::PendingReceiver<blink::mojom::WebBluetoothService> receiver);
196
ortunobc3bce12016-04-15 21:22:55197 // WebContentsObserver:
198 // These functions should always check that the affected RenderFrameHost
Claudio DeSouza3b4ad052021-11-23 02:32:43199 // is this->render_frame_host() and not some other frame in the same tab.
Jun Caie27db6b2019-06-05 03:52:15200 void OnVisibilityChanged(Visibility visibility) override;
Ovidio Henriquez5bfc18162020-03-24 16:17:27201 void OnWebContentsLostFocus(RenderWidgetHost* render_widget_host) override;
ortunobc3bce12016-04-15 21:22:55202
203 // BluetoothAdapter::Observer:
ortunob6374dd82016-05-27 03:04:07204 void AdapterPoweredChanged(device::BluetoothAdapter* adapter,
205 bool powered) override;
206 void DeviceAdded(device::BluetoothAdapter* adapter,
207 device::BluetoothDevice* device) override;
ortunob6c45d4f2016-05-07 04:19:42208 void DeviceChanged(device::BluetoothAdapter* adapter,
209 device::BluetoothDevice* device) override;
Doug Turner23a658b92018-12-20 01:57:54210 void DeviceAdvertisementReceived(
211 const std::string& device_address,
Arthur Sonzognic686e8f2024-01-11 08:36:37212 const std::optional<std::string>& device_name,
213 const std::optional<std::string>& advertisement_name,
214 std::optional<int8_t> rssi,
215 std::optional<int8_t> tx_power,
216 std::optional<uint16_t> appearance,
Doug Turner23a658b92018-12-20 01:57:54217 const device::BluetoothDevice::UUIDList& advertised_uuids,
218 const device::BluetoothDevice::ServiceDataMap& service_data_map,
219 const device::BluetoothDevice::ManufacturerDataMap& manufacturer_data_map)
220 override;
ortuno67acd832016-04-30 00:13:22221 void GattServicesDiscovered(device::BluetoothAdapter* adapter,
222 device::BluetoothDevice* device) override;
ortunobc3bce12016-04-15 21:22:55223 void GattCharacteristicValueChanged(
224 device::BluetoothAdapter* adapter,
rkc122239752016-04-20 23:59:08225 device::BluetoothRemoteGattCharacteristic* characteristic,
ortunobc3bce12016-04-15 21:22:55226 const std::vector<uint8_t>& value) override;
227
228 // Notifies the WebBluetoothServiceClient that characteristic
229 // |characteristic_instance_id| changed it's value. We only do this for
230 // characteristics that have been returned to the client in the past.
231 void NotifyCharacteristicValueChanged(
232 const std::string& characteristic_instance_id,
juncai1ef7dd42016-11-29 04:28:21233 const std::vector<uint8_t>& value);
ortunobc3bce12016-04-15 21:22:55234
235 // WebBluetoothService methods:
Ovidio Henriquez62154472019-08-21 14:45:11236 void GetAvailability(GetAvailabilityCallback callback) override;
ortunob6374dd82016-05-27 03:04:07237 void RequestDevice(blink::mojom::WebBluetoothRequestDeviceOptionsPtr options,
tzikcf7bcd652017-06-15 04:19:30238 RequestDeviceCallback callback) override;
Ovidio Henriquez278801c22020-03-10 21:52:01239 void GetDevices(GetDevicesCallback callback) override;
François Beaufortf100253a82022-03-10 11:26:31240 void ForgetDevice(const blink::WebBluetoothDeviceId& device_id,
241 ForgetDeviceCallback callback) override;
ortunob6c45d4f2016-05-07 04:19:42242 void RemoteServerConnect(
Ovidio Henriquez0e8ab7072019-05-31 21:38:07243 const blink::WebBluetoothDeviceId& device_id,
Henrique Ferreirodb47b3e2019-09-11 14:29:39244 mojo::PendingAssociatedRemote<blink::mojom::WebBluetoothServerClient>
245 client,
tzikcf7bcd652017-06-15 04:19:30246 RemoteServerConnectCallback callback) override;
Ovidio Henriquez0e8ab7072019-05-31 21:38:07247 void RemoteServerDisconnect(
248 const blink::WebBluetoothDeviceId& device_id) override;
beaufort.francois7952f002016-06-14 16:44:09249 void RemoteServerGetPrimaryServices(
Ovidio Henriquez0e8ab7072019-05-31 21:38:07250 const blink::WebBluetoothDeviceId& device_id,
beaufort.francois7952f002016-06-14 16:44:09251 blink::mojom::WebBluetoothGATTQueryQuantity quantity,
Arthur Sonzognic686e8f2024-01-11 08:36:37252 const std::optional<device::BluetoothUUID>& services_uuid,
tzikcf7bcd652017-06-15 04:19:30253 RemoteServerGetPrimaryServicesCallback callback) override;
ortunob0fb6a182016-04-27 01:45:26254 void RemoteServiceGetCharacteristics(
juncai1ef7dd42016-11-29 04:28:21255 const std::string& service_instance_id,
ortunob0fb6a182016-04-27 01:45:26256 blink::mojom::WebBluetoothGATTQueryQuantity quantity,
Arthur Sonzognic686e8f2024-01-11 08:36:37257 const std::optional<device::BluetoothUUID>& characteristics_uuid,
tzikcf7bcd652017-06-15 04:19:30258 RemoteServiceGetCharacteristicsCallback callback) override;
ortuno12e91f072016-04-15 22:57:33259 void RemoteCharacteristicReadValue(
juncai1ef7dd42016-11-29 04:28:21260 const std::string& characteristic_instance_id,
tzikcf7bcd652017-06-15 04:19:30261 RemoteCharacteristicReadValueCallback callback) override;
ortunoad6b0fea2016-03-31 18:49:11262 void RemoteCharacteristicWriteValue(
juncai1ef7dd42016-11-29 04:28:21263 const std::string& characteristic_instance_id,
Reilly Grant8002d42f2024-10-23 22:40:31264 base::span<const uint8_t> value,
David Lechner2e7a43a2020-05-26 20:29:59265 blink::mojom::WebBluetoothWriteType write_type,
tzikcf7bcd652017-06-15 04:19:30266 RemoteCharacteristicWriteValueCallback callback) override;
ortunobc3bce12016-04-15 21:22:55267 void RemoteCharacteristicStartNotifications(
juncai1ef7dd42016-11-29 04:28:21268 const std::string& characteristic_instance_id,
Henrique Ferreirodb47b3e2019-09-11 14:29:39269 mojo::PendingAssociatedRemote<
270 blink::mojom::WebBluetoothCharacteristicClient> client,
tzikcf7bcd652017-06-15 04:19:30271 RemoteCharacteristicStartNotificationsCallback callback) override;
Chris Mumford4d1cf30782021-10-05 23:02:47272 void RemoteCharacteristicStartNotificationsInternal(
273 const std::string& characteristic_instance_id,
274 mojo::AssociatedRemote<blink::mojom::WebBluetoothCharacteristicClient>
275 client,
276 RemoteCharacteristicStartNotificationsCallback callback) override;
ortunobc3bce12016-04-15 21:22:55277 void RemoteCharacteristicStopNotifications(
juncai1ef7dd42016-11-29 04:28:21278 const std::string& characteristic_instance_id,
tzikcf7bcd652017-06-15 04:19:30279 RemoteCharacteristicStopNotificationsCallback callback) override;
dougt4f2237c2017-01-14 04:14:13280 void RemoteCharacteristicGetDescriptors(
281 const std::string& service_instance_id,
282 blink::mojom::WebBluetoothGATTQueryQuantity quantity,
Arthur Sonzognic686e8f2024-01-11 08:36:37283 const std::optional<device::BluetoothUUID>& characteristics_uuid,
tzikcf7bcd652017-06-15 04:19:30284 RemoteCharacteristicGetDescriptorsCallback callback) override;
dougta2fe055212017-01-27 05:35:30285 void RemoteDescriptorReadValue(
Chris Mumford61ee9ba2021-06-22 16:16:15286 const std::string& descriptor_instance_id,
tzikcf7bcd652017-06-15 04:19:30287 RemoteDescriptorReadValueCallback callback) override;
dougtbe62e9d2017-02-01 16:13:55288 void RemoteDescriptorWriteValue(
289 const std::string& descriptor_instance_id,
Reilly Grant8002d42f2024-10-23 22:40:31290 base::span<const uint8_t> value,
tzikcf7bcd652017-06-15 04:19:30291 RemoteDescriptorWriteValueCallback callback) override;
Doug Turner23a658b92018-12-20 01:57:54292 void RequestScanningStart(
Ovidio Henriquez3dee626c2020-05-05 19:37:10293 mojo::PendingAssociatedRemote<
Alvin Jic0c16c72023-08-25 18:41:57294 blink::mojom::WebBluetoothAdvertisementClient> client_remote,
Doug Turner9b931de2019-01-08 18:22:37295 blink::mojom::WebBluetoothRequestLEScanOptionsPtr options,
Doug Turner23a658b92018-12-20 01:57:54296 RequestScanningStartCallback callback) override;
Ovidio Henriquez887bb132020-06-04 21:45:55297 void WatchAdvertisementsForDevice(
298 const blink::WebBluetoothDeviceId& device_id,
299 mojo::PendingAssociatedRemote<
Alvin Jic0c16c72023-08-25 18:41:57300 blink::mojom::WebBluetoothAdvertisementClient> client_remote,
Ovidio Henriquez887bb132020-06-04 21:45:55301 WatchAdvertisementsForDeviceCallback callback) override;
ortunoad6b0fea2016-03-31 18:49:11302
ortunob6374dd82016-05-27 03:04:07303 void RequestDeviceImpl(
304 blink::mojom::WebBluetoothRequestDeviceOptionsPtr options,
tzikcf7bcd652017-06-15 04:19:30305 RequestDeviceCallback callback,
Reilly Granta255d1be2019-11-14 07:01:05306 scoped_refptr<device::BluetoothAdapter> adapter);
ortunob6374dd82016-05-27 03:04:07307
Ovidio Henriquez278801c22020-03-10 21:52:01308 void GetDevicesImpl(GetDevicesCallback callback,
309 scoped_refptr<device::BluetoothAdapter> adapter);
310
Ovidio Henriquez887bb132020-06-04 21:45:55311 // Callbacks for BLE scanning.
Doug Turner23a658b92018-12-20 01:57:54312 void RequestScanningStartImpl(
Ovidio Henriquez887bb132020-06-04 21:45:55313 mojo::PendingAssociatedRemote<
Alvin Jic0c16c72023-08-25 18:41:57314 blink::mojom::WebBluetoothAdvertisementClient> client_remote,
Doug Turner9b931de2019-01-08 18:22:37315 blink::mojom::WebBluetoothRequestLEScanOptionsPtr options,
Doug Turner23a658b92018-12-20 01:57:54316 RequestScanningStartCallback callback,
Reilly Granta255d1be2019-11-14 07:01:05317 scoped_refptr<device::BluetoothAdapter> adapter);
Ovidio Henriquez887bb132020-06-04 21:45:55318 void OnStartDiscoverySessionForScanning(
319 mojo::PendingAssociatedRemote<
Alvin Jic0c16c72023-08-25 18:41:57320 blink::mojom::WebBluetoothAdvertisementClient> client_remote,
Doug Turner9b931de2019-01-08 18:22:37321 blink::mojom::WebBluetoothRequestLEScanOptionsPtr options,
Doug Turner23a658b92018-12-20 01:57:54322 std::unique_ptr<device::BluetoothDiscoverySession> session);
Ovidio Henriquez887bb132020-06-04 21:45:55323 void OnDiscoverySessionErrorForScanning();
Doug Turner23a658b92018-12-20 01:57:54324
Ovidio Henriquez887bb132020-06-04 21:45:55325 // Callbacks for watch advertisements for device.
326 void WatchAdvertisementsForDeviceImpl(
327 const blink::WebBluetoothDeviceId& device_id,
328 mojo::PendingAssociatedRemote<
Alvin Jic0c16c72023-08-25 18:41:57329 blink::mojom::WebBluetoothAdvertisementClient> client_remote,
Ovidio Henriquez887bb132020-06-04 21:45:55330 WatchAdvertisementsForDeviceCallback callback,
331 scoped_refptr<device::BluetoothAdapter> adapter);
332 void OnStartDiscoverySessionForWatchAdvertisements(
333 std::unique_ptr<device::BluetoothDiscoverySession> session);
334 void OnDiscoverySessionErrorForWatchAdvertisements();
335
336 // Remove WatchAdvertisementsClients and ScanningClients with disconnected
337 // WebBluetoothAdvertisementClients from their respective containers.
338 void RemoveDisconnectedClients();
339
340 // Stop active discovery sessions and destroy them if there aren't any active
341 // AdvertisementClients.
342 void MaybeStopDiscovery();
Doug Turner23a658b92018-12-20 01:57:54343
ortuno67acd832016-04-30 00:13:22344 // Should only be run after the services have been discovered for
345 // |device_address|.
beaufort.francois7952f002016-06-14 16:44:09346 void RemoteServerGetPrimaryServicesImpl(
Ovidio Henriquez0e8ab7072019-05-31 21:38:07347 const blink::WebBluetoothDeviceId& device_id,
beaufort.francois7952f002016-06-14 16:44:09348 blink::mojom::WebBluetoothGATTQueryQuantity quantity,
Arthur Sonzognic686e8f2024-01-11 08:36:37349 const std::optional<device::BluetoothUUID>& services_uuid,
tzikcf7bcd652017-06-15 04:19:30350 RemoteServerGetPrimaryServicesCallback callback,
ortuno67acd832016-04-30 00:13:22351 device::BluetoothDevice* device);
352
Reilly Grantb936f9e2021-04-29 21:04:43353 // Callback for BluetoothDeviceChooserController::GetDevice.
354 void OnGetDevice(RequestDeviceCallback callback,
355 blink::mojom::WebBluetoothResult result,
356 blink::mojom::WebBluetoothRequestDeviceOptionsPtr options,
357 const std::string& device_id);
ortunob6374dd82016-05-27 03:04:07358
ortunob6c45d4f2016-05-07 04:19:42359 // Callbacks for BluetoothDevice::CreateGattConnection.
Chris Mumfordf59d16b2021-06-23 00:32:11360 void OnCreateGATTConnection(
Ovidio Henriquez0e8ab7072019-05-31 21:38:07361 const blink::WebBluetoothDeviceId& device_id,
Henrique Ferreirodb47b3e2019-09-11 14:29:39362 mojo::AssociatedRemote<blink::mojom::WebBluetoothServerClient> client,
tzikcf7bcd652017-06-15 04:19:30363 RemoteServerConnectCallback callback,
Chris Mumfordf59d16b2021-06-23 00:32:11364 std::unique_ptr<device::BluetoothGattConnection> connection,
Arthur Sonzognic686e8f2024-01-11 08:36:37365 std::optional<device::BluetoothDevice::ConnectErrorCode> error_code);
ortunob6c45d4f2016-05-07 04:19:42366
rkc122239752016-04-20 23:59:08367 // Callbacks for BluetoothRemoteGattCharacteristic::ReadRemoteCharacteristic.
Chris Mumford6627ae42021-05-03 18:54:40368 void OnCharacteristicReadValue(
Chris Mumford4d1cf30782021-10-05 23:02:47369 const std::string& characteristic_instance_id,
tzikcf7bcd652017-06-15 04:19:30370 RemoteCharacteristicReadValueCallback callback,
Arthur Sonzognic686e8f2024-01-11 08:36:37371 std::optional<device::BluetoothGattService::GattErrorCode> error_code,
dougt4f2237c2017-01-14 04:14:13372 const std::vector<uint8_t>& value);
ortuno12e91f072016-04-15 22:57:33373
rkc122239752016-04-20 23:59:08374 // Callbacks for BluetoothRemoteGattCharacteristic::WriteRemoteCharacteristic.
dougt4f2237c2017-01-14 04:14:13375 void OnCharacteristicWriteValueSuccess(
tzikcf7bcd652017-06-15 04:19:30376 RemoteCharacteristicWriteValueCallback callback);
dougt4f2237c2017-01-14 04:14:13377 void OnCharacteristicWriteValueFailed(
Chris Mumford4d1cf30782021-10-05 23:02:47378 const std::string& characteristic_instance_id,
379 const std::vector<uint8_t>& value,
380 blink::mojom::WebBluetoothWriteType write_type,
tzikcf7bcd652017-06-15 04:19:30381 RemoteCharacteristicWriteValueCallback callback,
Chris Mumford860d05e2021-05-12 17:08:51382 device::BluetoothGattService::GattErrorCode error_code);
ortunoad6b0fea2016-03-31 18:49:11383
rkc122239752016-04-20 23:59:08384 // Callbacks for BluetoothRemoteGattCharacteristic::StartNotifySession.
ortunobc3bce12016-04-15 21:22:55385 void OnStartNotifySessionSuccess(
tzikcf7bcd652017-06-15 04:19:30386 RemoteCharacteristicStartNotificationsCallback callback,
ortunobc3bce12016-04-15 21:22:55387 std::unique_ptr<device::BluetoothGattNotifySession> notify_session);
388 void OnStartNotifySessionFailed(
tzikcf7bcd652017-06-15 04:19:30389 RemoteCharacteristicStartNotificationsCallback callback,
Chris Mumforde6fa96a42021-07-20 00:15:14390 const std::string& characteristic_instance_id,
Chris Mumford860d05e2021-05-12 17:08:51391 device::BluetoothGattService::GattErrorCode error_code);
ortunobc3bce12016-04-15 21:22:55392
393 // Callback for BluetoothGattNotifySession::Stop.
394 void OnStopNotifySessionComplete(
395 const std::string& characteristic_instance_id,
tzikcf7bcd652017-06-15 04:19:30396 RemoteCharacteristicStopNotificationsCallback callback);
ortunobc3bce12016-04-15 21:22:55397
dougta2fe055212017-01-27 05:35:30398 // Callbacks for BluetoothRemoteGattDescriptor::ReadRemoteDescriptor.
Chris Mumford6627ae42021-05-03 18:54:40399 void OnDescriptorReadValue(
Chris Mumford4d1cf30782021-10-05 23:02:47400 const std::string& descriptor_instance_id,
tzikcf7bcd652017-06-15 04:19:30401 RemoteDescriptorReadValueCallback callback,
Arthur Sonzognic686e8f2024-01-11 08:36:37402 std::optional<device::BluetoothGattService::GattErrorCode> error_code,
Chris Mumford6627ae42021-05-03 18:54:40403 const std::vector<uint8_t>& value);
dougta2fe055212017-01-27 05:35:30404
dougtbe62e9d2017-02-01 16:13:55405 // Callbacks for BluetoothRemoteGattDescriptor::WriteRemoteDescriptor.
406 void OnDescriptorWriteValueSuccess(
tzikcf7bcd652017-06-15 04:19:30407 RemoteDescriptorWriteValueCallback callback);
dougtbe62e9d2017-02-01 16:13:55408 void OnDescriptorWriteValueFailed(
Chris Mumford4d1cf30782021-10-05 23:02:47409 const std::string& descriptor_instance_id,
410 const std::vector<uint8_t>& value,
tzikcf7bcd652017-06-15 04:19:30411 RemoteDescriptorWriteValueCallback callback,
Chris Mumford860d05e2021-05-12 17:08:51412 device::BluetoothGattService::GattErrorCode error_code);
dougtbe62e9d2017-02-01 16:13:55413
ortunob0fb6a182016-04-27 01:45:26414 // Functions to query the platform cache for the bluetooth object.
415 // result.outcome == CacheQueryOutcome::SUCCESS if the object was found in the
416 // cache. Otherwise result.outcome that can used to record the outcome and
417 // result.error will contain the error that should be sent to the renderer.
418 // One of the possible outcomes is BAD_RENDERER. In this case we crash the
419 // renderer, record the reason and close the pipe, so it's safe to drop
420 // any callbacks.
421
ortunob6374dd82016-05-27 03:04:07422 // Queries the platform cache for a Device with |device_id| for |origin|.
423 // Fills in the |outcome| field and the |device| field if successful.
Ovidio Henriquez0e8ab7072019-05-31 21:38:07424 CacheQueryResult QueryCacheForDevice(
425 const blink::WebBluetoothDeviceId& device_id);
ortunob6374dd82016-05-27 03:04:07426
Chris Mumford550e0122021-06-17 00:32:32427 // Return the cached BluetoothDevice for the given |device_id|.
428 device::BluetoothDevice* GetCachedDevice(
429 const blink::WebBluetoothDeviceId& device_id);
430
ortuno67acd832016-04-30 00:13:22431 // Queries the platform cache for a Service with |service_instance_id|. Fills
432 // in the |outcome| field, and |device| and |service| fields if successful.
433 CacheQueryResult QueryCacheForService(const std::string& service_instance_id);
434
ortunob0fb6a182016-04-27 01:45:26435 // Queries the platform cache for a characteristic with
436 // |characteristic_instance_id|. Fills in the |outcome| field, and |device|,
437 // |service| and |characteristic| fields if successful.
438 CacheQueryResult QueryCacheForCharacteristic(
439 const std::string& characteristic_instance_id);
440
dougta2fe055212017-01-27 05:35:30441 // Queries the platform cache for a descriptor with |descriptor_instance_id|.
442 // Fills in the |outcome| field, and |device|, |service|, |characteristic|,
443 // |descriptor| fields if successful.
444 CacheQueryResult QueryCacheForDescriptor(
445 const std::string& descriptor_instance_id);
446
Giovanni Ortuño Urquidi8688a0d2017-05-20 06:12:32447 void RunPendingPrimaryServicesRequests(device::BluetoothDevice* device);
448
ortunoad6b0fea2016-03-31 18:49:11449 RenderProcessHost* GetRenderProcessHost();
ortunob6374dd82016-05-27 03:04:07450 device::BluetoothAdapter* GetAdapter();
juncaif70c51172017-02-10 23:49:17451 BluetoothAllowedDevices& allowed_devices();
ortunoad6b0fea2016-03-31 18:49:11452
Jun Cai732a05e32019-05-29 19:34:19453 void StoreAllowedScanOptions(
454 const blink::mojom::WebBluetoothRequestLEScanOptions& options);
Arthur Sonzognic686e8f2024-01-11 08:36:37455 bool AreScanFiltersAllowed(const std::optional<ScanFilters>& filters) const;
Jun Cai732a05e32019-05-29 19:34:19456
Ovidio Henriquez5bfc18162020-03-24 16:17:27457 // Clears state associated with Bluetooth LE Scanning.
Ovidio Henriquez887bb132020-06-04 21:45:55458 void ClearAdvertisementClients();
Ovidio Henriquez5bfc18162020-03-24 16:17:27459
Ovidio Henriquez3d729f62020-02-07 00:43:29460 bool IsAllowedToAccessAtLeastOneService(
461 const blink::WebBluetoothDeviceId& device_id);
462 bool IsAllowedToAccessService(const blink::WebBluetoothDeviceId& device_id,
463 const device::BluetoothUUID& service);
Ovidio Henriquezbbc7853c2020-09-17 22:36:56464 bool IsAllowedToAccessManufacturerData(
465 const blink::WebBluetoothDeviceId& device_id,
466 uint16_t manufacturer_code);
Ovidio Henriquez3d729f62020-02-07 00:43:29467
Ovidio Henriquez887bb132020-06-04 21:45:55468 // Returns true if at least |ble_scan_discovery_session_| or
469 // |watch_advertisements_discovery_session_| is active.
470 bool HasActiveDiscoverySession();
471
Matt Reynolds8cca57d52025-02-20 18:20:59472 // Prevents the associated RenderFrameHost from entering the back forward
473 // cache and evicts it if it was already added.
474 void PreventBackForwardCache();
475
Chris Mumford02de39b2021-05-06 15:28:59476 // WebBluetoothPairingManagerDelegate implementation:
477 blink::WebBluetoothDeviceId GetCharacteristicDeviceID(
478 const std::string& characteristic_instance_id) override;
Chris Mumford61ee9ba2021-06-22 16:16:15479 blink::WebBluetoothDeviceId GetDescriptorDeviceId(
480 const std::string& descriptor_instance_id) override;
Chris Mumford4d1cf30782021-10-05 23:02:47481 blink::WebBluetoothDeviceId GetWebBluetoothDeviceId(
482 const std::string& device_address) override;
Chris Mumfordf59d16b2021-06-23 00:32:11483 void PairDevice(const blink::WebBluetoothDeviceId& device_id,
484 device::BluetoothDevice::PairingDelegate* pairing_delegate,
485 device::BluetoothDevice::ConnectCallback callback) override;
Chris Mumford550e0122021-06-17 00:32:32486 void CancelPairing(const blink::WebBluetoothDeviceId& device_id) override;
Chris Mumford4d1cf30782021-10-05 23:02:47487 void SetPinCode(const blink::WebBluetoothDeviceId& device_id,
488 const std::string& pincode) override;
Alvin Jif6100132022-07-07 21:53:43489 void PromptForBluetoothPairing(
Chris Mumford4d1cf30782021-10-05 23:02:47490 const std::u16string& device_identifier,
Alvin Jif6100132022-07-07 21:53:43491 BluetoothDelegate::PairPromptCallback callback,
Alvin Jibab887b2022-07-27 00:59:54492 BluetoothDelegate::PairingKind pairing_kind,
Arthur Sonzognic686e8f2024-01-11 08:36:37493 const std::optional<std::u16string>& pin) override;
Alvin Ji3443b9b2022-06-17 19:57:47494 void PairConfirmed(const blink::WebBluetoothDeviceId& device_id) override;
Daniel Chengd6978b062023-11-16 00:11:38495
496 mojo::Receiver<blink::mojom::WebBluetoothService> receiver_;
497
ortunob6374dd82016-05-27 03:04:07498 // Used to open a BluetoothChooser and start a device discovery session.
499 std::unique_ptr<BluetoothDeviceChooserController> device_chooser_controller_;
500
Jun Cai149002e2019-05-09 23:13:07501 // Used to open a BluetoothScanningPrompt.
502 std::unique_ptr<BluetoothDeviceScanningPromptController>
503 device_scanning_prompt_controller_;
504
ortunob0fb6a182016-04-27 01:45:26505 // Maps to get the object's parent based on its instanceID.
ortuno67acd832016-04-30 00:13:22506 std::unordered_map<std::string, std::string> service_id_to_device_address_;
ortunob0fb6a182016-04-27 01:45:26507 std::unordered_map<std::string, std::string> characteristic_id_to_service_id_;
dougt4f2237c2017-01-14 04:14:13508 std::unordered_map<std::string, std::string>
509 descriptor_id_to_characteristic_id_;
ortunob0fb6a182016-04-27 01:45:26510
ortunob6c45d4f2016-05-07 04:19:42511 // Map to keep track of the connected Bluetooth devices.
512 std::unique_ptr<FrameConnectedBluetoothDevices> connected_devices_;
513
ortuno67acd832016-04-30 00:13:22514 // Maps a device address to callbacks that are waiting for services to
515 // be discovered for that device.
516 std::unordered_map<std::string, std::vector<PrimaryServicesRequestCallback>>
517 pending_primary_services_requests_;
518
ortunobc3bce12016-04-15 21:22:55519 // Map to keep track of the characteristics' notify sessions.
520 std::unordered_map<std::string,
juncai5fbf7e62017-03-23 21:21:56521 std::unique_ptr<GATTNotifySessionAndCharacteristicClient>>
ortunobc3bce12016-04-15 21:22:55522 characteristic_id_to_notify_session_;
Chris Mumforde6fa96a42021-07-20 00:15:14523 // Map characteristic instance ID to deferred startNotification data.
524 std::unordered_map<
525 std::string,
526 base::queue<std::unique_ptr<DeferredStartNotificationData>>>
527 characteristic_id_to_deferred_start_;
ortunobc3bce12016-04-15 21:22:55528
Doug Turner23a658b92018-12-20 01:57:54529 // Keeps track of our BLE scanning session.
Ovidio Henriquez887bb132020-06-04 21:45:55530 std::unique_ptr<device::BluetoothDiscoverySession>
531 ble_scan_discovery_session_;
Doug Turner23a658b92018-12-20 01:57:54532
Ovidio Henriquez887bb132020-06-04 21:45:55533 // Keeps track of our watch advertisements discovery session.
534 std::unique_ptr<device::BluetoothDiscoverySession>
535 watch_advertisements_discovery_session_;
536
537 // This queues up a scanning start callback so that we only have one
538 // BluetoothDiscoverySession start request at a time for a BLE scan.
539 RequestScanningStartCallback request_scanning_start_callback_;
540
Alvin Jif4c234d412023-08-23 16:58:54541 // This queues up pending watch advertisements clients so that
Ovidio Henriquez887bb132020-06-04 21:45:55542 // we only have one BluetoothDiscoverySession start request at a time for
543 // watching device advertisements.
Alvin Jif4c234d412023-08-23 16:58:54544 std::vector<std::unique_ptr<WatchAdvertisementsClient>>
545 watch_advertisements_pending_clients_;
Doug Turner23a658b92018-12-20 01:57:54546
547 // List of clients that we must broadcast scan changes to.
Doug Turner9b931de2019-01-08 18:22:37548 std::vector<std::unique_ptr<ScanningClient>> scanning_clients_;
Ovidio Henriquez887bb132020-06-04 21:45:55549 std::vector<std::unique_ptr<WatchAdvertisementsClient>>
550 watch_advertisements_clients_;
Doug Turner23a658b92018-12-20 01:57:54551
Jun Cai732a05e32019-05-29 19:34:19552 // Allowed Bluetooth scanning filters.
553 ScanFilters allowed_scan_filters_;
554
555 // Whether a site has been allowed to receive all Bluetooth advertisement
556 // packets.
557 bool accept_all_advertisements_ = false;
558
Chris Mumford4d1cf30782021-10-05 23:02:47559#if PAIR_BLUETOOTH_ON_DEMAND()
560 std::unique_ptr<WebBluetoothPairingManager> pairing_manager_;
561#endif
562
Matt Reynolds8cca57d52025-02-20 18:20:59563 // When valid, prevents the frame from entering the back forward cache.
564 RenderFrameHostImpl::BackForwardCacheDisablingFeatureHandle
565 back_forward_cache_feature_handle_;
566
Andy Paicu1d7fc172021-01-20 18:29:45567 base::ScopedObservation<BluetoothDelegate,
Andrew Rayskiyebdd7f22022-11-07 18:59:27568 BluetoothDelegate::FramePermissionObserver>
Andy Paicu1d7fc172021-01-20 18:29:45569 observer_{this};
570
Chengwei Hsieh3de031c32025-08-01 23:32:02571 // A set contains device ids that have GATT connection attempt ongoing.
572 std::unordered_set<blink::WebBluetoothDeviceId,
573 blink::WebBluetoothDeviceIdHash>
574 pending_connection_device_ids_;
575
Jeremy Roman3bca4bf2019-07-11 03:41:25576 base::WeakPtrFactory<WebBluetoothServiceImpl> weak_ptr_factory_{this};
ortunoad6b0fea2016-03-31 18:49:11577};
578
579} // namespace content
580
581#endif // CONTENT_BROWSER_BLUETOOTH_WEB_BLUETOOTH_SERVICE_IMPL_H_