OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "content/browser/bluetooth/bluetooth_service_impl.h" | |
6 | |
7 #include "content/browser/bluetooth/bluetooth_blacklist.h" | |
8 #include "content/browser/bluetooth/bluetooth_dispatcher_host.h" | |
9 #include "content/browser/renderer_host/render_process_host_impl.h" | |
10 #include "content/public/browser/render_frame_host.h" | |
11 #include "device/bluetooth/bluetooth_adapter_factory.h" | |
12 #include "device/bluetooth/bluetooth_device.h" | |
13 #include "device/bluetooth/bluetooth_discovery_session.h" | |
14 #include "device/bluetooth/bluetooth_gatt_characteristic.h" | |
15 | |
16 using device::BluetoothGattService; | |
17 | |
18 namespace content { | |
19 | |
20 namespace { | |
21 | |
22 blink::mojom::WebBluetoothError GetWebError(CacheQueryOutcome outcome) { | |
23 switch (outcome) { | |
24 case CacheQueryOutcome::BAD_RENDERER: | |
25 NOTREACHED(); | |
26 return blink::mojom::WebBluetoothError::DEVICE_NO_LONGER_IN_RANGE; | |
27 case CacheQueryOutcome::SUCCESS: | |
28 return blink::mojom::WebBluetoothError::SUCCESS; | |
29 case CacheQueryOutcome::NO_DEVICE: | |
30 return blink::mojom::WebBluetoothError::DEVICE_NO_LONGER_IN_RANGE; | |
31 case CacheQueryOutcome::NO_SERVICE: | |
32 return blink::mojom::WebBluetoothError::SERVICE_NO_LONGER_EXISTS; | |
33 case CacheQueryOutcome::NO_CHARACTERISTIC: | |
34 return blink::mojom::WebBluetoothError::CHARACTERISTIC_NO_LONGER_EXISTS; | |
35 } | |
36 NOTREACHED(); | |
37 return blink::mojom::WebBluetoothError::DEVICE_NO_LONGER_IN_RANGE; | |
38 } | |
39 | |
40 blink::mojom::WebBluetoothError TranslateGATTErrorAndRecord( | |
41 BluetoothGattService::GattErrorCode error_code, | |
42 UMAGATTOperation operation) { | |
43 switch (error_code) { | |
44 case BluetoothGattService::GATT_ERROR_UNKNOWN: | |
45 RecordGATTOperationOutcome(operation, UMAGATTOperationOutcome::UNKNOWN); | |
46 return blink::mojom::WebBluetoothError::GATT_UNKNOWN_ERROR; | |
47 case BluetoothGattService::GATT_ERROR_FAILED: | |
48 RecordGATTOperationOutcome(operation, UMAGATTOperationOutcome::FAILED); | |
49 return blink::mojom::WebBluetoothError::GATT_UNKNOWN_FAILURE; | |
50 case BluetoothGattService::GATT_ERROR_IN_PROGRESS: | |
51 RecordGATTOperationOutcome(operation, | |
52 UMAGATTOperationOutcome::IN_PROGRESS); | |
53 return blink::mojom::WebBluetoothError::GATT_OPERATION_IN_PROGRESS; | |
54 case BluetoothGattService::GATT_ERROR_INVALID_LENGTH: | |
55 RecordGATTOperationOutcome(operation, | |
56 UMAGATTOperationOutcome::INVALID_LENGTH); | |
57 return blink::mojom::WebBluetoothError::GATT_INVALID_ATTRIBUTE_LENGTH; | |
58 case BluetoothGattService::GATT_ERROR_NOT_PERMITTED: | |
59 RecordGATTOperationOutcome(operation, | |
60 UMAGATTOperationOutcome::NOT_PERMITTED); | |
61 return blink::mojom::WebBluetoothError::GATT_NOT_PERMITTED; | |
62 case BluetoothGattService::GATT_ERROR_NOT_AUTHORIZED: | |
63 RecordGATTOperationOutcome(operation, | |
64 UMAGATTOperationOutcome::NOT_AUTHORIZED); | |
65 return blink::mojom::WebBluetoothError::GATT_NOT_AUTHORIZED; | |
66 case BluetoothGattService::GATT_ERROR_NOT_PAIRED: | |
67 RecordGATTOperationOutcome(operation, | |
68 UMAGATTOperationOutcome::NOT_PAIRED); | |
69 return blink::mojom::WebBluetoothError::GATT_NOT_PAIRED; | |
70 case BluetoothGattService::GATT_ERROR_NOT_SUPPORTED: | |
71 RecordGATTOperationOutcome(operation, | |
72 UMAGATTOperationOutcome::NOT_SUPPORTED); | |
73 return blink::mojom::WebBluetoothError::GATT_NOT_SUPPORTED; | |
74 } | |
75 NOTREACHED(); | |
76 return blink::mojom::WebBluetoothError::GATT_UNTRANSLATED_ERROR_CODE; | |
77 } | |
78 | |
79 } // namespace | |
80 | |
81 using CacheQueryResult = BluetoothDispatcherHost::CacheQueryResult; | |
82 | |
83 // static | |
84 void BluetoothServiceImpl::Create( | |
85 int render_process_id, | |
86 mojo::InterfaceRequest<BluetoothService> request) { | |
87 new BluetoothServiceImpl(std::move(request), render_process_id); | |
88 } | |
89 | |
90 BluetoothServiceImpl::BluetoothServiceImpl( | |
91 mojo::InterfaceRequest<BluetoothService> request, | |
92 int render_process_id) | |
93 : render_process_id_(render_process_id), | |
94 binding_(this, std::move(request)), | |
95 weak_ptr_factory_(this) { | |
96 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
97 | |
98 // Bind all future weak pointers to the UI thread. | |
99 weak_ptr_on_ui_thread_ = weak_ptr_factory_.GetWeakPtr(); | |
100 weak_ptr_on_ui_thread_.get(); // Associates with UI thread. | |
101 } | |
102 | |
103 BluetoothServiceImpl::~BluetoothServiceImpl() {} | |
104 | |
105 void BluetoothServiceImpl::RemoteCharacteristicWriteValue( | |
106 int frame_routing_id, | |
107 const mojo::String& characteristic_instance_id, | |
108 mojo::Array<uint8_t> value, | |
109 const RemoteCharacteristicWriteValueCallback& callback) { | |
110 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
111 RecordWebBluetoothFunctionCall( | |
112 UMAWebBluetoothFunction::CHARACTERISTIC_WRITE_VALUE); | |
113 | |
114 // We perform the length check on the renderer side. So if we | |
115 // get a value with length > 512, we can assume it's a hostile | |
116 // renderer and kill it. | |
117 if (value.size() > 512) { | |
118 CrashRenderer(bad_message::BDH_INVALID_WRITE_VALUE_LENGTH); | |
119 return; | |
120 } | |
121 | |
122 CacheQueryResult query_result = | |
123 GetBluetoothDispatcherHost()->QueryCacheForCharacteristic( | |
124 GetOrigin(frame_routing_id), characteristic_instance_id); | |
125 | |
126 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { | |
127 return; | |
128 } | |
129 | |
130 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { | |
131 RecordCharacteristicWriteValueOutcome(query_result.outcome); | |
132 callback.Run(GetWebError(query_result.outcome)); | |
133 return; | |
134 } | |
135 | |
136 if (BluetoothBlacklist::Get().IsExcludedFromWrites( | |
137 query_result.characteristic->GetUUID())) { | |
138 RecordCharacteristicWriteValueOutcome(UMAGATTOperationOutcome::BLACKLISTED); | |
139 callback.Run(blink::mojom::WebBluetoothError::BLACKLISTED_WRITE); | |
140 return; | |
141 } | |
142 query_result.characteristic->WriteRemoteCharacteristic( | |
Ken Rockot(use gerrit already)
2016/03/09 19:31:26
persisting offline discussion: need to make sure t
ortuno
2016/03/16 16:29:45
As discussed offline: BluetoothServiceImpl lives o
| |
143 value.To<std::vector<uint8_t>>(), | |
144 base::Bind(&BluetoothServiceImpl::OnWriteValueSuccess, | |
145 weak_ptr_on_ui_thread_, callback), | |
146 base::Bind(&BluetoothServiceImpl::OnWriteValueFailed, | |
147 weak_ptr_on_ui_thread_, callback)); | |
148 } | |
149 | |
150 void BluetoothServiceImpl::OnWriteValueSuccess( | |
151 const RemoteCharacteristicWriteValueCallback& callback) { | |
152 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
153 RecordCharacteristicWriteValueOutcome(UMAGATTOperationOutcome::SUCCESS); | |
154 callback.Run(blink::mojom::WebBluetoothError::SUCCESS); | |
155 } | |
156 | |
157 void BluetoothServiceImpl::OnWriteValueFailed( | |
158 const RemoteCharacteristicWriteValueCallback& callback, | |
159 device::BluetoothGattService::GattErrorCode error_code) { | |
160 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
161 callback.Run(TranslateGATTErrorAndRecord( | |
162 error_code, UMAGATTOperation::CHARACTERISTIC_WRITE)); | |
163 } | |
164 | |
165 BluetoothDispatcherHost* BluetoothServiceImpl::GetBluetoothDispatcherHost() { | |
166 RenderProcessHostImpl* render_process_host = | |
167 static_cast<RenderProcessHostImpl*>( | |
168 RenderProcessHost::FromID(render_process_id_)); | |
169 return render_process_host->GetBluetoothDispatcherHost(); | |
170 } | |
171 | |
172 void BluetoothServiceImpl::CrashRenderer(bad_message::BadMessageReason reason) { | |
173 bad_message::ReceivedBadMessage(RenderProcessHost::FromID(render_process_id_), | |
174 reason); | |
175 } | |
176 | |
177 url::Origin BluetoothServiceImpl::GetOrigin(int frame_routing_id) { | |
178 return RenderFrameHost::FromID(render_process_id_, frame_routing_id) | |
179 ->GetLastCommittedOrigin(); | |
180 } | |
181 | |
182 } // namespace content | |
OLD | NEW |