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

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

Issue 2658473002: Refactor BluetoothAllowedDevicesMap (Closed)
Patch Set: updated test code Created 3 years, 10 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: A service, characteristic, or descriptor ID not in the 5 // ID Not In Map Note: A service, characteristic, or descriptor ID not in the
6 // corresponding WebBluetoothServiceImpl map [service_id_to_device_address_, 6 // corresponding WebBluetoothServiceImpl map [service_id_to_device_address_,
7 // characteristic_id_to_service_id_, descriptor_id_to_characteristic_id_] 7 // characteristic_id_to_service_id_, descriptor_id_to_characteristic_id_]
8 // implies a hostile renderer because a renderer obtains the corresponding ID 8 // implies a hostile renderer because a renderer obtains the corresponding ID
9 // from this class and it will be added to the map at that time. 9 // from this class and it will be added to the map at that time.
10 10
11 #include "content/browser/bluetooth/web_bluetooth_service_impl.h" 11 #include "content/browser/bluetooth/web_bluetooth_service_impl.h"
12 12
13 #include <algorithm> 13 #include <algorithm>
14 14
15 #include "base/strings/utf_string_conversions.h" 15 #include "base/strings/utf_string_conversions.h"
16 #include "base/threading/thread_task_runner_handle.h" 16 #include "base/threading/thread_task_runner_handle.h"
17 #include "content/browser/bluetooth/bluetooth_blocklist.h" 17 #include "content/browser/bluetooth/bluetooth_blocklist.h"
18 #include "content/browser/bluetooth/bluetooth_device_chooser_controller.h" 18 #include "content/browser/bluetooth/bluetooth_device_chooser_controller.h"
19 #include "content/browser/bluetooth/bluetooth_metrics.h" 19 #include "content/browser/bluetooth/bluetooth_metrics.h"
20 #include "content/browser/bluetooth/frame_connected_bluetooth_devices.h" 20 #include "content/browser/bluetooth/frame_connected_bluetooth_devices.h"
21 #include "content/browser/renderer_host/render_process_host_impl.h" 21 #include "content/browser/renderer_host/render_process_host_impl.h"
22 #include "content/common/bluetooth/web_bluetooth_device_id.h" 22 #include "content/common/bluetooth/web_bluetooth_device_id.h"
23 #include "content/public/browser/bluetooth_allowed_devices_map_base.h"
23 #include "content/public/browser/browser_thread.h" 24 #include "content/public/browser/browser_thread.h"
24 #include "content/public/browser/navigation_handle.h" 25 #include "content/public/browser/navigation_handle.h"
25 #include "content/public/browser/render_frame_host.h" 26 #include "content/public/browser/render_frame_host.h"
26 #include "content/public/browser/web_contents.h" 27 #include "content/public/browser/web_contents.h"
28 #include "content/public/browser/web_contents_delegate.h"
27 #include "device/bluetooth/bluetooth_adapter_factory_wrapper.h" 29 #include "device/bluetooth/bluetooth_adapter_factory_wrapper.h"
28 #include "device/bluetooth/bluetooth_remote_gatt_characteristic.h" 30 #include "device/bluetooth/bluetooth_remote_gatt_characteristic.h"
29 #include "device/bluetooth/bluetooth_remote_gatt_descriptor.h" 31 #include "device/bluetooth/bluetooth_remote_gatt_descriptor.h"
30 32
31 using device::BluetoothAdapterFactoryWrapper; 33 using device::BluetoothAdapterFactoryWrapper;
32 using device::BluetoothUUID; 34 using device::BluetoothUUID;
33 35
34 namespace content { 36 namespace content {
35 37
36 namespace { 38 namespace {
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 ClearState(); 185 ClearState();
184 } 186 }
185 187
186 void WebBluetoothServiceImpl::SetClientConnectionErrorHandler( 188 void WebBluetoothServiceImpl::SetClientConnectionErrorHandler(
187 base::Closure closure) { 189 base::Closure closure) {
188 binding_.set_connection_error_handler(closure); 190 binding_.set_connection_error_handler(closure);
189 } 191 }
190 192
191 bool WebBluetoothServiceImpl::IsDevicePaired( 193 bool WebBluetoothServiceImpl::IsDevicePaired(
192 const std::string& device_address) { 194 const std::string& device_address) {
193 return allowed_devices_map_.GetDeviceId(GetOrigin(), device_address) != 195 return allowed_devices()->GetDeviceId(device_address) != nullptr;
194 nullptr;
195 } 196 }
196 197
197 void WebBluetoothServiceImpl::DidFinishNavigation( 198 void WebBluetoothServiceImpl::DidFinishNavigation(
198 NavigationHandle* navigation_handle) { 199 NavigationHandle* navigation_handle) {
199 if (navigation_handle->HasCommitted() && 200 if (navigation_handle->HasCommitted() &&
200 navigation_handle->GetRenderFrameHost() == render_frame_host_ && 201 navigation_handle->GetRenderFrameHost() == render_frame_host_ &&
201 !navigation_handle->IsSamePage()) { 202 !navigation_handle->IsSamePage()) {
202 ClearState(); 203 ClearState();
203 } 204 }
204 } 205 }
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 blink::mojom::WebBluetoothGATTQueryQuantity quantity, 383 blink::mojom::WebBluetoothGATTQueryQuantity quantity,
383 const base::Optional<BluetoothUUID>& services_uuid, 384 const base::Optional<BluetoothUUID>& services_uuid,
384 const RemoteServerGetPrimaryServicesCallback& callback) { 385 const RemoteServerGetPrimaryServicesCallback& callback) {
385 DCHECK_CURRENTLY_ON(BrowserThread::UI); 386 DCHECK_CURRENTLY_ON(BrowserThread::UI);
386 RecordWebBluetoothFunctionCall( 387 RecordWebBluetoothFunctionCall(
387 quantity == blink::mojom::WebBluetoothGATTQueryQuantity::SINGLE 388 quantity == blink::mojom::WebBluetoothGATTQueryQuantity::SINGLE
388 ? UMAWebBluetoothFunction::GET_PRIMARY_SERVICE 389 ? UMAWebBluetoothFunction::GET_PRIMARY_SERVICE
389 : UMAWebBluetoothFunction::GET_PRIMARY_SERVICES); 390 : UMAWebBluetoothFunction::GET_PRIMARY_SERVICES);
390 RecordGetPrimaryServicesServices(quantity, services_uuid); 391 RecordGetPrimaryServicesServices(quantity, services_uuid);
391 392
392 if (!allowed_devices_map_.IsOriginAllowedToAccessAtLeastOneService( 393 if (!allowed_devices()->IsAllowedToAccessAtLeastOneService(device_id)) {
393 GetOrigin(), device_id)) {
394 callback.Run( 394 callback.Run(
395 blink::mojom::WebBluetoothResult::NOT_ALLOWED_TO_ACCESS_ANY_SERVICE, 395 blink::mojom::WebBluetoothResult::NOT_ALLOWED_TO_ACCESS_ANY_SERVICE,
396 base::nullopt /* service */); 396 base::nullopt /* service */);
397 return; 397 return;
398 } 398 }
399 399
400 if (services_uuid && 400 if (services_uuid &&
401 !allowed_devices_map_.IsOriginAllowedToAccessService( 401 !allowed_devices()->IsAllowedToAccessService(device_id,
402 GetOrigin(), device_id, services_uuid.value())) { 402 services_uuid.value())) {
403 callback.Run( 403 callback.Run(
404 blink::mojom::WebBluetoothResult::NOT_ALLOWED_TO_ACCESS_SERVICE, 404 blink::mojom::WebBluetoothResult::NOT_ALLOWED_TO_ACCESS_SERVICE,
405 base::nullopt /* service */); 405 base::nullopt /* service */);
406 return; 406 return;
407 } 407 }
408 408
409 const CacheQueryResult query_result = QueryCacheForDevice(device_id); 409 const CacheQueryResult query_result = QueryCacheForDevice(device_id);
410 410
411 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { 411 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) {
412 return; 412 return;
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after
805 device::BluetoothDevice* device) { 805 device::BluetoothDevice* device) {
806 DCHECK_CURRENTLY_ON(BrowserThread::UI); 806 DCHECK_CURRENTLY_ON(BrowserThread::UI);
807 DCHECK(device->IsGattServicesDiscoveryComplete()); 807 DCHECK(device->IsGattServicesDiscoveryComplete());
808 808
809 std::vector<device::BluetoothRemoteGattService*> services = 809 std::vector<device::BluetoothRemoteGattService*> services =
810 services_uuid ? device->GetPrimaryServicesByUUID(services_uuid.value()) 810 services_uuid ? device->GetPrimaryServicesByUUID(services_uuid.value())
811 : device->GetPrimaryServices(); 811 : device->GetPrimaryServices();
812 812
813 std::vector<blink::mojom::WebBluetoothRemoteGATTServicePtr> response_services; 813 std::vector<blink::mojom::WebBluetoothRemoteGATTServicePtr> response_services;
814 for (device::BluetoothRemoteGattService* service : services) { 814 for (device::BluetoothRemoteGattService* service : services) {
815 if (!allowed_devices_map_.IsOriginAllowedToAccessService( 815 if (!allowed_devices()->IsAllowedToAccessService(device_id,
816 GetOrigin(), device_id, service->GetUUID())) { 816 service->GetUUID())) {
817 continue; 817 continue;
818 } 818 }
819 std::string service_instance_id = service->GetIdentifier(); 819 std::string service_instance_id = service->GetIdentifier();
820 const std::string& device_address = device->GetAddress(); 820 const std::string& device_address = device->GetAddress();
821 auto insert_result = service_id_to_device_address_.insert( 821 auto insert_result = service_id_to_device_address_.insert(
822 make_pair(service_instance_id, device_address)); 822 make_pair(service_instance_id, device_address));
823 // If value is already in map, DCHECK it's valid. 823 // If value is already in map, DCHECK it's valid.
824 if (!insert_result.second) 824 if (!insert_result.second)
825 DCHECK_EQ(insert_result.first->second, device_address); 825 DCHECK_EQ(insert_result.first->second, device_address);
826 826
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
863 const device::BluetoothDevice* const device = 863 const device::BluetoothDevice* const device =
864 GetAdapter()->GetDevice(device_address); 864 GetAdapter()->GetDevice(device_address);
865 if (device == nullptr) { 865 if (device == nullptr) {
866 DVLOG(1) << "Device " << device_address << " no longer in adapter"; 866 DVLOG(1) << "Device " << device_address << " no longer in adapter";
867 RecordRequestDeviceOutcome(UMARequestDeviceOutcome::CHOSEN_DEVICE_VANISHED); 867 RecordRequestDeviceOutcome(UMARequestDeviceOutcome::CHOSEN_DEVICE_VANISHED);
868 callback.Run(blink::mojom::WebBluetoothResult::CHOSEN_DEVICE_VANISHED, 868 callback.Run(blink::mojom::WebBluetoothResult::CHOSEN_DEVICE_VANISHED,
869 nullptr /* device */); 869 nullptr /* device */);
870 return; 870 return;
871 } 871 }
872 872
873 const WebBluetoothDeviceId device_id_for_origin = 873 const WebBluetoothDeviceId device_id =
874 allowed_devices_map_.AddDevice(GetOrigin(), device_address, options); 874 allowed_devices()->AddDevice(device_address, options);
875 875
876 DVLOG(1) << "Device: " << device->GetNameForDisplay(); 876 DVLOG(1) << "Device: " << device->GetNameForDisplay();
877 877
878 blink::mojom::WebBluetoothDevicePtr device_ptr = 878 blink::mojom::WebBluetoothDevicePtr device_ptr =
879 blink::mojom::WebBluetoothDevice::New(); 879 blink::mojom::WebBluetoothDevice::New();
880 device_ptr->id = device_id_for_origin; 880 device_ptr->id = device_id;
881 device_ptr->name = device->GetName(); 881 device_ptr->name = device->GetName();
882 882
883 RecordRequestDeviceOutcome(UMARequestDeviceOutcome::SUCCESS); 883 RecordRequestDeviceOutcome(UMARequestDeviceOutcome::SUCCESS);
884 callback.Run(blink::mojom::WebBluetoothResult::SUCCESS, 884 callback.Run(blink::mojom::WebBluetoothResult::SUCCESS,
885 std::move(device_ptr)); 885 std::move(device_ptr));
886 } 886 }
887 887
888 void WebBluetoothServiceImpl::OnGetDeviceFailed( 888 void WebBluetoothServiceImpl::OnGetDeviceFailed(
889 const RequestDeviceCallback& callback, 889 const RequestDeviceCallback& callback,
890 blink::mojom::WebBluetoothResult result) { 890 blink::mojom::WebBluetoothResult result) {
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
989 device::BluetoothRemoteGattService::GattErrorCode error_code) { 989 device::BluetoothRemoteGattService::GattErrorCode error_code) {
990 DCHECK_CURRENTLY_ON(BrowserThread::UI); 990 DCHECK_CURRENTLY_ON(BrowserThread::UI);
991 callback.Run(TranslateGATTErrorAndRecord(error_code, 991 callback.Run(TranslateGATTErrorAndRecord(error_code,
992 UMAGATTOperation::DESCRIPTOR_READ), 992 UMAGATTOperation::DESCRIPTOR_READ),
993 base::nullopt /* value */); 993 base::nullopt /* value */);
994 } 994 }
995 995
996 CacheQueryResult WebBluetoothServiceImpl::QueryCacheForDevice( 996 CacheQueryResult WebBluetoothServiceImpl::QueryCacheForDevice(
997 const WebBluetoothDeviceId& device_id) { 997 const WebBluetoothDeviceId& device_id) {
998 const std::string& device_address = 998 const std::string& device_address =
999 allowed_devices_map_.GetDeviceAddress(GetOrigin(), device_id); 999 allowed_devices()->GetDeviceAddress(device_id);
1000 if (device_address.empty()) { 1000 if (device_address.empty()) {
1001 CrashRendererAndClosePipe(bad_message::BDH_DEVICE_NOT_ALLOWED_FOR_ORIGIN); 1001 CrashRendererAndClosePipe(bad_message::BDH_DEVICE_NOT_ALLOWED_FOR_ORIGIN);
1002 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); 1002 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER);
1003 } 1003 }
1004 1004
1005 CacheQueryResult result; 1005 CacheQueryResult result;
1006 result.device = GetAdapter()->GetDevice(device_address); 1006 result.device = GetAdapter()->GetDevice(device_address);
1007 1007
1008 // When a device can't be found in the BluetoothAdapter, that generally 1008 // When a device can't be found in the BluetoothAdapter, that generally
1009 // indicates that it's gone out of range. We reject with a NetworkError in 1009 // indicates that it's gone out of range. We reject with a NetworkError in
1010 // that case. 1010 // that case.
1011 if (result.device == nullptr) { 1011 if (result.device == nullptr) {
1012 result.outcome = CacheQueryOutcome::NO_DEVICE; 1012 result.outcome = CacheQueryOutcome::NO_DEVICE;
1013 } 1013 }
1014 return result; 1014 return result;
1015 } 1015 }
1016 1016
1017 CacheQueryResult WebBluetoothServiceImpl::QueryCacheForService( 1017 CacheQueryResult WebBluetoothServiceImpl::QueryCacheForService(
1018 const std::string& service_instance_id) { 1018 const std::string& service_instance_id) {
1019 auto device_iter = service_id_to_device_address_.find(service_instance_id); 1019 auto device_iter = service_id_to_device_address_.find(service_instance_id);
1020 1020
1021 // Kill the render, see "ID Not in Map Note" above. 1021 // Kill the render, see "ID Not in Map Note" above.
1022 if (device_iter == service_id_to_device_address_.end()) { 1022 if (device_iter == service_id_to_device_address_.end()) {
1023 CrashRendererAndClosePipe(bad_message::BDH_INVALID_SERVICE_ID); 1023 CrashRendererAndClosePipe(bad_message::BDH_INVALID_SERVICE_ID);
1024 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); 1024 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER);
1025 } 1025 }
1026 1026
1027 const WebBluetoothDeviceId* device_id = 1027 const WebBluetoothDeviceId* device_id =
1028 allowed_devices_map_.GetDeviceId(GetOrigin(), device_iter->second); 1028 allowed_devices()->GetDeviceId(device_iter->second);
1029 // Kill the renderer if origin is not allowed to access the device. 1029 // Kill the renderer if origin is not allowed to access the device.
1030 if (device_id == nullptr) { 1030 if (device_id == nullptr) {
1031 CrashRendererAndClosePipe(bad_message::BDH_DEVICE_NOT_ALLOWED_FOR_ORIGIN); 1031 CrashRendererAndClosePipe(bad_message::BDH_DEVICE_NOT_ALLOWED_FOR_ORIGIN);
1032 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); 1032 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER);
1033 } 1033 }
1034 1034
1035 CacheQueryResult result = QueryCacheForDevice(*device_id); 1035 CacheQueryResult result = QueryCacheForDevice(*device_id);
1036 if (result.outcome != CacheQueryOutcome::SUCCESS) { 1036 if (result.outcome != CacheQueryOutcome::SUCCESS) {
1037 return result; 1037 return result;
1038 } 1038 }
1039 1039
1040 result.service = result.device->GetGattService(service_instance_id); 1040 result.service = result.device->GetGattService(service_instance_id);
1041 if (result.service == nullptr) { 1041 if (result.service == nullptr) {
1042 result.outcome = CacheQueryOutcome::NO_SERVICE; 1042 result.outcome = CacheQueryOutcome::NO_SERVICE;
1043 } else if (!allowed_devices_map_.IsOriginAllowedToAccessService( 1043 } else if (!allowed_devices()->IsAllowedToAccessService(
1044 GetOrigin(), *device_id, result.service->GetUUID())) { 1044 *device_id, result.service->GetUUID())) {
1045 CrashRendererAndClosePipe(bad_message::BDH_SERVICE_NOT_ALLOWED_FOR_ORIGIN); 1045 CrashRendererAndClosePipe(bad_message::BDH_SERVICE_NOT_ALLOWED_FOR_ORIGIN);
1046 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); 1046 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER);
1047 } 1047 }
1048 return result; 1048 return result;
1049 } 1049 }
1050 1050
1051 CacheQueryResult WebBluetoothServiceImpl::QueryCacheForCharacteristic( 1051 CacheQueryResult WebBluetoothServiceImpl::QueryCacheForCharacteristic(
1052 const std::string& characteristic_instance_id) { 1052 const std::string& characteristic_instance_id) {
1053 auto characteristic_iter = 1053 auto characteristic_iter =
1054 characteristic_id_to_service_id_.find(characteristic_instance_id); 1054 characteristic_id_to_service_id_.find(characteristic_instance_id);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1114 void WebBluetoothServiceImpl::CrashRendererAndClosePipe( 1114 void WebBluetoothServiceImpl::CrashRendererAndClosePipe(
1115 bad_message::BadMessageReason reason) { 1115 bad_message::BadMessageReason reason) {
1116 bad_message::ReceivedBadMessage(GetRenderProcessHost(), reason); 1116 bad_message::ReceivedBadMessage(GetRenderProcessHost(), reason);
1117 binding_.Close(); 1117 binding_.Close();
1118 } 1118 }
1119 1119
1120 url::Origin WebBluetoothServiceImpl::GetOrigin() { 1120 url::Origin WebBluetoothServiceImpl::GetOrigin() {
1121 return render_frame_host_->GetLastCommittedOrigin(); 1121 return render_frame_host_->GetLastCommittedOrigin();
1122 } 1122 }
1123 1123
1124 BluetoothAllowedDevices* WebBluetoothServiceImpl::allowed_devices() {
1125 if (!allowed_devices_) {
1126 WebContentsDelegate* delegate = web_contents()->GetDelegate();
1127 BluetoothAllowedDevicesMapBase* allowed_devices_map =
1128 delegate->GetBluetoothDevicesMap(render_frame_host_);
1129 allowed_devices_ =
1130 allowed_devices_map->GetOrCreateAllowedDevices(GetOrigin());
dcheng 2017/02/01 07:54:09 Is this expected to be immutable per-origin?
juncai 2017/02/02 01:44:33 The BluetoothAllowedDevices object that an origin
1131 DCHECK(allowed_devices_);
1132 }
1133 return allowed_devices_;
1134 }
1135
1124 void WebBluetoothServiceImpl::ClearState() { 1136 void WebBluetoothServiceImpl::ClearState() {
1125 characteristic_id_to_notify_session_.clear(); 1137 characteristic_id_to_notify_session_.clear();
1126 pending_primary_services_requests_.clear(); 1138 pending_primary_services_requests_.clear();
1127 descriptor_id_to_characteristic_id_.clear(); 1139 descriptor_id_to_characteristic_id_.clear();
1128 characteristic_id_to_service_id_.clear(); 1140 characteristic_id_to_service_id_.clear();
1129 service_id_to_device_address_.clear(); 1141 service_id_to_device_address_.clear();
1130 connected_devices_.reset( 1142 connected_devices_.reset(
1131 new FrameConnectedBluetoothDevices(render_frame_host_)); 1143 new FrameConnectedBluetoothDevices(render_frame_host_));
1132 allowed_devices_map_ = BluetoothAllowedDevicesMap();
1133 device_chooser_controller_.reset(); 1144 device_chooser_controller_.reset();
1134 BluetoothAdapterFactoryWrapper::Get().ReleaseAdapter(this); 1145 BluetoothAdapterFactoryWrapper::Get().ReleaseAdapter(this);
1135 } 1146 }
1136 1147
1137 } // namespace content 1148 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698