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

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

Issue 2658473002: Refactor BluetoothAllowedDevicesMap (Closed)
Patch Set: clean up 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/browser/storage_partition_impl.h"
22 #include "content/common/bluetooth/web_bluetooth_device_id.h" 23 #include "content/common/bluetooth/web_bluetooth_device_id.h"
24 #include "content/public/browser/browser_context.h"
23 #include "content/public/browser/browser_thread.h" 25 #include "content/public/browser/browser_thread.h"
24 #include "content/public/browser/navigation_handle.h" 26 #include "content/public/browser/navigation_handle.h"
25 #include "content/public/browser/render_frame_host.h" 27 #include "content/public/browser/render_frame_host.h"
26 #include "content/public/browser/web_contents.h" 28 #include "content/public/browser/web_contents.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;
(...skipping 150 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 435 matching lines...) Expand 10 before | Expand all | Expand 10 after
848 device::BluetoothDevice* device) { 848 device::BluetoothDevice* device) {
849 DCHECK_CURRENTLY_ON(BrowserThread::UI); 849 DCHECK_CURRENTLY_ON(BrowserThread::UI);
850 DCHECK(device->IsGattServicesDiscoveryComplete()); 850 DCHECK(device->IsGattServicesDiscoveryComplete());
851 851
852 std::vector<device::BluetoothRemoteGattService*> services = 852 std::vector<device::BluetoothRemoteGattService*> services =
853 services_uuid ? device->GetPrimaryServicesByUUID(services_uuid.value()) 853 services_uuid ? device->GetPrimaryServicesByUUID(services_uuid.value())
854 : device->GetPrimaryServices(); 854 : device->GetPrimaryServices();
855 855
856 std::vector<blink::mojom::WebBluetoothRemoteGATTServicePtr> response_services; 856 std::vector<blink::mojom::WebBluetoothRemoteGATTServicePtr> response_services;
857 for (device::BluetoothRemoteGattService* service : services) { 857 for (device::BluetoothRemoteGattService* service : services) {
858 if (!allowed_devices_map_.IsOriginAllowedToAccessService( 858 if (!allowed_devices()->IsAllowedToAccessService(device_id,
859 GetOrigin(), device_id, service->GetUUID())) { 859 service->GetUUID())) {
860 continue; 860 continue;
861 } 861 }
862 std::string service_instance_id = service->GetIdentifier(); 862 std::string service_instance_id = service->GetIdentifier();
863 const std::string& device_address = device->GetAddress(); 863 const std::string& device_address = device->GetAddress();
864 auto insert_result = service_id_to_device_address_.insert( 864 auto insert_result = service_id_to_device_address_.insert(
865 make_pair(service_instance_id, device_address)); 865 make_pair(service_instance_id, device_address));
866 // If value is already in map, DCHECK it's valid. 866 // If value is already in map, DCHECK it's valid.
867 if (!insert_result.second) 867 if (!insert_result.second)
868 DCHECK_EQ(insert_result.first->second, device_address); 868 DCHECK_EQ(insert_result.first->second, device_address);
869 869
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
906 const device::BluetoothDevice* const device = 906 const device::BluetoothDevice* const device =
907 GetAdapter()->GetDevice(device_address); 907 GetAdapter()->GetDevice(device_address);
908 if (device == nullptr) { 908 if (device == nullptr) {
909 DVLOG(1) << "Device " << device_address << " no longer in adapter"; 909 DVLOG(1) << "Device " << device_address << " no longer in adapter";
910 RecordRequestDeviceOutcome(UMARequestDeviceOutcome::CHOSEN_DEVICE_VANISHED); 910 RecordRequestDeviceOutcome(UMARequestDeviceOutcome::CHOSEN_DEVICE_VANISHED);
911 callback.Run(blink::mojom::WebBluetoothResult::CHOSEN_DEVICE_VANISHED, 911 callback.Run(blink::mojom::WebBluetoothResult::CHOSEN_DEVICE_VANISHED,
912 nullptr /* device */); 912 nullptr /* device */);
913 return; 913 return;
914 } 914 }
915 915
916 const WebBluetoothDeviceId device_id_for_origin = 916 const WebBluetoothDeviceId device_id =
917 allowed_devices_map_.AddDevice(GetOrigin(), device_address, options); 917 allowed_devices()->AddDevice(device_address, options);
918 918
919 DVLOG(1) << "Device: " << device->GetNameForDisplay(); 919 DVLOG(1) << "Device: " << device->GetNameForDisplay();
920 920
921 blink::mojom::WebBluetoothDevicePtr device_ptr = 921 blink::mojom::WebBluetoothDevicePtr device_ptr =
922 blink::mojom::WebBluetoothDevice::New(); 922 blink::mojom::WebBluetoothDevice::New();
923 device_ptr->id = device_id_for_origin; 923 device_ptr->id = device_id;
924 device_ptr->name = device->GetName(); 924 device_ptr->name = device->GetName();
925 925
926 RecordRequestDeviceOutcome(UMARequestDeviceOutcome::SUCCESS); 926 RecordRequestDeviceOutcome(UMARequestDeviceOutcome::SUCCESS);
927 callback.Run(blink::mojom::WebBluetoothResult::SUCCESS, 927 callback.Run(blink::mojom::WebBluetoothResult::SUCCESS,
928 std::move(device_ptr)); 928 std::move(device_ptr));
929 } 929 }
930 930
931 void WebBluetoothServiceImpl::OnGetDeviceFailed( 931 void WebBluetoothServiceImpl::OnGetDeviceFailed(
932 const RequestDeviceCallback& callback, 932 const RequestDeviceCallback& callback,
933 blink::mojom::WebBluetoothResult result) { 933 blink::mojom::WebBluetoothResult result) {
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
1048 device::BluetoothRemoteGattService::GattErrorCode error_code) { 1048 device::BluetoothRemoteGattService::GattErrorCode error_code) {
1049 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1049 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1050 RecordDescriptorWriteValueOutcome(UMAGATTOperationOutcome::SUCCESS); 1050 RecordDescriptorWriteValueOutcome(UMAGATTOperationOutcome::SUCCESS);
1051 callback.Run(TranslateGATTErrorAndRecord(error_code, 1051 callback.Run(TranslateGATTErrorAndRecord(error_code,
1052 UMAGATTOperation::DESCRIPTOR_WRITE)); 1052 UMAGATTOperation::DESCRIPTOR_WRITE));
1053 } 1053 }
1054 1054
1055 CacheQueryResult WebBluetoothServiceImpl::QueryCacheForDevice( 1055 CacheQueryResult WebBluetoothServiceImpl::QueryCacheForDevice(
1056 const WebBluetoothDeviceId& device_id) { 1056 const WebBluetoothDeviceId& device_id) {
1057 const std::string& device_address = 1057 const std::string& device_address =
1058 allowed_devices_map_.GetDeviceAddress(GetOrigin(), device_id); 1058 allowed_devices()->GetDeviceAddress(device_id);
1059 if (device_address.empty()) { 1059 if (device_address.empty()) {
1060 CrashRendererAndClosePipe(bad_message::BDH_DEVICE_NOT_ALLOWED_FOR_ORIGIN); 1060 CrashRendererAndClosePipe(bad_message::BDH_DEVICE_NOT_ALLOWED_FOR_ORIGIN);
1061 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); 1061 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER);
1062 } 1062 }
1063 1063
1064 CacheQueryResult result; 1064 CacheQueryResult result;
1065 result.device = GetAdapter()->GetDevice(device_address); 1065 result.device = GetAdapter()->GetDevice(device_address);
1066 1066
1067 // When a device can't be found in the BluetoothAdapter, that generally 1067 // When a device can't be found in the BluetoothAdapter, that generally
1068 // indicates that it's gone out of range. We reject with a NetworkError in 1068 // indicates that it's gone out of range. We reject with a NetworkError in
1069 // that case. 1069 // that case.
1070 if (result.device == nullptr) { 1070 if (result.device == nullptr) {
1071 result.outcome = CacheQueryOutcome::NO_DEVICE; 1071 result.outcome = CacheQueryOutcome::NO_DEVICE;
1072 } 1072 }
1073 return result; 1073 return result;
1074 } 1074 }
1075 1075
1076 CacheQueryResult WebBluetoothServiceImpl::QueryCacheForService( 1076 CacheQueryResult WebBluetoothServiceImpl::QueryCacheForService(
1077 const std::string& service_instance_id) { 1077 const std::string& service_instance_id) {
1078 auto device_iter = service_id_to_device_address_.find(service_instance_id); 1078 auto device_iter = service_id_to_device_address_.find(service_instance_id);
1079 1079
1080 // Kill the render, see "ID Not in Map Note" above. 1080 // Kill the render, see "ID Not in Map Note" above.
1081 if (device_iter == service_id_to_device_address_.end()) { 1081 if (device_iter == service_id_to_device_address_.end()) {
1082 CrashRendererAndClosePipe(bad_message::BDH_INVALID_SERVICE_ID); 1082 CrashRendererAndClosePipe(bad_message::BDH_INVALID_SERVICE_ID);
1083 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); 1083 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER);
1084 } 1084 }
1085 1085
1086 const WebBluetoothDeviceId* device_id = 1086 const WebBluetoothDeviceId* device_id =
1087 allowed_devices_map_.GetDeviceId(GetOrigin(), device_iter->second); 1087 allowed_devices()->GetDeviceId(device_iter->second);
1088 // Kill the renderer if origin is not allowed to access the device. 1088 // Kill the renderer if origin is not allowed to access the device.
1089 if (device_id == nullptr) { 1089 if (device_id == nullptr) {
1090 CrashRendererAndClosePipe(bad_message::BDH_DEVICE_NOT_ALLOWED_FOR_ORIGIN); 1090 CrashRendererAndClosePipe(bad_message::BDH_DEVICE_NOT_ALLOWED_FOR_ORIGIN);
1091 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); 1091 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER);
1092 } 1092 }
1093 1093
1094 CacheQueryResult result = QueryCacheForDevice(*device_id); 1094 CacheQueryResult result = QueryCacheForDevice(*device_id);
1095 if (result.outcome != CacheQueryOutcome::SUCCESS) { 1095 if (result.outcome != CacheQueryOutcome::SUCCESS) {
1096 return result; 1096 return result;
1097 } 1097 }
1098 1098
1099 result.service = result.device->GetGattService(service_instance_id); 1099 result.service = result.device->GetGattService(service_instance_id);
1100 if (result.service == nullptr) { 1100 if (result.service == nullptr) {
1101 result.outcome = CacheQueryOutcome::NO_SERVICE; 1101 result.outcome = CacheQueryOutcome::NO_SERVICE;
1102 } else if (!allowed_devices_map_.IsOriginAllowedToAccessService( 1102 } else if (!allowed_devices()->IsAllowedToAccessService(
1103 GetOrigin(), *device_id, result.service->GetUUID())) { 1103 *device_id, result.service->GetUUID())) {
1104 CrashRendererAndClosePipe(bad_message::BDH_SERVICE_NOT_ALLOWED_FOR_ORIGIN); 1104 CrashRendererAndClosePipe(bad_message::BDH_SERVICE_NOT_ALLOWED_FOR_ORIGIN);
1105 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER); 1105 return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER);
1106 } 1106 }
1107 return result; 1107 return result;
1108 } 1108 }
1109 1109
1110 CacheQueryResult WebBluetoothServiceImpl::QueryCacheForCharacteristic( 1110 CacheQueryResult WebBluetoothServiceImpl::QueryCacheForCharacteristic(
1111 const std::string& characteristic_instance_id) { 1111 const std::string& characteristic_instance_id) {
1112 auto characteristic_iter = 1112 auto characteristic_iter =
1113 characteristic_id_to_service_id_.find(characteristic_instance_id); 1113 characteristic_id_to_service_id_.find(characteristic_instance_id);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1173 void WebBluetoothServiceImpl::CrashRendererAndClosePipe( 1173 void WebBluetoothServiceImpl::CrashRendererAndClosePipe(
1174 bad_message::BadMessageReason reason) { 1174 bad_message::BadMessageReason reason) {
1175 bad_message::ReceivedBadMessage(GetRenderProcessHost(), reason); 1175 bad_message::ReceivedBadMessage(GetRenderProcessHost(), reason);
1176 binding_.Close(); 1176 binding_.Close();
1177 } 1177 }
1178 1178
1179 url::Origin WebBluetoothServiceImpl::GetOrigin() { 1179 url::Origin WebBluetoothServiceImpl::GetOrigin() {
1180 return render_frame_host_->GetLastCommittedOrigin(); 1180 return render_frame_host_->GetLastCommittedOrigin();
1181 } 1181 }
1182 1182
1183 BluetoothAllowedDevices* WebBluetoothServiceImpl::allowed_devices() {
1184 if (!allowed_devices_) {
1185 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
scheib 2017/02/03 23:28:13 I suppose check with jam@, but whenever I see a st
juncai 2017/02/08 06:43:49 Hi, jam@, the three functions: https://cs.chromium
jam1 2017/02/10 05:24:39 the public interface is for getters that are expos
scheib 2017/02/10 06:33:59 That's a bit unfortunate, as it's not clear that t
juncai 2017/02/10 22:30:43 What about adding some comments about this in a se
scheib 2017/02/10 23:31:21 Separate patch is OK, need to float to jam@ for th
1186 BrowserContext::GetDefaultStoragePartition(
1187 web_contents()->GetBrowserContext()));
1188 scoped_refptr<BluetoothAllowedDevicesMap> allowed_devices_map =
1189 partition->GetBluetoothAllowedDevicesMap();
1190 allowed_devices_ =
1191 allowed_devices_map->GetOrCreateAllowedDevices(GetOrigin());
1192 DCHECK(allowed_devices_);
1193 }
1194 return allowed_devices_;
ortuno 2017/02/03 20:16:50 Can this be null? If so we need to DCHECK that it
juncai 2017/02/08 06:43:49 It can't be null. Changed it to return a reference
1195 }
1196
1183 void WebBluetoothServiceImpl::ClearState() { 1197 void WebBluetoothServiceImpl::ClearState() {
1184 characteristic_id_to_notify_session_.clear(); 1198 characteristic_id_to_notify_session_.clear();
1185 pending_primary_services_requests_.clear(); 1199 pending_primary_services_requests_.clear();
1186 descriptor_id_to_characteristic_id_.clear(); 1200 descriptor_id_to_characteristic_id_.clear();
1187 characteristic_id_to_service_id_.clear(); 1201 characteristic_id_to_service_id_.clear();
1188 service_id_to_device_address_.clear(); 1202 service_id_to_device_address_.clear();
1189 connected_devices_.reset( 1203 connected_devices_.reset(
1190 new FrameConnectedBluetoothDevices(render_frame_host_)); 1204 new FrameConnectedBluetoothDevices(render_frame_host_));
1191 allowed_devices_map_ = BluetoothAllowedDevicesMap();
1192 device_chooser_controller_.reset(); 1205 device_chooser_controller_.reset();
1193 BluetoothAdapterFactoryWrapper::Get().ReleaseAdapter(this); 1206 BluetoothAdapterFactoryWrapper::Get().ReleaseAdapter(this);
1194 } 1207 }
1195 1208
1196 } // namespace content 1209 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698