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/web_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_gatt_characteristic.h" | |
12 | |
13 using device::BluetoothGattService; | |
14 | |
15 namespace content { | |
16 | |
17 namespace { | |
18 | |
19 blink::mojom::WebBluetoothError GetWebError(CacheQueryOutcome outcome) { | |
20 switch (outcome) { | |
21 case CacheQueryOutcome::BAD_RENDERER: | |
22 NOTREACHED(); | |
23 return blink::mojom::WebBluetoothError::DEVICE_NO_LONGER_IN_RANGE; | |
24 case CacheQueryOutcome::SUCCESS: | |
25 return blink::mojom::WebBluetoothError::SUCCESS; | |
26 case CacheQueryOutcome::NO_DEVICE: | |
27 return blink::mojom::WebBluetoothError::DEVICE_NO_LONGER_IN_RANGE; | |
28 case CacheQueryOutcome::NO_SERVICE: | |
29 return blink::mojom::WebBluetoothError::SERVICE_NO_LONGER_EXISTS; | |
30 case CacheQueryOutcome::NO_CHARACTERISTIC: | |
31 return blink::mojom::WebBluetoothError::CHARACTERISTIC_NO_LONGER_EXISTS; | |
32 } | |
33 NOTREACHED(); | |
34 return blink::mojom::WebBluetoothError::DEVICE_NO_LONGER_IN_RANGE; | |
35 } | |
36 | |
37 blink::mojom::WebBluetoothError TranslateGATTErrorAndRecord( | |
38 BluetoothGattService::GattErrorCode error_code, | |
39 UMAGATTOperation operation) { | |
40 switch (error_code) { | |
41 case BluetoothGattService::GATT_ERROR_UNKNOWN: | |
42 RecordGATTOperationOutcome(operation, UMAGATTOperationOutcome::UNKNOWN); | |
43 return blink::mojom::WebBluetoothError::GATT_UNKNOWN_ERROR; | |
44 case BluetoothGattService::GATT_ERROR_FAILED: | |
45 RecordGATTOperationOutcome(operation, UMAGATTOperationOutcome::FAILED); | |
46 return blink::mojom::WebBluetoothError::GATT_UNKNOWN_FAILURE; | |
47 case BluetoothGattService::GATT_ERROR_IN_PROGRESS: | |
48 RecordGATTOperationOutcome(operation, | |
49 UMAGATTOperationOutcome::IN_PROGRESS); | |
50 return blink::mojom::WebBluetoothError::GATT_OPERATION_IN_PROGRESS; | |
51 case BluetoothGattService::GATT_ERROR_INVALID_LENGTH: | |
52 RecordGATTOperationOutcome(operation, | |
53 UMAGATTOperationOutcome::INVALID_LENGTH); | |
54 return blink::mojom::WebBluetoothError::GATT_INVALID_ATTRIBUTE_LENGTH; | |
55 case BluetoothGattService::GATT_ERROR_NOT_PERMITTED: | |
56 RecordGATTOperationOutcome(operation, | |
57 UMAGATTOperationOutcome::NOT_PERMITTED); | |
58 return blink::mojom::WebBluetoothError::GATT_NOT_PERMITTED; | |
59 case BluetoothGattService::GATT_ERROR_NOT_AUTHORIZED: | |
60 RecordGATTOperationOutcome(operation, | |
61 UMAGATTOperationOutcome::NOT_AUTHORIZED); | |
62 return blink::mojom::WebBluetoothError::GATT_NOT_AUTHORIZED; | |
63 case BluetoothGattService::GATT_ERROR_NOT_PAIRED: | |
64 RecordGATTOperationOutcome(operation, | |
65 UMAGATTOperationOutcome::NOT_PAIRED); | |
66 return blink::mojom::WebBluetoothError::GATT_NOT_PAIRED; | |
67 case BluetoothGattService::GATT_ERROR_NOT_SUPPORTED: | |
68 RecordGATTOperationOutcome(operation, | |
69 UMAGATTOperationOutcome::NOT_SUPPORTED); | |
70 return blink::mojom::WebBluetoothError::GATT_NOT_SUPPORTED; | |
71 } | |
72 NOTREACHED(); | |
73 return blink::mojom::WebBluetoothError::GATT_UNTRANSLATED_ERROR_CODE; | |
74 } | |
75 | |
76 } // namespace | |
77 | |
78 using CacheQueryResult = BluetoothDispatcherHost::CacheQueryResult; | |
79 | |
80 WebBluetoothServiceImpl::WebBluetoothServiceImpl( | |
81 RenderFrameHost* render_frame_host, | |
82 mojo::InterfaceRequest<blink::mojom::WebBluetoothService> request) | |
83 : render_frame_host_(render_frame_host), | |
84 render_process_host_(render_frame_host->GetProcess()), | |
85 binding_(this, std::move(request)), | |
86 weak_ptr_factory_(this) { | |
87 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
88 | |
89 // Bind all future weak pointers to the UI thread. | |
90 weak_ptr_on_ui_thread_ = weak_ptr_factory_.GetWeakPtr(); | |
Ken Rockot(use gerrit already)
2016/03/17 18:16:13
nit: I think this is a weird thing to do, but it s
ortuno
2016/03/18 01:19:20
I agree. I'll bring it up with scheib.
| |
91 weak_ptr_on_ui_thread_.get(); // Associates with UI thread. | |
92 } | |
93 | |
94 WebBluetoothServiceImpl::~WebBluetoothServiceImpl() {} | |
95 | |
96 void WebBluetoothServiceImpl::RemoteCharacteristicWriteValue( | |
97 const mojo::String& characteristic_instance_id, | |
98 mojo::Array<uint8_t> value, | |
99 const RemoteCharacteristicWriteValueCallback& callback) { | |
100 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
101 RecordWebBluetoothFunctionCall( | |
102 UMAWebBluetoothFunction::CHARACTERISTIC_WRITE_VALUE); | |
103 | |
104 RecordWebBluetoothFunctionCall( | |
105 UMAWebBluetoothFunction::CHARACTERISTIC_WRITE_VALUE); | |
106 | |
107 // We perform the length check on the renderer side. So if we | |
108 // get a value with length > 512, we can assume it's a hostile | |
109 // renderer and kill it. | |
110 if (value.size() > 512) { | |
111 CrashRenderer(bad_message::BDH_INVALID_WRITE_VALUE_LENGTH); | |
112 return; | |
Ken Rockot(use gerrit already)
2016/03/17 18:16:13
You should still invoke the callback here. At leas
ortuno
2016/03/18 01:19:20
I call binding_.Close() on CrashRenderAndClosePipe
| |
113 } | |
114 | |
115 CacheQueryResult query_result = | |
116 GetBluetoothDispatcherHost()->QueryCacheForCharacteristic( | |
117 GetOrigin(), characteristic_instance_id); | |
118 | |
119 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { | |
120 return; | |
121 } | |
122 | |
123 if (query_result.outcome != CacheQueryOutcome::SUCCESS) { | |
124 RecordCharacteristicWriteValueOutcome(query_result.outcome); | |
125 callback.Run(GetWebError(query_result.outcome)); | |
126 return; | |
127 } | |
128 | |
129 if (BluetoothBlacklist::Get().IsExcludedFromWrites( | |
130 query_result.characteristic->GetUUID())) { | |
131 RecordCharacteristicWriteValueOutcome(UMAGATTOperationOutcome::BLACKLISTED); | |
132 callback.Run(blink::mojom::WebBluetoothError::BLACKLISTED_WRITE); | |
133 return; | |
134 } | |
135 | |
136 query_result.characteristic->WriteRemoteCharacteristic( | |
137 value.To<std::vector<uint8_t>>(), | |
138 base::Bind(&WebBluetoothServiceImpl::OnWriteValueSuccess, | |
139 weak_ptr_on_ui_thread_, callback), | |
Ken Rockot(use gerrit already)
2016/03/17 18:16:13
As discussed previously, it's generally unsafe to
ortuno
2016/03/18 01:19:20
As discussed offline, it's ok to do this for the t
| |
140 base::Bind(&WebBluetoothServiceImpl::OnWriteValueFailed, | |
141 weak_ptr_on_ui_thread_, callback)); | |
142 } | |
143 | |
144 void WebBluetoothServiceImpl::OnWriteValueSuccess( | |
145 const RemoteCharacteristicWriteValueCallback& callback) { | |
146 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
147 RecordCharacteristicWriteValueOutcome(UMAGATTOperationOutcome::SUCCESS); | |
148 callback.Run(blink::mojom::WebBluetoothError::SUCCESS); | |
149 } | |
150 | |
151 void WebBluetoothServiceImpl::OnWriteValueFailed( | |
152 const RemoteCharacteristicWriteValueCallback& callback, | |
153 device::BluetoothGattService::GattErrorCode error_code) { | |
154 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
155 callback.Run(TranslateGATTErrorAndRecord( | |
156 error_code, UMAGATTOperation::CHARACTERISTIC_WRITE)); | |
157 } | |
158 | |
159 BluetoothDispatcherHost* WebBluetoothServiceImpl::GetBluetoothDispatcherHost() { | |
160 RenderProcessHostImpl* render_process_host_impl = | |
161 static_cast<RenderProcessHostImpl*>(render_process_host_); | |
162 return render_process_host_impl->GetBluetoothDispatcherHost(); | |
163 } | |
164 | |
165 void WebBluetoothServiceImpl::CrashRenderer( | |
166 bad_message::BadMessageReason reason) { | |
167 bad_message::ReceivedBadMessage(render_process_host_, reason); | |
168 } | |
169 | |
170 url::Origin WebBluetoothServiceImpl::GetOrigin() { | |
171 return render_frame_host_->GetLastCommittedOrigin(); | |
172 } | |
173 | |
174 } // namespace content | |
OLD | NEW |