Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 // WebBluetoothServiceImpl 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/strings/utf_string_conversions.h" | |
| 16 #include "base/thread_task_runner_handle.h" | 17 #include "base/thread_task_runner_handle.h" |
| 18 #include "content/browser/bluetooth/bluetooth_adapter_factory_wrapper.h" | |
| 17 #include "content/browser/bluetooth/bluetooth_blacklist.h" | 19 #include "content/browser/bluetooth/bluetooth_blacklist.h" |
| 18 #include "content/browser/bluetooth/bluetooth_dispatcher_host.h" | 20 #include "content/browser/bluetooth/bluetooth_device_provider.h" |
| 21 #include "content/browser/bluetooth/bluetooth_metrics.h" | |
| 19 #include "content/browser/bluetooth/frame_connected_bluetooth_devices.h" | 22 #include "content/browser/bluetooth/frame_connected_bluetooth_devices.h" |
| 20 #include "content/browser/renderer_host/render_process_host_impl.h" | 23 #include "content/browser/renderer_host/render_process_host_impl.h" |
| 24 #include "content/public/browser/browser_thread.h" | |
| 21 #include "content/public/browser/navigation_handle.h" | 25 #include "content/public/browser/navigation_handle.h" |
| 22 #include "content/public/browser/render_frame_host.h" | 26 #include "content/public/browser/render_frame_host.h" |
| 23 #include "content/public/browser/web_contents.h" | 27 #include "content/public/browser/web_contents.h" |
| 24 #include "device/bluetooth/bluetooth_remote_gatt_characteristic.h" | 28 #include "device/bluetooth/bluetooth_remote_gatt_characteristic.h" |
| 25 | 29 |
| 26 namespace content { | 30 namespace content { |
| 27 | 31 |
| 28 namespace { | 32 namespace { |
| 29 | 33 |
| 30 blink::mojom::WebBluetoothError TranslateConnectErrorAndRecord( | 34 blink::mojom::WebBluetoothError TranslateConnectErrorAndRecord( |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 163 WebBluetoothServiceImpl::WebBluetoothServiceImpl( | 167 WebBluetoothServiceImpl::WebBluetoothServiceImpl( |
| 164 RenderFrameHost* render_frame_host, | 168 RenderFrameHost* render_frame_host, |
| 165 blink::mojom::WebBluetoothServiceRequest request) | 169 blink::mojom::WebBluetoothServiceRequest request) |
| 166 : WebContentsObserver(WebContents::FromRenderFrameHost(render_frame_host)), | 170 : WebContentsObserver(WebContents::FromRenderFrameHost(render_frame_host)), |
| 167 connected_devices_(new FrameConnectedBluetoothDevices(render_frame_host)), | 171 connected_devices_(new FrameConnectedBluetoothDevices(render_frame_host)), |
| 168 render_frame_host_(render_frame_host), | 172 render_frame_host_(render_frame_host), |
| 169 binding_(this, std::move(request)), | 173 binding_(this, std::move(request)), |
| 170 weak_ptr_factory_(this) { | 174 weak_ptr_factory_(this) { |
| 171 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 175 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 172 CHECK(web_contents()); | 176 CHECK(web_contents()); |
| 173 | |
| 174 GetBluetoothDispatcherHost()->AddAdapterObserver(this); | |
| 175 } | 177 } |
| 176 | 178 |
| 177 WebBluetoothServiceImpl::~WebBluetoothServiceImpl() { | 179 WebBluetoothServiceImpl::~WebBluetoothServiceImpl() { |
| 178 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 180 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 179 GetBluetoothDispatcherHost()->RemoveAdapterObserver(this); | 181 GetBluetoothAdapterFactoryWrapper()->ReleaseAdapter(this); |
| 180 } | 182 } |
| 181 | 183 |
| 182 void WebBluetoothServiceImpl::SetClientConnectionErrorHandler( | 184 void WebBluetoothServiceImpl::SetClientConnectionErrorHandler( |
| 183 base::Closure closure) { | 185 base::Closure closure) { |
| 184 binding_.set_connection_error_handler(closure); | 186 binding_.set_connection_error_handler(closure); |
| 185 } | 187 } |
| 186 | 188 |
| 187 void WebBluetoothServiceImpl::DidFinishNavigation( | 189 void WebBluetoothServiceImpl::DidFinishNavigation( |
| 188 NavigationHandle* navigation_handle) { | 190 NavigationHandle* navigation_handle) { |
| 189 if (navigation_handle->HasCommitted() && | 191 if (navigation_handle->HasCommitted() && |
| 190 navigation_handle->GetRenderFrameHost() == render_frame_host_ && | 192 navigation_handle->GetRenderFrameHost() == render_frame_host_ && |
| 191 !navigation_handle->IsSamePage()) { | 193 !navigation_handle->IsSamePage()) { |
| 192 ClearState(); | 194 ClearState(); |
| 193 } | 195 } |
| 194 } | 196 } |
| 195 | 197 |
| 196 void WebBluetoothServiceImpl::AdapterPresentChanged( | 198 void WebBluetoothServiceImpl::AdapterPoweredChanged( |
| 197 device::BluetoothAdapter* adapter, | 199 device::BluetoothAdapter* adapter, |
| 198 bool present) { | 200 bool powered) { |
| 199 if (!present) { | 201 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 200 ClearState(); | 202 if (device_provider_.get()) { |
|
Jeffrey Yasskin
2016/05/13 04:41:59
Is removing this going to bring https://crbug.com/
ortuno
2016/05/13 20:11:18
Noup! That bug happened because the adapter in Blu
| |
| 203 device_provider_->AdapterPoweredChanged(powered); | |
| 201 } | 204 } |
| 202 } | 205 } |
| 203 | 206 |
| 207 void WebBluetoothServiceImpl::DeviceAdded(device::BluetoothAdapter* adapter, | |
| 208 device::BluetoothDevice* device) { | |
| 209 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| 210 if (device_provider_.get()) { | |
| 211 VLOG(1) << "Adding device to device provider: " << device->GetAddress(); | |
| 212 device_provider_->AddFilteredDevice(*device); | |
| 213 } | |
| 214 } | |
| 215 | |
| 204 void WebBluetoothServiceImpl::DeviceChanged(device::BluetoothAdapter* adapter, | 216 void WebBluetoothServiceImpl::DeviceChanged(device::BluetoothAdapter* adapter, |
| 205 device::BluetoothDevice* device) { | 217 device::BluetoothDevice* device) { |
| 206 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 218 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 207 if (!device->IsGattConnected() || !device->IsConnected()) { | 219 if (!device->IsGattConnected() || !device->IsConnected()) { |
| 208 std::string device_id = | 220 std::string device_id = |
| 209 connected_devices_->CloseConnectionToDeviceWithAddress( | 221 connected_devices_->CloseConnectionToDeviceWithAddress( |
| 210 device->GetAddress()); | 222 device->GetAddress()); |
| 211 if (!device_id.empty()) { | 223 if (!device_id.empty()) { |
| 212 // TODO(ortuno): Send event to client. | 224 // TODO(ortuno): Send event to client. |
| 213 // http://crbug.com/581855 | 225 // http://crbug.com/581855 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 268 characteristic_instance_id, mojo::Array<uint8_t>(std::move(value))); | 280 characteristic_instance_id, mojo::Array<uint8_t>(std::move(value))); |
| 269 } | 281 } |
| 270 } | 282 } |
| 271 | 283 |
| 272 void WebBluetoothServiceImpl::SetClient( | 284 void WebBluetoothServiceImpl::SetClient( |
| 273 blink::mojom::WebBluetoothServiceClientAssociatedPtrInfo client) { | 285 blink::mojom::WebBluetoothServiceClientAssociatedPtrInfo client) { |
| 274 DCHECK(!client_.get()); | 286 DCHECK(!client_.get()); |
| 275 client_.Bind(std::move(client)); | 287 client_.Bind(std::move(client)); |
| 276 } | 288 } |
| 277 | 289 |
| 290 void WebBluetoothServiceImpl::RequestDevice( | |
| 291 blink::mojom::WebBluetoothRequestDeviceOptionsPtr options, | |
| 292 const RequestDeviceCallback& callback) { | |
| 293 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::REQUEST_DEVICE); | |
| 294 RecordRequestDeviceOptions(options); | |
| 295 | |
| 296 if (!GetBluetoothAdapterFactoryWrapper()->GetAdapter(this)) { | |
| 297 if (GetBluetoothAdapterFactoryWrapper()->IsBluetoothAdapterAvailable()) { | |
| 298 GetBluetoothAdapterFactoryWrapper()->AcquireAdapter( | |
| 299 this, base::Bind(&WebBluetoothServiceImpl::RequestDeviceImpl, | |
| 300 weak_ptr_factory_.GetWeakPtr(), | |
| 301 base::Passed(std::move(options)), callback)); | |
| 302 return; | |
| 303 } | |
| 304 RecordRequestDeviceOutcome(UMARequestDeviceOutcome::NO_BLUETOOTH_ADAPTER); | |
| 305 callback.Run(blink::mojom::WebBluetoothError::NO_BLUETOOTH_ADAPTER, | |
| 306 nullptr /* device */); | |
| 307 return; | |
| 308 } | |
| 309 RequestDeviceImpl(std::move(options), callback); | |
| 310 } | |
| 311 | |
| 278 void WebBluetoothServiceImpl::RemoteServerConnect( | 312 void WebBluetoothServiceImpl::RemoteServerConnect( |
| 279 const mojo::String& device_id, | 313 const mojo::String& device_id, |
| 280 const RemoteServerConnectCallback& callback) { | 314 const RemoteServerConnectCallback& callback) { |
| 281 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 315 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 282 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::CONNECT_GATT); | 316 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::CONNECT_GATT); |
| 283 | 317 |
| 284 const CacheQueryResult query_result = | 318 const CacheQueryResult query_result = QueryCacheForDevice(device_id); |
| 285 GetBluetoothDispatcherHost()->QueryCacheForDevice(GetOrigin(), device_id); | |
| 286 | 319 |
| 287 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { | 320 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { |
| 288 RecordConnectGATTOutcome(query_result.outcome); | 321 RecordConnectGATTOutcome(query_result.outcome); |
| 289 callback.Run(query_result.GetWebError()); | 322 callback.Run(query_result.GetWebError()); |
| 290 return; | 323 return; |
| 291 } | 324 } |
| 292 | 325 |
| 293 if (connected_devices_->IsConnectedToDeviceWithId(device_id)) { | 326 if (connected_devices_->IsConnectedToDeviceWithId(device_id)) { |
| 294 VLOG(1) << "Already connected."; | 327 VLOG(1) << "Already connected."; |
| 295 callback.Run(blink::mojom::WebBluetoothError::SUCCESS); | 328 callback.Run(blink::mojom::WebBluetoothError::SUCCESS); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 328 } | 361 } |
| 329 | 362 |
| 330 void WebBluetoothServiceImpl::RemoteServerGetPrimaryService( | 363 void WebBluetoothServiceImpl::RemoteServerGetPrimaryService( |
| 331 const mojo::String& device_id, | 364 const mojo::String& device_id, |
| 332 const mojo::String& service_uuid, | 365 const mojo::String& service_uuid, |
| 333 const RemoteServerGetPrimaryServiceCallback& callback) { | 366 const RemoteServerGetPrimaryServiceCallback& callback) { |
| 334 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 367 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 335 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::GET_PRIMARY_SERVICE); | 368 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::GET_PRIMARY_SERVICE); |
| 336 RecordGetPrimaryServiceService(device::BluetoothUUID(service_uuid)); | 369 RecordGetPrimaryServiceService(device::BluetoothUUID(service_uuid)); |
| 337 | 370 |
| 338 if (!GetBluetoothDispatcherHost() | 371 if (!allowed_devices_map_.IsOriginAllowedToAccessService( |
| 339 ->allowed_devices_map_.IsOriginAllowedToAccessService( | 372 GetOrigin(), device_id, service_uuid)) { |
| 340 GetOrigin(), device_id, service_uuid)) { | |
| 341 callback.Run(blink::mojom::WebBluetoothError::NOT_ALLOWED_TO_ACCESS_SERVICE, | 373 callback.Run(blink::mojom::WebBluetoothError::NOT_ALLOWED_TO_ACCESS_SERVICE, |
| 342 nullptr /* service */); | 374 nullptr /* service */); |
| 343 return; | 375 return; |
| 344 } | 376 } |
| 345 | 377 |
| 346 const CacheQueryResult query_result = | 378 const CacheQueryResult query_result = QueryCacheForDevice(device_id); |
| 347 GetBluetoothDispatcherHost()->QueryCacheForDevice(GetOrigin(), device_id); | |
| 348 | 379 |
| 349 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { | 380 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { |
| 350 binding_.Close(); | 381 binding_.Close(); |
| 351 return; | 382 return; |
| 352 } | 383 } |
| 353 | 384 |
| 354 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { | 385 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { |
| 355 RecordGetPrimaryServiceOutcome(query_result.outcome); | 386 RecordGetPrimaryServiceOutcome(query_result.outcome); |
| 356 callback.Run(query_result.GetWebError(), nullptr /* service */); | 387 callback.Run(query_result.GetWebError(), nullptr /* service */); |
| 357 return; | 388 return; |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 606 // If the frame hasn't subscribed to notifications before we just | 637 // If the frame hasn't subscribed to notifications before we just |
| 607 // run the callback. | 638 // run the callback. |
| 608 callback.Run(); | 639 callback.Run(); |
| 609 return; | 640 return; |
| 610 } | 641 } |
| 611 notify_session_iter->second->Stop(base::Bind( | 642 notify_session_iter->second->Stop(base::Bind( |
| 612 &WebBluetoothServiceImpl::OnStopNotifySessionComplete, | 643 &WebBluetoothServiceImpl::OnStopNotifySessionComplete, |
| 613 weak_ptr_factory_.GetWeakPtr(), characteristic_instance_id, callback)); | 644 weak_ptr_factory_.GetWeakPtr(), characteristic_instance_id, callback)); |
| 614 } | 645 } |
| 615 | 646 |
| 647 void WebBluetoothServiceImpl::RequestDeviceImpl( | |
| 648 blink::mojom::WebBluetoothRequestDeviceOptionsPtr options, | |
| 649 const RequestDeviceCallback& callback) { | |
| 650 // requestDevice() can only be called when processing a user-gesture and | |
| 651 // any user gesture outside of a chooser should close the chooser so we should | |
| 652 // never get a request with an open chooser. | |
| 653 CHECK(!device_provider_.get()); | |
| 654 | |
| 655 device_provider_.reset(new BluetoothDeviceProvider( | |
| 656 render_frame_host_, GetBluetoothAdapterFactoryWrapper()->GetAdapter(this), | |
| 657 GetBluetoothAdapterFactoryWrapper()->GetScanDuration())); | |
| 658 | |
| 659 device_provider_->GetDevice( | |
| 660 options->Clone(), base::Bind(&WebBluetoothServiceImpl::OnGetDeviceSuccess, | |
| 661 weak_ptr_factory_.GetWeakPtr(), | |
| 662 base::Passed(options->Clone()), callback), | |
|
Jeffrey Yasskin
2016/05/13 04:41:59
Instead of cloning the options, would it make sens
ortuno
2016/05/13 20:11:18
Done.
| |
| 663 base::Bind(&WebBluetoothServiceImpl::OnGetDeviceFailed, | |
| 664 weak_ptr_factory_.GetWeakPtr(), callback)); | |
| 665 } | |
| 666 | |
| 616 void WebBluetoothServiceImpl::RemoteServerGetPrimaryServiceImpl( | 667 void WebBluetoothServiceImpl::RemoteServerGetPrimaryServiceImpl( |
| 617 const std::string& service_uuid, | 668 const std::string& service_uuid, |
| 618 const RemoteServerGetPrimaryServiceCallback& callback, | 669 const RemoteServerGetPrimaryServiceCallback& callback, |
| 619 device::BluetoothDevice* device) { | 670 device::BluetoothDevice* device) { |
| 620 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 671 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 621 DCHECK(device->IsGattServicesDiscoveryComplete()); | 672 DCHECK(device->IsGattServicesDiscoveryComplete()); |
| 622 | 673 |
| 623 std::vector<device::BluetoothRemoteGattService*> services = | 674 std::vector<device::BluetoothRemoteGattService*> services = |
| 624 GetPrimaryServicesByUUID(device, service_uuid); | 675 GetPrimaryServicesByUUID(device, service_uuid); |
| 625 | 676 |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 641 | 692 |
| 642 RecordGetPrimaryServiceOutcome(UMAGetPrimaryServiceOutcome::SUCCESS); | 693 RecordGetPrimaryServiceOutcome(UMAGetPrimaryServiceOutcome::SUCCESS); |
| 643 blink::mojom::WebBluetoothRemoteGATTServicePtr service_ptr = | 694 blink::mojom::WebBluetoothRemoteGATTServicePtr service_ptr = |
| 644 blink::mojom::WebBluetoothRemoteGATTService::New(); | 695 blink::mojom::WebBluetoothRemoteGATTService::New(); |
| 645 service_ptr->instance_id = services[0]->GetIdentifier(); | 696 service_ptr->instance_id = services[0]->GetIdentifier(); |
| 646 service_ptr->uuid = services[0]->GetUUID().canonical_value(); | 697 service_ptr->uuid = services[0]->GetUUID().canonical_value(); |
| 647 callback.Run(blink::mojom::WebBluetoothError::SUCCESS, | 698 callback.Run(blink::mojom::WebBluetoothError::SUCCESS, |
| 648 std::move(service_ptr)); | 699 std::move(service_ptr)); |
| 649 } | 700 } |
| 650 | 701 |
| 702 void WebBluetoothServiceImpl::OnGetDeviceSuccess( | |
| 703 blink::mojom::WebBluetoothRequestDeviceOptionsPtr options, | |
| 704 const RequestDeviceCallback& callback, | |
| 705 const std::string& device_address) { | |
| 706 blink::mojom::WebBluetoothDevicePtr device_ptr = | |
|
Jeffrey Yasskin
2016/05/13 04:41:59
I'd probably create this just before it's used for
ortuno
2016/05/13 20:11:18
Done.
| |
| 707 blink::mojom::WebBluetoothDevice::New(); | |
| 708 | |
| 709 const device::BluetoothDevice* const device = | |
| 710 GetBluetoothAdapterFactoryWrapper()->GetAdapter(this)->GetDevice( | |
|
Jeffrey Yasskin
2016/05/13 04:41:59
Consider wrapping the "GetBluetoothAdapterFactoryW
ortuno
2016/05/13 20:11:18
Done.
| |
| 711 device_address); | |
| 712 if (device == nullptr) { | |
| 713 VLOG(1) << "Device " << device_address << " no longer in adapter"; | |
| 714 RecordRequestDeviceOutcome(UMARequestDeviceOutcome::CHOSEN_DEVICE_VANISHED); | |
| 715 callback.Run(blink::mojom::WebBluetoothError::CHOSEN_DEVICE_VANISHED, | |
| 716 nullptr /* device */); | |
| 717 device_provider_.reset(); | |
|
Jeffrey Yasskin
2016/05/13 04:41:59
Can you reset this at the beginning of the functio
ortuno
2016/05/13 20:11:18
Done.
| |
| 718 return; | |
| 719 } | |
| 720 | |
| 721 const std::string device_id_for_origin = | |
| 722 allowed_devices_map_.AddDevice(GetOrigin(), device_address, options); | |
| 723 | |
| 724 VLOG(1) << "Device: " << device->GetName(); | |
| 725 VLOG(1) << "UUIDs: "; | |
| 726 | |
| 727 mojo::Array<mojo::String> filtered_uuids; | |
| 728 for (const device::BluetoothUUID& uuid : device->GetUUIDs()) { | |
| 729 if (allowed_devices_map_.IsOriginAllowedToAccessService( | |
| 730 GetOrigin(), device_id_for_origin, uuid.canonical_value())) { | |
| 731 VLOG(1) << "\t Allowed: " << uuid.canonical_value(); | |
| 732 filtered_uuids.push_back(uuid.canonical_value()); | |
| 733 } else { | |
| 734 VLOG(1) << "\t Not Allowed: " << uuid.canonical_value(); | |
| 735 } | |
| 736 } | |
| 737 | |
| 738 device_ptr->id = device_id_for_origin; | |
| 739 device_ptr->name = base::UTF16ToUTF8(device->GetName()); | |
| 740 device_ptr->uuids = std::move(filtered_uuids); | |
| 741 | |
| 742 RecordRequestDeviceOutcome(UMARequestDeviceOutcome::SUCCESS); | |
| 743 callback.Run(blink::mojom::WebBluetoothError::SUCCESS, std::move(device_ptr)); | |
| 744 device_provider_.reset(); | |
| 745 } | |
| 746 | |
| 747 void WebBluetoothServiceImpl::OnGetDeviceFailed( | |
| 748 const RequestDeviceCallback& callback, | |
| 749 blink::mojom::WebBluetoothError error) { | |
| 750 // Errors are recorded by the BluetoothDeviceProvider that called this | |
|
Jeffrey Yasskin
2016/05/13 04:41:59
Or just "by *device_provider_."?
ortuno
2016/05/13 20:11:18
Done.
| |
| 751 // function. | |
| 752 callback.Run(error, nullptr /* device */); | |
| 753 device_provider_.reset(); | |
| 754 } | |
| 755 | |
| 651 void WebBluetoothServiceImpl::OnCreateGATTConnectionSuccess( | 756 void WebBluetoothServiceImpl::OnCreateGATTConnectionSuccess( |
| 652 const std::string& device_id, | 757 const std::string& device_id, |
| 653 base::TimeTicks start_time, | 758 base::TimeTicks start_time, |
| 654 const RemoteServerConnectCallback& callback, | 759 const RemoteServerConnectCallback& callback, |
| 655 std::unique_ptr<device::BluetoothGattConnection> connection) { | 760 std::unique_ptr<device::BluetoothGattConnection> connection) { |
| 656 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 761 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 657 RecordConnectGATTTimeSuccess(base::TimeTicks::Now() - start_time); | 762 RecordConnectGATTTimeSuccess(base::TimeTicks::Now() - start_time); |
| 658 RecordConnectGATTOutcome(UMAConnectGATTOutcome::SUCCESS); | 763 RecordConnectGATTOutcome(UMAConnectGATTOutcome::SUCCESS); |
| 659 | 764 |
| 660 connected_devices_->Insert(device_id, std::move(connection)); | 765 connected_devices_->Insert(device_id, std::move(connection)); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 726 error_code, UMAGATTOperation::START_NOTIFICATIONS)); | 831 error_code, UMAGATTOperation::START_NOTIFICATIONS)); |
| 727 } | 832 } |
| 728 | 833 |
| 729 void WebBluetoothServiceImpl::OnStopNotifySessionComplete( | 834 void WebBluetoothServiceImpl::OnStopNotifySessionComplete( |
| 730 const std::string& characteristic_instance_id, | 835 const std::string& characteristic_instance_id, |
| 731 const RemoteCharacteristicStopNotificationsCallback& callback) { | 836 const RemoteCharacteristicStopNotificationsCallback& callback) { |
| 732 characteristic_id_to_notify_session_.erase(characteristic_instance_id); | 837 characteristic_id_to_notify_session_.erase(characteristic_instance_id); |
| 733 callback.Run(); | 838 callback.Run(); |
| 734 } | 839 } |
| 735 | 840 |
| 841 CacheQueryResult WebBluetoothServiceImpl::QueryCacheForDevice( | |
| 842 const std::string& device_id) { | |
| 843 const std::string& device_address = | |
| 844 allowed_devices_map_.GetDeviceAddress(GetOrigin(), device_id); | |
| 845 if (device_address.empty()) { | |
| 846 CrashRendererAndClosePipe(bad_message::BDH_DEVICE_NOT_ALLOWED_FOR_ORIGIN); | |
| 847 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); | |
| 848 } | |
| 849 | |
| 850 CacheQueryResult result; | |
| 851 result.device = | |
| 852 GetBluetoothAdapterFactoryWrapper()->GetAdapter(this)->GetDevice( | |
| 853 device_address); | |
| 854 | |
| 855 // When a device can't be found in the BluetoothAdapter, that generally | |
| 856 // indicates that it's gone out of range. We reject with a NetworkError in | |
| 857 // that case. | |
| 858 if (result.device == nullptr) { | |
| 859 result.outcome = CacheQueryOutcome::NO_DEVICE; | |
| 860 } | |
| 861 return result; | |
| 862 } | |
| 863 | |
| 736 CacheQueryResult WebBluetoothServiceImpl::QueryCacheForService( | 864 CacheQueryResult WebBluetoothServiceImpl::QueryCacheForService( |
| 737 const std::string& service_instance_id) { | 865 const std::string& service_instance_id) { |
| 738 auto device_iter = service_id_to_device_address_.find(service_instance_id); | 866 auto device_iter = service_id_to_device_address_.find(service_instance_id); |
| 739 | 867 |
| 740 // Kill the render, see "ID Not in Map Note" above. | 868 // Kill the render, see "ID Not in Map Note" above. |
| 741 if (device_iter == service_id_to_device_address_.end()) { | 869 if (device_iter == service_id_to_device_address_.end()) { |
| 742 CrashRendererAndClosePipe(bad_message::BDH_INVALID_SERVICE_ID); | 870 CrashRendererAndClosePipe(bad_message::BDH_INVALID_SERVICE_ID); |
| 743 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); | 871 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); |
| 744 } | 872 } |
| 745 | 873 |
| 746 const std::string& device_id = | 874 const std::string& device_id = |
| 747 GetBluetoothDispatcherHost()->allowed_devices_map_.GetDeviceId( | 875 allowed_devices_map_.GetDeviceId(GetOrigin(), device_iter->second); |
| 748 GetOrigin(), device_iter->second); | |
| 749 // Kill the renderer if origin is not allowed to access the device. | 876 // Kill the renderer if origin is not allowed to access the device. |
| 750 if (device_id.empty()) { | 877 if (device_id.empty()) { |
| 751 CrashRendererAndClosePipe(bad_message::BDH_DEVICE_NOT_ALLOWED_FOR_ORIGIN); | 878 CrashRendererAndClosePipe(bad_message::BDH_DEVICE_NOT_ALLOWED_FOR_ORIGIN); |
| 752 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); | 879 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); |
| 753 } | 880 } |
| 754 | 881 |
| 755 CacheQueryResult result = | 882 CacheQueryResult result = QueryCacheForDevice(device_id); |
| 756 GetBluetoothDispatcherHost()->QueryCacheForDevice(GetOrigin(), device_id); | |
| 757 | |
| 758 // TODO(ortuno): Remove once QueryCacheForDevice closes binding_. | |
| 759 // http://crbug.com/508771 | |
| 760 if (result.outcome == CacheQueryOutcome::BAD_RENDERER) { | |
| 761 binding_.Close(); | |
| 762 } | |
| 763 | |
| 764 if (result.outcome != CacheQueryOutcome::SUCCESS) { | 883 if (result.outcome != CacheQueryOutcome::SUCCESS) { |
| 765 return result; | 884 return result; |
| 766 } | 885 } |
| 767 | 886 |
| 768 result.service = result.device->GetGattService(service_instance_id); | 887 result.service = result.device->GetGattService(service_instance_id); |
| 769 if (result.service == nullptr) { | 888 if (result.service == nullptr) { |
| 770 result.outcome = CacheQueryOutcome::NO_SERVICE; | 889 result.outcome = CacheQueryOutcome::NO_SERVICE; |
| 771 } else if (!GetBluetoothDispatcherHost() | 890 } else if (!allowed_devices_map_.IsOriginAllowedToAccessService( |
| 772 ->allowed_devices_map_.IsOriginAllowedToAccessService( | 891 GetOrigin(), device_id, |
| 773 GetOrigin(), device_id, | 892 result.service->GetUUID().canonical_value())) { |
| 774 result.service->GetUUID().canonical_value())) { | |
| 775 CrashRendererAndClosePipe(bad_message::BDH_SERVICE_NOT_ALLOWED_FOR_ORIGIN); | 893 CrashRendererAndClosePipe(bad_message::BDH_SERVICE_NOT_ALLOWED_FOR_ORIGIN); |
| 776 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); | 894 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); |
| 777 } | 895 } |
| 778 return result; | 896 return result; |
| 779 } | 897 } |
| 780 | 898 |
| 781 CacheQueryResult WebBluetoothServiceImpl::QueryCacheForCharacteristic( | 899 CacheQueryResult WebBluetoothServiceImpl::QueryCacheForCharacteristic( |
| 782 const std::string& characteristic_instance_id) { | 900 const std::string& characteristic_instance_id) { |
| 783 auto characteristic_iter = | 901 auto characteristic_iter = |
| 784 characteristic_id_to_service_id_.find(characteristic_instance_id); | 902 characteristic_id_to_service_id_.find(characteristic_instance_id); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 802 result.outcome = CacheQueryOutcome::NO_CHARACTERISTIC; | 920 result.outcome = CacheQueryOutcome::NO_CHARACTERISTIC; |
| 803 } | 921 } |
| 804 | 922 |
| 805 return result; | 923 return result; |
| 806 } | 924 } |
| 807 | 925 |
| 808 RenderProcessHost* WebBluetoothServiceImpl::GetRenderProcessHost() { | 926 RenderProcessHost* WebBluetoothServiceImpl::GetRenderProcessHost() { |
| 809 return render_frame_host_->GetProcess(); | 927 return render_frame_host_->GetProcess(); |
| 810 } | 928 } |
| 811 | 929 |
| 812 BluetoothDispatcherHost* WebBluetoothServiceImpl::GetBluetoothDispatcherHost() { | 930 BluetoothAdapterFactoryWrapper* |
| 931 WebBluetoothServiceImpl::GetBluetoothAdapterFactoryWrapper() { | |
| 813 RenderProcessHostImpl* render_process_host_impl = | 932 RenderProcessHostImpl* render_process_host_impl = |
| 814 static_cast<RenderProcessHostImpl*>(GetRenderProcessHost()); | 933 static_cast<RenderProcessHostImpl*>(GetRenderProcessHost()); |
| 815 return render_process_host_impl->GetBluetoothDispatcherHost(); | 934 return render_process_host_impl->GetBluetoothAdapterFactoryWrapper(); |
| 816 } | 935 } |
| 817 | 936 |
| 818 void WebBluetoothServiceImpl::CrashRendererAndClosePipe( | 937 void WebBluetoothServiceImpl::CrashRendererAndClosePipe( |
| 819 bad_message::BadMessageReason reason) { | 938 bad_message::BadMessageReason reason) { |
| 820 bad_message::ReceivedBadMessage(GetRenderProcessHost(), reason); | 939 bad_message::ReceivedBadMessage(GetRenderProcessHost(), reason); |
| 821 binding_.Close(); | 940 binding_.Close(); |
| 822 } | 941 } |
| 823 | 942 |
| 824 url::Origin WebBluetoothServiceImpl::GetOrigin() { | 943 url::Origin WebBluetoothServiceImpl::GetOrigin() { |
| 825 return render_frame_host_->GetLastCommittedOrigin(); | 944 return render_frame_host_->GetLastCommittedOrigin(); |
| 826 } | 945 } |
| 827 | 946 |
| 828 void WebBluetoothServiceImpl::ClearState() { | 947 void WebBluetoothServiceImpl::ClearState() { |
| 829 characteristic_id_to_notify_session_.clear(); | 948 characteristic_id_to_notify_session_.clear(); |
| 830 pending_primary_services_requests_.clear(); | 949 pending_primary_services_requests_.clear(); |
| 831 characteristic_id_to_service_id_.clear(); | 950 characteristic_id_to_service_id_.clear(); |
| 832 service_id_to_device_address_.clear(); | 951 service_id_to_device_address_.clear(); |
| 833 connected_devices_.reset( | 952 connected_devices_.reset( |
| 834 new FrameConnectedBluetoothDevices(render_frame_host_)); | 953 new FrameConnectedBluetoothDevices(render_frame_host_)); |
| 954 allowed_devices_map_ = BluetoothAllowedDevicesMap(); | |
| 955 device_provider_.reset(); | |
| 956 GetBluetoothAdapterFactoryWrapper()->ReleaseAdapter(this); | |
| 835 } | 957 } |
| 836 | 958 |
| 837 } // namespace content | 959 } // namespace content |
| OLD | NEW |