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/threading/thread_task_runner_handle.h" | 17 #include "base/threading/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_chooser_controller.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 ClearState(); |
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_chooser_controller_.get()) { |
| 203 device_chooser_controller_->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_chooser_controller_.get()) { |
| 211 VLOG(1) << "Adding device to device chooser controller: " |
| 212 << device->GetAddress(); |
| 213 device_chooser_controller_->AddFilteredDevice(*device); |
| 214 } |
| 215 } |
| 216 |
204 void WebBluetoothServiceImpl::DeviceChanged(device::BluetoothAdapter* adapter, | 217 void WebBluetoothServiceImpl::DeviceChanged(device::BluetoothAdapter* adapter, |
205 device::BluetoothDevice* device) { | 218 device::BluetoothDevice* device) { |
206 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 219 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
207 if (!device->IsGattConnected() || !device->IsConnected()) { | 220 if (!device->IsGattConnected() || !device->IsConnected()) { |
208 std::string device_id = | 221 std::string device_id = |
209 connected_devices_->CloseConnectionToDeviceWithAddress( | 222 connected_devices_->CloseConnectionToDeviceWithAddress( |
210 device->GetAddress()); | 223 device->GetAddress()); |
211 if (!device_id.empty()) { | 224 if (!device_id.empty()) { |
212 // TODO(ortuno): Send event to client. | 225 // TODO(ortuno): Send event to client. |
213 // http://crbug.com/581855 | 226 // 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))); | 281 characteristic_instance_id, mojo::Array<uint8_t>(std::move(value))); |
269 } | 282 } |
270 } | 283 } |
271 | 284 |
272 void WebBluetoothServiceImpl::SetClient( | 285 void WebBluetoothServiceImpl::SetClient( |
273 blink::mojom::WebBluetoothServiceClientAssociatedPtrInfo client) { | 286 blink::mojom::WebBluetoothServiceClientAssociatedPtrInfo client) { |
274 DCHECK(!client_.get()); | 287 DCHECK(!client_.get()); |
275 client_.Bind(std::move(client)); | 288 client_.Bind(std::move(client)); |
276 } | 289 } |
277 | 290 |
| 291 void WebBluetoothServiceImpl::RequestDevice( |
| 292 blink::mojom::WebBluetoothRequestDeviceOptionsPtr options, |
| 293 const RequestDeviceCallback& callback) { |
| 294 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::REQUEST_DEVICE); |
| 295 RecordRequestDeviceOptions(options); |
| 296 |
| 297 if (!GetAdapter()) { |
| 298 if (GetBluetoothAdapterFactoryWrapper().IsBluetoothAdapterAvailable()) { |
| 299 GetBluetoothAdapterFactoryWrapper().AcquireAdapter( |
| 300 this, base::Bind(&WebBluetoothServiceImpl::RequestDeviceImpl, |
| 301 weak_ptr_factory_.GetWeakPtr(), |
| 302 base::Passed(std::move(options)), callback)); |
| 303 return; |
| 304 } |
| 305 RecordRequestDeviceOutcome(UMARequestDeviceOutcome::NO_BLUETOOTH_ADAPTER); |
| 306 callback.Run(blink::mojom::WebBluetoothError::NO_BLUETOOTH_ADAPTER, |
| 307 nullptr /* device */); |
| 308 return; |
| 309 } |
| 310 RequestDeviceImpl(std::move(options), callback, GetAdapter()); |
| 311 } |
| 312 |
278 void WebBluetoothServiceImpl::RemoteServerConnect( | 313 void WebBluetoothServiceImpl::RemoteServerConnect( |
279 const mojo::String& device_id, | 314 const mojo::String& device_id, |
280 const RemoteServerConnectCallback& callback) { | 315 const RemoteServerConnectCallback& callback) { |
281 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 316 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
282 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::CONNECT_GATT); | 317 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::CONNECT_GATT); |
283 | 318 |
284 const CacheQueryResult query_result = | 319 const CacheQueryResult query_result = QueryCacheForDevice(device_id); |
285 GetBluetoothDispatcherHost()->QueryCacheForDevice(GetOrigin(), device_id); | |
286 | 320 |
287 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { | 321 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { |
288 RecordConnectGATTOutcome(query_result.outcome); | 322 RecordConnectGATTOutcome(query_result.outcome); |
289 callback.Run(query_result.GetWebError()); | 323 callback.Run(query_result.GetWebError()); |
290 return; | 324 return; |
291 } | 325 } |
292 | 326 |
293 if (connected_devices_->IsConnectedToDeviceWithId(device_id)) { | 327 if (connected_devices_->IsConnectedToDeviceWithId(device_id)) { |
294 VLOG(1) << "Already connected."; | 328 VLOG(1) << "Already connected."; |
295 callback.Run(blink::mojom::WebBluetoothError::SUCCESS); | 329 callback.Run(blink::mojom::WebBluetoothError::SUCCESS); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 } | 362 } |
329 | 363 |
330 void WebBluetoothServiceImpl::RemoteServerGetPrimaryService( | 364 void WebBluetoothServiceImpl::RemoteServerGetPrimaryService( |
331 const mojo::String& device_id, | 365 const mojo::String& device_id, |
332 const mojo::String& service_uuid, | 366 const mojo::String& service_uuid, |
333 const RemoteServerGetPrimaryServiceCallback& callback) { | 367 const RemoteServerGetPrimaryServiceCallback& callback) { |
334 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 368 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
335 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::GET_PRIMARY_SERVICE); | 369 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::GET_PRIMARY_SERVICE); |
336 RecordGetPrimaryServiceService(device::BluetoothUUID(service_uuid)); | 370 RecordGetPrimaryServiceService(device::BluetoothUUID(service_uuid)); |
337 | 371 |
338 if (!GetBluetoothDispatcherHost() | 372 if (!allowed_devices_map_.IsOriginAllowedToAccessService( |
339 ->allowed_devices_map_.IsOriginAllowedToAccessService( | 373 GetOrigin(), device_id, service_uuid)) { |
340 GetOrigin(), device_id, service_uuid)) { | |
341 callback.Run(blink::mojom::WebBluetoothError::NOT_ALLOWED_TO_ACCESS_SERVICE, | 374 callback.Run(blink::mojom::WebBluetoothError::NOT_ALLOWED_TO_ACCESS_SERVICE, |
342 nullptr /* service */); | 375 nullptr /* service */); |
343 return; | 376 return; |
344 } | 377 } |
345 | 378 |
346 const CacheQueryResult query_result = | 379 const CacheQueryResult query_result = QueryCacheForDevice(device_id); |
347 GetBluetoothDispatcherHost()->QueryCacheForDevice(GetOrigin(), device_id); | |
348 | 380 |
349 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { | 381 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { |
350 binding_.Close(); | 382 binding_.Close(); |
351 return; | 383 return; |
352 } | 384 } |
353 | 385 |
354 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { | 386 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { |
355 RecordGetPrimaryServiceOutcome(query_result.outcome); | 387 RecordGetPrimaryServiceOutcome(query_result.outcome); |
356 callback.Run(query_result.GetWebError(), nullptr /* service */); | 388 callback.Run(query_result.GetWebError(), nullptr /* service */); |
357 return; | 389 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 | 638 // If the frame hasn't subscribed to notifications before we just |
607 // run the callback. | 639 // run the callback. |
608 callback.Run(); | 640 callback.Run(); |
609 return; | 641 return; |
610 } | 642 } |
611 notify_session_iter->second->Stop(base::Bind( | 643 notify_session_iter->second->Stop(base::Bind( |
612 &WebBluetoothServiceImpl::OnStopNotifySessionComplete, | 644 &WebBluetoothServiceImpl::OnStopNotifySessionComplete, |
613 weak_ptr_factory_.GetWeakPtr(), characteristic_instance_id, callback)); | 645 weak_ptr_factory_.GetWeakPtr(), characteristic_instance_id, callback)); |
614 } | 646 } |
615 | 647 |
| 648 void WebBluetoothServiceImpl::RequestDeviceImpl( |
| 649 blink::mojom::WebBluetoothRequestDeviceOptionsPtr options, |
| 650 const RequestDeviceCallback& callback, |
| 651 device::BluetoothAdapter* adapter) { |
| 652 // requestDevice() can only be called when processing a user-gesture and |
| 653 // any user gesture outside of a chooser should close the chooser so we should |
| 654 // never get a request with an open chooser. |
| 655 CHECK(!device_chooser_controller_.get()); |
| 656 |
| 657 device_chooser_controller_.reset(new BluetoothDeviceChooserController( |
| 658 this, render_frame_host_, adapter, |
| 659 GetBluetoothAdapterFactoryWrapper().GetScanDuration())); |
| 660 |
| 661 device_chooser_controller_->GetDevice( |
| 662 std::move(options), |
| 663 base::Bind(&WebBluetoothServiceImpl::OnGetDeviceSuccess, |
| 664 weak_ptr_factory_.GetWeakPtr(), callback), |
| 665 base::Bind(&WebBluetoothServiceImpl::OnGetDeviceFailed, |
| 666 weak_ptr_factory_.GetWeakPtr(), callback)); |
| 667 } |
| 668 |
616 void WebBluetoothServiceImpl::RemoteServerGetPrimaryServiceImpl( | 669 void WebBluetoothServiceImpl::RemoteServerGetPrimaryServiceImpl( |
617 const std::string& service_uuid, | 670 const std::string& service_uuid, |
618 const RemoteServerGetPrimaryServiceCallback& callback, | 671 const RemoteServerGetPrimaryServiceCallback& callback, |
619 device::BluetoothDevice* device) { | 672 device::BluetoothDevice* device) { |
620 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 673 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
621 DCHECK(device->IsGattServicesDiscoveryComplete()); | 674 DCHECK(device->IsGattServicesDiscoveryComplete()); |
622 | 675 |
623 std::vector<device::BluetoothRemoteGattService*> services = | 676 std::vector<device::BluetoothRemoteGattService*> services = |
624 GetPrimaryServicesByUUID(device, service_uuid); | 677 GetPrimaryServicesByUUID(device, service_uuid); |
625 | 678 |
(...skipping 15 matching lines...) Expand all Loading... |
641 | 694 |
642 RecordGetPrimaryServiceOutcome(UMAGetPrimaryServiceOutcome::SUCCESS); | 695 RecordGetPrimaryServiceOutcome(UMAGetPrimaryServiceOutcome::SUCCESS); |
643 blink::mojom::WebBluetoothRemoteGATTServicePtr service_ptr = | 696 blink::mojom::WebBluetoothRemoteGATTServicePtr service_ptr = |
644 blink::mojom::WebBluetoothRemoteGATTService::New(); | 697 blink::mojom::WebBluetoothRemoteGATTService::New(); |
645 service_ptr->instance_id = services[0]->GetIdentifier(); | 698 service_ptr->instance_id = services[0]->GetIdentifier(); |
646 service_ptr->uuid = services[0]->GetUUID().canonical_value(); | 699 service_ptr->uuid = services[0]->GetUUID().canonical_value(); |
647 callback.Run(blink::mojom::WebBluetoothError::SUCCESS, | 700 callback.Run(blink::mojom::WebBluetoothError::SUCCESS, |
648 std::move(service_ptr)); | 701 std::move(service_ptr)); |
649 } | 702 } |
650 | 703 |
| 704 void WebBluetoothServiceImpl::OnGetDeviceSuccess( |
| 705 const RequestDeviceCallback& callback, |
| 706 blink::mojom::WebBluetoothRequestDeviceOptionsPtr options, |
| 707 const std::string& device_address) { |
| 708 device_chooser_controller_.reset(); |
| 709 |
| 710 const device::BluetoothDevice* const device = |
| 711 GetAdapter()->GetDevice(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 return; |
| 718 } |
| 719 |
| 720 const std::string device_id_for_origin = |
| 721 allowed_devices_map_.AddDevice(GetOrigin(), device_address, options); |
| 722 |
| 723 VLOG(1) << "Device: " << device->GetName(); |
| 724 VLOG(1) << "UUIDs: "; |
| 725 |
| 726 mojo::Array<mojo::String> filtered_uuids; |
| 727 for (const device::BluetoothUUID& uuid : device->GetUUIDs()) { |
| 728 if (allowed_devices_map_.IsOriginAllowedToAccessService( |
| 729 GetOrigin(), device_id_for_origin, uuid.canonical_value())) { |
| 730 VLOG(1) << "\t Allowed: " << uuid.canonical_value(); |
| 731 filtered_uuids.push_back(uuid.canonical_value()); |
| 732 } else { |
| 733 VLOG(1) << "\t Not Allowed: " << uuid.canonical_value(); |
| 734 } |
| 735 } |
| 736 |
| 737 blink::mojom::WebBluetoothDevicePtr device_ptr = |
| 738 blink::mojom::WebBluetoothDevice::New(); |
| 739 device_ptr->id = device_id_for_origin; |
| 740 device_ptr->name = base::UTF16ToUTF8(device->GetName()); |
| 741 device_ptr->uuids = std::move(filtered_uuids); |
| 742 |
| 743 RecordRequestDeviceOutcome(UMARequestDeviceOutcome::SUCCESS); |
| 744 callback.Run(blink::mojom::WebBluetoothError::SUCCESS, std::move(device_ptr)); |
| 745 } |
| 746 |
| 747 void WebBluetoothServiceImpl::OnGetDeviceFailed( |
| 748 const RequestDeviceCallback& callback, |
| 749 blink::mojom::WebBluetoothError error) { |
| 750 // Errors are recorded by the *device_chooser_controller_. |
| 751 callback.Run(error, nullptr /* device */); |
| 752 device_chooser_controller_.reset(); |
| 753 } |
| 754 |
651 void WebBluetoothServiceImpl::OnCreateGATTConnectionSuccess( | 755 void WebBluetoothServiceImpl::OnCreateGATTConnectionSuccess( |
652 const std::string& device_id, | 756 const std::string& device_id, |
653 base::TimeTicks start_time, | 757 base::TimeTicks start_time, |
654 const RemoteServerConnectCallback& callback, | 758 const RemoteServerConnectCallback& callback, |
655 std::unique_ptr<device::BluetoothGattConnection> connection) { | 759 std::unique_ptr<device::BluetoothGattConnection> connection) { |
656 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 760 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
657 RecordConnectGATTTimeSuccess(base::TimeTicks::Now() - start_time); | 761 RecordConnectGATTTimeSuccess(base::TimeTicks::Now() - start_time); |
658 RecordConnectGATTOutcome(UMAConnectGATTOutcome::SUCCESS); | 762 RecordConnectGATTOutcome(UMAConnectGATTOutcome::SUCCESS); |
659 | 763 |
660 connected_devices_->Insert(device_id, std::move(connection)); | 764 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)); | 830 error_code, UMAGATTOperation::START_NOTIFICATIONS)); |
727 } | 831 } |
728 | 832 |
729 void WebBluetoothServiceImpl::OnStopNotifySessionComplete( | 833 void WebBluetoothServiceImpl::OnStopNotifySessionComplete( |
730 const std::string& characteristic_instance_id, | 834 const std::string& characteristic_instance_id, |
731 const RemoteCharacteristicStopNotificationsCallback& callback) { | 835 const RemoteCharacteristicStopNotificationsCallback& callback) { |
732 characteristic_id_to_notify_session_.erase(characteristic_instance_id); | 836 characteristic_id_to_notify_session_.erase(characteristic_instance_id); |
733 callback.Run(); | 837 callback.Run(); |
734 } | 838 } |
735 | 839 |
| 840 CacheQueryResult WebBluetoothServiceImpl::QueryCacheForDevice( |
| 841 const std::string& device_id) { |
| 842 const std::string& device_address = |
| 843 allowed_devices_map_.GetDeviceAddress(GetOrigin(), device_id); |
| 844 if (device_address.empty()) { |
| 845 CrashRendererAndClosePipe(bad_message::BDH_DEVICE_NOT_ALLOWED_FOR_ORIGIN); |
| 846 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); |
| 847 } |
| 848 |
| 849 CacheQueryResult result; |
| 850 result.device = GetAdapter()->GetDevice(device_address); |
| 851 |
| 852 // When a device can't be found in the BluetoothAdapter, that generally |
| 853 // indicates that it's gone out of range. We reject with a NetworkError in |
| 854 // that case. |
| 855 if (result.device == nullptr) { |
| 856 result.outcome = CacheQueryOutcome::NO_DEVICE; |
| 857 } |
| 858 return result; |
| 859 } |
| 860 |
736 CacheQueryResult WebBluetoothServiceImpl::QueryCacheForService( | 861 CacheQueryResult WebBluetoothServiceImpl::QueryCacheForService( |
737 const std::string& service_instance_id) { | 862 const std::string& service_instance_id) { |
738 auto device_iter = service_id_to_device_address_.find(service_instance_id); | 863 auto device_iter = service_id_to_device_address_.find(service_instance_id); |
739 | 864 |
740 // Kill the render, see "ID Not in Map Note" above. | 865 // Kill the render, see "ID Not in Map Note" above. |
741 if (device_iter == service_id_to_device_address_.end()) { | 866 if (device_iter == service_id_to_device_address_.end()) { |
742 CrashRendererAndClosePipe(bad_message::BDH_INVALID_SERVICE_ID); | 867 CrashRendererAndClosePipe(bad_message::BDH_INVALID_SERVICE_ID); |
743 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); | 868 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); |
744 } | 869 } |
745 | 870 |
746 const std::string& device_id = | 871 const std::string& device_id = |
747 GetBluetoothDispatcherHost()->allowed_devices_map_.GetDeviceId( | 872 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. | 873 // Kill the renderer if origin is not allowed to access the device. |
750 if (device_id.empty()) { | 874 if (device_id.empty()) { |
751 CrashRendererAndClosePipe(bad_message::BDH_DEVICE_NOT_ALLOWED_FOR_ORIGIN); | 875 CrashRendererAndClosePipe(bad_message::BDH_DEVICE_NOT_ALLOWED_FOR_ORIGIN); |
752 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); | 876 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); |
753 } | 877 } |
754 | 878 |
755 CacheQueryResult result = | 879 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) { | 880 if (result.outcome != CacheQueryOutcome::SUCCESS) { |
765 return result; | 881 return result; |
766 } | 882 } |
767 | 883 |
768 result.service = result.device->GetGattService(service_instance_id); | 884 result.service = result.device->GetGattService(service_instance_id); |
769 if (result.service == nullptr) { | 885 if (result.service == nullptr) { |
770 result.outcome = CacheQueryOutcome::NO_SERVICE; | 886 result.outcome = CacheQueryOutcome::NO_SERVICE; |
771 } else if (!GetBluetoothDispatcherHost() | 887 } else if (!allowed_devices_map_.IsOriginAllowedToAccessService( |
772 ->allowed_devices_map_.IsOriginAllowedToAccessService( | 888 GetOrigin(), device_id, |
773 GetOrigin(), device_id, | 889 result.service->GetUUID().canonical_value())) { |
774 result.service->GetUUID().canonical_value())) { | |
775 CrashRendererAndClosePipe(bad_message::BDH_SERVICE_NOT_ALLOWED_FOR_ORIGIN); | 890 CrashRendererAndClosePipe(bad_message::BDH_SERVICE_NOT_ALLOWED_FOR_ORIGIN); |
776 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); | 891 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); |
777 } | 892 } |
778 return result; | 893 return result; |
779 } | 894 } |
780 | 895 |
781 CacheQueryResult WebBluetoothServiceImpl::QueryCacheForCharacteristic( | 896 CacheQueryResult WebBluetoothServiceImpl::QueryCacheForCharacteristic( |
782 const std::string& characteristic_instance_id) { | 897 const std::string& characteristic_instance_id) { |
783 auto characteristic_iter = | 898 auto characteristic_iter = |
784 characteristic_id_to_service_id_.find(characteristic_instance_id); | 899 characteristic_id_to_service_id_.find(characteristic_instance_id); |
(...skipping 17 matching lines...) Expand all Loading... |
802 result.outcome = CacheQueryOutcome::NO_CHARACTERISTIC; | 917 result.outcome = CacheQueryOutcome::NO_CHARACTERISTIC; |
803 } | 918 } |
804 | 919 |
805 return result; | 920 return result; |
806 } | 921 } |
807 | 922 |
808 RenderProcessHost* WebBluetoothServiceImpl::GetRenderProcessHost() { | 923 RenderProcessHost* WebBluetoothServiceImpl::GetRenderProcessHost() { |
809 return render_frame_host_->GetProcess(); | 924 return render_frame_host_->GetProcess(); |
810 } | 925 } |
811 | 926 |
812 BluetoothDispatcherHost* WebBluetoothServiceImpl::GetBluetoothDispatcherHost() { | 927 BluetoothAdapterFactoryWrapper& |
| 928 WebBluetoothServiceImpl::GetBluetoothAdapterFactoryWrapper() { |
813 RenderProcessHostImpl* render_process_host_impl = | 929 RenderProcessHostImpl* render_process_host_impl = |
814 static_cast<RenderProcessHostImpl*>(GetRenderProcessHost()); | 930 static_cast<RenderProcessHostImpl*>(GetRenderProcessHost()); |
815 return render_process_host_impl->GetBluetoothDispatcherHost(); | 931 return render_process_host_impl->GetBluetoothAdapterFactoryWrapper(); |
| 932 } |
| 933 |
| 934 device::BluetoothAdapter* WebBluetoothServiceImpl::GetAdapter() { |
| 935 return GetBluetoothAdapterFactoryWrapper().GetAdapter(this); |
816 } | 936 } |
817 | 937 |
818 void WebBluetoothServiceImpl::CrashRendererAndClosePipe( | 938 void WebBluetoothServiceImpl::CrashRendererAndClosePipe( |
819 bad_message::BadMessageReason reason) { | 939 bad_message::BadMessageReason reason) { |
820 bad_message::ReceivedBadMessage(GetRenderProcessHost(), reason); | 940 bad_message::ReceivedBadMessage(GetRenderProcessHost(), reason); |
821 binding_.Close(); | 941 binding_.Close(); |
822 } | 942 } |
823 | 943 |
824 url::Origin WebBluetoothServiceImpl::GetOrigin() { | 944 url::Origin WebBluetoothServiceImpl::GetOrigin() { |
825 return render_frame_host_->GetLastCommittedOrigin(); | 945 return render_frame_host_->GetLastCommittedOrigin(); |
826 } | 946 } |
827 | 947 |
828 void WebBluetoothServiceImpl::ClearState() { | 948 void WebBluetoothServiceImpl::ClearState() { |
829 characteristic_id_to_notify_session_.clear(); | 949 characteristic_id_to_notify_session_.clear(); |
830 pending_primary_services_requests_.clear(); | 950 pending_primary_services_requests_.clear(); |
831 characteristic_id_to_service_id_.clear(); | 951 characteristic_id_to_service_id_.clear(); |
832 service_id_to_device_address_.clear(); | 952 service_id_to_device_address_.clear(); |
833 connected_devices_.reset( | 953 connected_devices_.reset( |
834 new FrameConnectedBluetoothDevices(render_frame_host_)); | 954 new FrameConnectedBluetoothDevices(render_frame_host_)); |
| 955 allowed_devices_map_ = BluetoothAllowedDevicesMap(); |
| 956 device_chooser_controller_.reset(); |
| 957 GetBluetoothAdapterFactoryWrapper().ReleaseAdapter(this); |
835 } | 958 } |
836 | 959 |
837 } // namespace content | 960 } // namespace content |
OLD | NEW |