Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(189)

Side by Side Diff: content/browser/bluetooth/web_bluetooth_service_impl.cc

Issue 1902153003: bluetooth: Move connect/disconnect to mojo (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@bluetooth-separate-connection-tests
Patch Set: Fix gypi Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // ID Not In Map Note: 5 // ID Not In Map Note:
6 // A service, characteristic, or descriptor ID not in the corresponding 6 // A service, characteristic, or descriptor ID not in the corresponding
7 // BluetoothDispatcherHost map [service_id_to_device_address_, 7 // BluetoothDispatcherHost map [service_id_to_device_address_,
8 // characteristic_id_to_service_id_, descriptor_to_characteristic_] implies a 8 // characteristic_id_to_service_id_, descriptor_to_characteristic_] implies a
9 // hostile renderer because a renderer obtains the corresponding ID from this 9 // hostile renderer because a renderer obtains the corresponding ID from this
10 // class and it will be added to the map at that time. 10 // class and it will be added to the map at that time.
11 11
12 #include "content/browser/bluetooth/web_bluetooth_service_impl.h" 12 #include "content/browser/bluetooth/web_bluetooth_service_impl.h"
13 13
14 #include <algorithm> 14 #include <algorithm>
15 15
16 #include "base/thread_task_runner_handle.h" 16 #include "base/thread_task_runner_handle.h"
17 #include "content/browser/bluetooth/bluetooth_blacklist.h" 17 #include "content/browser/bluetooth/bluetooth_blacklist.h"
18 #include "content/browser/bluetooth/bluetooth_dispatcher_host.h" 18 #include "content/browser/bluetooth/bluetooth_dispatcher_host.h"
19 #include "content/browser/bluetooth/frame_connected_bluetooth_devices.h"
19 #include "content/browser/renderer_host/render_process_host_impl.h" 20 #include "content/browser/renderer_host/render_process_host_impl.h"
20 #include "content/public/browser/navigation_handle.h" 21 #include "content/public/browser/navigation_handle.h"
21 #include "content/public/browser/render_frame_host.h" 22 #include "content/public/browser/render_frame_host.h"
22 #include "content/public/browser/web_contents.h" 23 #include "content/public/browser/web_contents.h"
23 #include "device/bluetooth/bluetooth_remote_gatt_characteristic.h" 24 #include "device/bluetooth/bluetooth_remote_gatt_characteristic.h"
24 25
25 namespace content { 26 namespace content {
26 27
27 namespace { 28 namespace {
28 29
30 blink::mojom::WebBluetoothError TranslateConnectErrorAndRecord(
31 device::BluetoothDevice::ConnectErrorCode error_code) {
32 switch (error_code) {
33 case device::BluetoothDevice::ERROR_UNKNOWN:
34 RecordConnectGATTOutcome(UMAConnectGATTOutcome::UNKNOWN);
35 return blink::mojom::WebBluetoothError::CONNECT_UNKNOWN_ERROR;
36 case device::BluetoothDevice::ERROR_INPROGRESS:
37 RecordConnectGATTOutcome(UMAConnectGATTOutcome::IN_PROGRESS);
38 return blink::mojom::WebBluetoothError::CONNECT_ALREADY_IN_PROGRESS;
39 case device::BluetoothDevice::ERROR_FAILED:
40 RecordConnectGATTOutcome(UMAConnectGATTOutcome::FAILED);
41 return blink::mojom::WebBluetoothError::CONNECT_UNKNOWN_FAILURE;
42 case device::BluetoothDevice::ERROR_AUTH_FAILED:
43 RecordConnectGATTOutcome(UMAConnectGATTOutcome::AUTH_FAILED);
44 return blink::mojom::WebBluetoothError::CONNECT_AUTH_FAILED;
45 case device::BluetoothDevice::ERROR_AUTH_CANCELED:
46 RecordConnectGATTOutcome(UMAConnectGATTOutcome::AUTH_CANCELED);
47 return blink::mojom::WebBluetoothError::CONNECT_AUTH_CANCELED;
48 case device::BluetoothDevice::ERROR_AUTH_REJECTED:
49 RecordConnectGATTOutcome(UMAConnectGATTOutcome::AUTH_REJECTED);
50 return blink::mojom::WebBluetoothError::CONNECT_AUTH_REJECTED;
51 case device::BluetoothDevice::ERROR_AUTH_TIMEOUT:
52 RecordConnectGATTOutcome(UMAConnectGATTOutcome::AUTH_TIMEOUT);
53 return blink::mojom::WebBluetoothError::CONNECT_AUTH_TIMEOUT;
54 case device::BluetoothDevice::ERROR_UNSUPPORTED_DEVICE:
55 RecordConnectGATTOutcome(UMAConnectGATTOutcome::UNSUPPORTED_DEVICE);
56 return blink::mojom::WebBluetoothError::CONNECT_UNSUPPORTED_DEVICE;
57 case device::BluetoothDevice::ERROR_ATTRIBUTE_LENGTH_INVALID:
58 RecordConnectGATTOutcome(UMAConnectGATTOutcome::ATTRIBUTE_LENGTH_INVALID);
59 return blink::mojom::WebBluetoothError::CONNECT_ATTRIBUTE_LENGTH_INVALID;
60 case device::BluetoothDevice::ERROR_CONNECTION_CONGESTED:
61 RecordConnectGATTOutcome(UMAConnectGATTOutcome::CONNECTION_CONGESTED);
62 return blink::mojom::WebBluetoothError::CONNECT_CONNECTION_CONGESTED;
63 case device::BluetoothDevice::ERROR_INSUFFICIENT_ENCRYPTION:
64 RecordConnectGATTOutcome(UMAConnectGATTOutcome::INSUFFICIENT_ENCRYPTION);
65 return blink::mojom::WebBluetoothError::CONNECT_INSUFFICIENT_ENCRYPTION;
66 case device::BluetoothDevice::ERROR_OFFSET_INVALID:
67 RecordConnectGATTOutcome(UMAConnectGATTOutcome::OFFSET_INVALID);
68 return blink::mojom::WebBluetoothError::CONNECT_OFFSET_INVALID;
69 case device::BluetoothDevice::ERROR_READ_NOT_PERMITTED:
70 RecordConnectGATTOutcome(UMAConnectGATTOutcome::READ_NOT_PERMITTED);
71 return blink::mojom::WebBluetoothError::CONNECT_READ_NOT_PERMITTED;
72 case device::BluetoothDevice::ERROR_REQUEST_NOT_SUPPORTED:
73 RecordConnectGATTOutcome(UMAConnectGATTOutcome::REQUEST_NOT_SUPPORTED);
74 return blink::mojom::WebBluetoothError::CONNECT_REQUEST_NOT_SUPPORTED;
75 case device::BluetoothDevice::ERROR_WRITE_NOT_PERMITTED:
76 RecordConnectGATTOutcome(UMAConnectGATTOutcome::WRITE_NOT_PERMITTED);
77 return blink::mojom::WebBluetoothError::CONNECT_WRITE_NOT_PERMITTED;
78 case device::BluetoothDevice::NUM_CONNECT_ERROR_CODES:
79 NOTREACHED();
80 return blink::mojom::WebBluetoothError::UNTRANSLATED_CONNECT_ERROR_CODE;
81 }
82 NOTREACHED();
83 return blink::mojom::WebBluetoothError::UNTRANSLATED_CONNECT_ERROR_CODE;
84 }
85
29 blink::mojom::WebBluetoothError TranslateGATTErrorAndRecord( 86 blink::mojom::WebBluetoothError TranslateGATTErrorAndRecord(
30 device::BluetoothRemoteGattService::GattErrorCode error_code, 87 device::BluetoothRemoteGattService::GattErrorCode error_code,
31 UMAGATTOperation operation) { 88 UMAGATTOperation operation) {
32 switch (error_code) { 89 switch (error_code) {
33 case device::BluetoothRemoteGattService::GATT_ERROR_UNKNOWN: 90 case device::BluetoothRemoteGattService::GATT_ERROR_UNKNOWN:
34 RecordGATTOperationOutcome(operation, UMAGATTOperationOutcome::UNKNOWN); 91 RecordGATTOperationOutcome(operation, UMAGATTOperationOutcome::UNKNOWN);
35 return blink::mojom::WebBluetoothError::GATT_UNKNOWN_ERROR; 92 return blink::mojom::WebBluetoothError::GATT_UNKNOWN_ERROR;
36 case device::BluetoothRemoteGattService::GATT_ERROR_FAILED: 93 case device::BluetoothRemoteGattService::GATT_ERROR_FAILED:
37 RecordGATTOperationOutcome(operation, UMAGATTOperationOutcome::FAILED); 94 RecordGATTOperationOutcome(operation, UMAGATTOperationOutcome::FAILED);
38 return blink::mojom::WebBluetoothError::GATT_UNKNOWN_FAILURE; 95 return blink::mojom::WebBluetoothError::GATT_UNKNOWN_FAILURE;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 } 157 }
101 return services; 158 return services;
102 } 159 }
103 160
104 } // namespace 161 } // namespace
105 162
106 WebBluetoothServiceImpl::WebBluetoothServiceImpl( 163 WebBluetoothServiceImpl::WebBluetoothServiceImpl(
107 RenderFrameHost* render_frame_host, 164 RenderFrameHost* render_frame_host,
108 blink::mojom::WebBluetoothServiceRequest request) 165 blink::mojom::WebBluetoothServiceRequest request)
109 : WebContentsObserver(WebContents::FromRenderFrameHost(render_frame_host)), 166 : WebContentsObserver(WebContents::FromRenderFrameHost(render_frame_host)),
167 connected_devices_(new FrameConnectedBluetoothDevices(render_frame_host)),
110 render_frame_host_(render_frame_host), 168 render_frame_host_(render_frame_host),
111 binding_(this, std::move(request)), 169 binding_(this, std::move(request)),
112 weak_ptr_factory_(this) { 170 weak_ptr_factory_(this) {
113 DCHECK_CURRENTLY_ON(BrowserThread::UI); 171 DCHECK_CURRENTLY_ON(BrowserThread::UI);
114 CHECK(web_contents()); 172 CHECK(web_contents());
115 173
116 GetBluetoothDispatcherHost()->AddAdapterObserver(this); 174 GetBluetoothDispatcherHost()->AddAdapterObserver(this);
117 } 175 }
118 176
119 WebBluetoothServiceImpl::~WebBluetoothServiceImpl() { 177 WebBluetoothServiceImpl::~WebBluetoothServiceImpl() {
(...skipping 16 matching lines...) Expand all
136 } 194 }
137 195
138 void WebBluetoothServiceImpl::AdapterPresentChanged( 196 void WebBluetoothServiceImpl::AdapterPresentChanged(
139 device::BluetoothAdapter* adapter, 197 device::BluetoothAdapter* adapter,
140 bool present) { 198 bool present) {
141 if (!present) { 199 if (!present) {
142 ClearState(); 200 ClearState();
143 } 201 }
144 } 202 }
145 203
204 void WebBluetoothServiceImpl::DeviceChanged(device::BluetoothAdapter* adapter,
205 device::BluetoothDevice* device) {
206 DCHECK_CURRENTLY_ON(BrowserThread::UI);
207 if (!device->IsGattConnected() || !device->IsConnected()) {
208 std::string device_id =
209 connected_devices_->CloseConnectionToDeviceWithAddress(
210 device->GetAddress());
211 if (!device_id.empty()) {
212 // TODO(ortuno): Send event to client.
213 // http://crbug.com/581855
214 }
215 }
216 }
217
146 void WebBluetoothServiceImpl::GattServicesDiscovered( 218 void WebBluetoothServiceImpl::GattServicesDiscovered(
147 device::BluetoothAdapter* adapter, 219 device::BluetoothAdapter* adapter,
148 device::BluetoothDevice* device) { 220 device::BluetoothDevice* device) {
149 DCHECK_CURRENTLY_ON(BrowserThread::UI); 221 DCHECK_CURRENTLY_ON(BrowserThread::UI);
150 const std::string& device_address = device->GetAddress(); 222 const std::string& device_address = device->GetAddress();
151 VLOG(1) << "Services discovered for device: " << device_address; 223 VLOG(1) << "Services discovered for device: " << device_address;
152 224
153 auto iter = pending_primary_services_requests_.find(device_address); 225 auto iter = pending_primary_services_requests_.find(device_address);
154 if (iter == pending_primary_services_requests_.end()) { 226 if (iter == pending_primary_services_requests_.end()) {
155 return; 227 return;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 characteristic_instance_id, mojo::Array<uint8_t>(std::move(value))); 268 characteristic_instance_id, mojo::Array<uint8_t>(std::move(value)));
197 } 269 }
198 } 270 }
199 271
200 void WebBluetoothServiceImpl::SetClient( 272 void WebBluetoothServiceImpl::SetClient(
201 blink::mojom::WebBluetoothServiceClientAssociatedPtrInfo client) { 273 blink::mojom::WebBluetoothServiceClientAssociatedPtrInfo client) {
202 DCHECK(!client_.get()); 274 DCHECK(!client_.get());
203 client_.Bind(std::move(client)); 275 client_.Bind(std::move(client));
204 } 276 }
205 277
278 void WebBluetoothServiceImpl::RemoteServerConnect(
279 const mojo::String& device_id,
280 const RemoteServerConnectCallback& callback) {
281 DCHECK_CURRENTLY_ON(BrowserThread::UI);
282 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::CONNECT_GATT);
283
284 const CacheQueryResult query_result =
285 GetBluetoothDispatcherHost()->QueryCacheForDevice(GetOrigin(), device_id);
286
287 if (query_result.outcome != CacheQueryOutcome::SUCCESS) {
288 RecordConnectGATTOutcome(query_result.outcome);
289 callback.Run(query_result.GetWebError());
290 return;
291 }
292
293 if (connected_devices_->IsConnectedToDeviceWithId(device_id)) {
294 VLOG(1) << "Already connected.";
295 callback.Run(blink::mojom::WebBluetoothError::SUCCESS);
296 return;
297 }
298
299 // It's possible for WebBluetoothServiceImpl to issue two successive
300 // connection requests for which it would get two successive responses
301 // and consequently try to insert two BluetoothGattConnections for the
302 // same device. WebBluetoothServiceImpl should reject or queue connection
303 // requests if there is a pending connection already, but the platform
304 // abstraction doesn't currently support checking for pending connections.
305 // TODO(ortuno): CHECK that this never happens once the platform
306 // abstraction allows to check for pending connections.
307 // http://crbug.com/583544
308 const base::TimeTicks start_time = base::TimeTicks::Now();
309 query_result.device->CreateGattConnection(
310 base::Bind(&WebBluetoothServiceImpl::OnCreateGATTConnectionSuccess,
311 weak_ptr_factory_.GetWeakPtr(), device_id, start_time,
312 callback),
313 base::Bind(&WebBluetoothServiceImpl::OnCreateGATTConnectionFailed,
314 weak_ptr_factory_.GetWeakPtr(), device_id, start_time,
315 callback));
316 }
317
318 void WebBluetoothServiceImpl::RemoteServerDisconnect(
319 const mojo::String& device_id) {
320 DCHECK_CURRENTLY_ON(BrowserThread::UI);
321 RecordWebBluetoothFunctionCall(
322 UMAWebBluetoothFunction::REMOTE_GATT_SERVER_DISCONNECT);
323
324 if (connected_devices_->IsConnectedToDeviceWithId(device_id)) {
325 VLOG(1) << "Disconnecting device: " << device_id;
326 connected_devices_->CloseConnectionToDeviceWithId(device_id);
327 }
328 }
329
206 void WebBluetoothServiceImpl::RemoteServerGetPrimaryService( 330 void WebBluetoothServiceImpl::RemoteServerGetPrimaryService(
207 const mojo::String& device_id, 331 const mojo::String& device_id,
208 const mojo::String& service_uuid, 332 const mojo::String& service_uuid,
209 const RemoteServerGetPrimaryServiceCallback& callback) { 333 const RemoteServerGetPrimaryServiceCallback& callback) {
210 DCHECK_CURRENTLY_ON(BrowserThread::UI); 334 DCHECK_CURRENTLY_ON(BrowserThread::UI);
211 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::GET_PRIMARY_SERVICE); 335 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::GET_PRIMARY_SERVICE);
212 RecordGetPrimaryServiceService(device::BluetoothUUID(service_uuid)); 336 RecordGetPrimaryServiceService(device::BluetoothUUID(service_uuid));
213 337
214 if (!GetBluetoothDispatcherHost() 338 if (!GetBluetoothDispatcherHost()
215 ->allowed_devices_map_.IsOriginAllowedToAccessService( 339 ->allowed_devices_map_.IsOriginAllowedToAccessService(
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
519 643
520 RecordGetPrimaryServiceOutcome(UMAGetPrimaryServiceOutcome::SUCCESS); 644 RecordGetPrimaryServiceOutcome(UMAGetPrimaryServiceOutcome::SUCCESS);
521 blink::mojom::WebBluetoothRemoteGATTServicePtr service_ptr = 645 blink::mojom::WebBluetoothRemoteGATTServicePtr service_ptr =
522 blink::mojom::WebBluetoothRemoteGATTService::New(); 646 blink::mojom::WebBluetoothRemoteGATTService::New();
523 service_ptr->instance_id = services[0]->GetIdentifier(); 647 service_ptr->instance_id = services[0]->GetIdentifier();
524 service_ptr->uuid = services[0]->GetUUID().canonical_value(); 648 service_ptr->uuid = services[0]->GetUUID().canonical_value();
525 callback.Run(blink::mojom::WebBluetoothError::SUCCESS, 649 callback.Run(blink::mojom::WebBluetoothError::SUCCESS,
526 std::move(service_ptr)); 650 std::move(service_ptr));
527 } 651 }
528 652
653 void WebBluetoothServiceImpl::OnCreateGATTConnectionSuccess(
654 const std::string& device_id,
655 base::TimeTicks start_time,
656 const RemoteServerConnectCallback& callback,
657 std::unique_ptr<device::BluetoothGattConnection> connection) {
658 DCHECK_CURRENTLY_ON(BrowserThread::UI);
659 RecordConnectGATTTimeSuccess(base::TimeTicks::Now() - start_time);
660 RecordConnectGATTOutcome(UMAConnectGATTOutcome::SUCCESS);
661
662 connected_devices_->Insert(device_id, std::move(connection));
663 callback.Run(blink::mojom::WebBluetoothError::SUCCESS);
664 }
665
666 void WebBluetoothServiceImpl::OnCreateGATTConnectionFailed(
667 const std::string& device_id,
668 base::TimeTicks start_time,
669 const RemoteServerConnectCallback& callback,
670 device::BluetoothDevice::ConnectErrorCode error_code) {
671 DCHECK_CURRENTLY_ON(BrowserThread::UI);
672 RecordConnectGATTTimeFailed(base::TimeTicks::Now() - start_time);
673 callback.Run(TranslateConnectErrorAndRecord(error_code));
674 }
675
529 void WebBluetoothServiceImpl::OnReadValueSuccess( 676 void WebBluetoothServiceImpl::OnReadValueSuccess(
530 const RemoteCharacteristicReadValueCallback& callback, 677 const RemoteCharacteristicReadValueCallback& callback,
531 const std::vector<uint8_t>& value) { 678 const std::vector<uint8_t>& value) {
532 DCHECK_CURRENTLY_ON(BrowserThread::UI); 679 DCHECK_CURRENTLY_ON(BrowserThread::UI);
533 RecordCharacteristicReadValueOutcome(UMAGATTOperationOutcome::SUCCESS); 680 RecordCharacteristicReadValueOutcome(UMAGATTOperationOutcome::SUCCESS);
534 callback.Run(blink::mojom::WebBluetoothError::SUCCESS, 681 callback.Run(blink::mojom::WebBluetoothError::SUCCESS,
535 mojo::Array<uint8_t>::From(value)); 682 mojo::Array<uint8_t>::From(value));
536 } 683 }
537 684
538 void WebBluetoothServiceImpl::OnReadValueFailed( 685 void WebBluetoothServiceImpl::OnReadValueFailed(
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
678 825
679 url::Origin WebBluetoothServiceImpl::GetOrigin() { 826 url::Origin WebBluetoothServiceImpl::GetOrigin() {
680 return render_frame_host_->GetLastCommittedOrigin(); 827 return render_frame_host_->GetLastCommittedOrigin();
681 } 828 }
682 829
683 void WebBluetoothServiceImpl::ClearState() { 830 void WebBluetoothServiceImpl::ClearState() {
684 characteristic_id_to_notify_session_.clear(); 831 characteristic_id_to_notify_session_.clear();
685 pending_primary_services_requests_.clear(); 832 pending_primary_services_requests_.clear();
686 characteristic_id_to_service_id_.clear(); 833 characteristic_id_to_service_id_.clear();
687 service_id_to_device_address_.clear(); 834 service_id_to_device_address_.clear();
835 connected_devices_.reset(
836 new FrameConnectedBluetoothDevices(render_frame_host_));
688 } 837 }
689 838
690 } // namespace content 839 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/bluetooth/web_bluetooth_service_impl.h ('k') | content/common/bluetooth/bluetooth_messages.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698