OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 #include "content/browser/bluetooth/bluetooth_dispatcher_host.h" | 5 #include "content/browser/bluetooth/bluetooth_dispatcher_host.h" |
6 | 6 |
7 #include "base/strings/utf_string_conversions.h" | 7 #include "base/strings/utf_string_conversions.h" |
| 8 #include "content/browser/bad_message.h" |
8 #include "content/common/bluetooth/bluetooth_messages.h" | 9 #include "content/common/bluetooth/bluetooth_messages.h" |
9 #include "device/bluetooth/bluetooth_adapter.h" | 10 #include "device/bluetooth/bluetooth_adapter.h" |
10 #include "device/bluetooth/bluetooth_adapter_factory.h" | 11 #include "device/bluetooth/bluetooth_adapter_factory.h" |
11 #include "device/bluetooth/bluetooth_device.h" | 12 #include "device/bluetooth/bluetooth_device.h" |
12 #include "device/bluetooth/bluetooth_discovery_session.h" | 13 #include "device/bluetooth/bluetooth_discovery_session.h" |
| 14 #include "device/bluetooth/bluetooth_gatt_characteristic.h" |
13 #include "device/bluetooth/bluetooth_gatt_service.h" | 15 #include "device/bluetooth/bluetooth_gatt_service.h" |
14 | 16 |
15 using device::BluetoothAdapter; | 17 using device::BluetoothAdapter; |
16 using device::BluetoothAdapterFactory; | 18 using device::BluetoothAdapterFactory; |
| 19 using device::BluetoothGattCharacteristic; |
17 using device::BluetoothGattService; | 20 using device::BluetoothGattService; |
18 | 21 |
19 namespace content { | 22 namespace content { |
20 | 23 |
21 // TODO(ortuno): Once we have a chooser for scanning and the right | 24 // TODO(ortuno): Once we have a chooser for scanning and the right |
22 // callback for discovered services we should delete these constants. | 25 // callback for discovered services we should delete these constants. |
23 // https://crbug.com/436280 and https://crbug.com/484504 | 26 // https://crbug.com/436280 and https://crbug.com/484504 |
24 const int kDelayTime = 5; // 5 seconds for scanning and discovering | 27 const int kDelayTime = 5; // 5 seconds for scanning and discovering |
25 const int kTestingDelayTime = 0; // No need to wait during tests | 28 const int kTestingDelayTime = 0; // No need to wait during tests |
26 | 29 |
(...skipping 20 matching lines...) Expand all Loading... |
47 *thread = BrowserThread::UI; | 50 *thread = BrowserThread::UI; |
48 } | 51 } |
49 | 52 |
50 bool BluetoothDispatcherHost::OnMessageReceived(const IPC::Message& message) { | 53 bool BluetoothDispatcherHost::OnMessageReceived(const IPC::Message& message) { |
51 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 54 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
52 bool handled = true; | 55 bool handled = true; |
53 IPC_BEGIN_MESSAGE_MAP(BluetoothDispatcherHost, message) | 56 IPC_BEGIN_MESSAGE_MAP(BluetoothDispatcherHost, message) |
54 IPC_MESSAGE_HANDLER(BluetoothHostMsg_RequestDevice, OnRequestDevice) | 57 IPC_MESSAGE_HANDLER(BluetoothHostMsg_RequestDevice, OnRequestDevice) |
55 IPC_MESSAGE_HANDLER(BluetoothHostMsg_ConnectGATT, OnConnectGATT) | 58 IPC_MESSAGE_HANDLER(BluetoothHostMsg_ConnectGATT, OnConnectGATT) |
56 IPC_MESSAGE_HANDLER(BluetoothHostMsg_GetPrimaryService, OnGetPrimaryService) | 59 IPC_MESSAGE_HANDLER(BluetoothHostMsg_GetPrimaryService, OnGetPrimaryService) |
| 60 IPC_MESSAGE_HANDLER(BluetoothHostMsg_GetCharacteristic, OnGetCharacteristic) |
57 IPC_MESSAGE_UNHANDLED(handled = false) | 61 IPC_MESSAGE_UNHANDLED(handled = false) |
58 IPC_END_MESSAGE_MAP() | 62 IPC_END_MESSAGE_MAP() |
59 return handled; | 63 return handled; |
60 } | 64 } |
61 | 65 |
62 void BluetoothDispatcherHost::SetBluetoothAdapterForTesting( | 66 void BluetoothDispatcherHost::SetBluetoothAdapterForTesting( |
63 scoped_refptr<device::BluetoothAdapter> mock_adapter) { | 67 scoped_refptr<device::BluetoothAdapter> mock_adapter) { |
64 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 68 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
65 current_delay_time_ = kTestingDelayTime; | 69 current_delay_time_ = kTestingDelayTime; |
66 set_adapter(mock_adapter.Pass()); | 70 set_adapter(mock_adapter.Pass()); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 // For now just wait a fixed time and call OnServiceDiscovered. | 146 // For now just wait a fixed time and call OnServiceDiscovered. |
143 // TODO(ortuno): Use callback once it's implemented http://crbug.com/484504 | 147 // TODO(ortuno): Use callback once it's implemented http://crbug.com/484504 |
144 BrowserThread::PostDelayedTask( | 148 BrowserThread::PostDelayedTask( |
145 BrowserThread::UI, FROM_HERE, | 149 BrowserThread::UI, FROM_HERE, |
146 base::Bind(&BluetoothDispatcherHost::OnServicesDiscovered, | 150 base::Bind(&BluetoothDispatcherHost::OnServicesDiscovered, |
147 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id, | 151 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id, |
148 device_instance_id, service_uuid), | 152 device_instance_id, service_uuid), |
149 base::TimeDelta::FromSeconds(current_delay_time_)); | 153 base::TimeDelta::FromSeconds(current_delay_time_)); |
150 } | 154 } |
151 | 155 |
| 156 void BluetoothDispatcherHost::OnGetCharacteristic( |
| 157 int thread_id, |
| 158 int request_id, |
| 159 const std::string& service_instance_id, |
| 160 const std::string& characteristic_uuid) { |
| 161 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 162 |
| 163 auto device_iter = service_to_device_.find(service_instance_id); |
| 164 // A service_instance_id not in the map implies a hostile renderer |
| 165 // because a renderer obtains the service id from this class and |
| 166 // it will be added to the map at that time. |
| 167 if (device_iter == service_to_device_.end()) { |
| 168 // Kill the renderer |
| 169 bad_message::ReceivedBadMessage(this, bad_message::BDH_INVALID_SERVICE_ID); |
| 170 return; |
| 171 } |
| 172 |
| 173 // TODO(ortuno): Check if domain has access to device. |
| 174 // https://crbug.com/493459 |
| 175 device::BluetoothDevice* device = |
| 176 adapter_->GetDevice(device_iter->second /* device_instance_id */); |
| 177 |
| 178 if (device == NULL) { |
| 179 Send(new BluetoothMsg_GetCharacteristicError( |
| 180 thread_id, request_id, BluetoothError::NETWORK_ERROR)); |
| 181 return; |
| 182 } |
| 183 |
| 184 // TODO(ortuno): Check if domain has access to service |
| 185 // http://crbug.com/493460 |
| 186 device::BluetoothGattService* service = |
| 187 device->GetGattService(service_instance_id); |
| 188 if (!service) { |
| 189 Send(new BluetoothMsg_GetCharacteristicError( |
| 190 thread_id, request_id, BluetoothError::NETWORK_ERROR)); |
| 191 return; |
| 192 } |
| 193 |
| 194 for (BluetoothGattCharacteristic* characteristic : |
| 195 service->GetCharacteristics()) { |
| 196 if (characteristic->GetUUID().canonical_value() == characteristic_uuid) { |
| 197 // TODO(ortuno): Use generated instance ID instead. |
| 198 // https://crbug.com/495379 |
| 199 Send(new BluetoothMsg_GetCharacteristicSuccess( |
| 200 thread_id, request_id, characteristic->GetIdentifier())); |
| 201 return; |
| 202 } |
| 203 } |
| 204 Send(new BluetoothMsg_GetCharacteristicError(thread_id, request_id, |
| 205 BluetoothError::NOT_FOUND)); |
| 206 } |
| 207 |
152 void BluetoothDispatcherHost::OnDiscoverySessionStarted( | 208 void BluetoothDispatcherHost::OnDiscoverySessionStarted( |
153 int thread_id, | 209 int thread_id, |
154 int request_id, | 210 int request_id, |
155 scoped_ptr<device::BluetoothDiscoverySession> discovery_session) { | 211 scoped_ptr<device::BluetoothDiscoverySession> discovery_session) { |
156 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 212 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
157 BrowserThread::PostDelayedTask( | 213 BrowserThread::PostDelayedTask( |
158 BrowserThread::UI, FROM_HERE, | 214 BrowserThread::UI, FROM_HERE, |
159 base::Bind(&BluetoothDispatcherHost::StopDiscoverySession, | 215 base::Bind(&BluetoothDispatcherHost::StopDiscoverySession, |
160 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id, | 216 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id, |
161 base::Passed(&discovery_session)), | 217 base::Passed(&discovery_session)), |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 302 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
247 | 303 |
248 device::BluetoothDevice* device = adapter_->GetDevice(device_instance_id); | 304 device::BluetoothDevice* device = adapter_->GetDevice(device_instance_id); |
249 if (device == NULL) { | 305 if (device == NULL) { |
250 Send(new BluetoothMsg_GetPrimaryServiceError( | 306 Send(new BluetoothMsg_GetPrimaryServiceError( |
251 thread_id, request_id, BluetoothError::NETWORK_ERROR)); | 307 thread_id, request_id, BluetoothError::NETWORK_ERROR)); |
252 return; | 308 return; |
253 } | 309 } |
254 for (BluetoothGattService* service : device->GetGattServices()) { | 310 for (BluetoothGattService* service : device->GetGattServices()) { |
255 if (service->GetUUID().canonical_value() == service_uuid) { | 311 if (service->GetUUID().canonical_value() == service_uuid) { |
| 312 // TODO(ortuno): Use generated instance ID instead. |
| 313 // https://crbug.com/495379 |
| 314 const std::string& service_identifier = service->GetIdentifier(); |
| 315 auto insert_result = service_to_device_.insert( |
| 316 make_pair(service_identifier, device_instance_id)); |
| 317 |
| 318 // If the service existed already check that device_instance_id is the |
| 319 // same. |
| 320 if (!insert_result.second) |
| 321 DCHECK(insert_result.first->second == device_instance_id); |
| 322 |
256 Send(new BluetoothMsg_GetPrimaryServiceSuccess(thread_id, request_id, | 323 Send(new BluetoothMsg_GetPrimaryServiceSuccess(thread_id, request_id, |
257 service->GetIdentifier())); | 324 service_identifier)); |
258 return; | 325 return; |
259 } | 326 } |
260 } | 327 } |
261 Send(new BluetoothMsg_GetPrimaryServiceError(thread_id, request_id, | 328 Send(new BluetoothMsg_GetPrimaryServiceError(thread_id, request_id, |
262 BluetoothError::NOT_FOUND)); | 329 BluetoothError::NOT_FOUND)); |
263 } | 330 } |
264 | 331 |
265 } // namespace content | 332 } // namespace content |
OLD | NEW |