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 <vector> | |
8 | |
9 #include "content/browser/bluetooth/bluetooth_blacklist.h" | |
10 #include "content/browser/bluetooth/bluetooth_dispatcher_host.h" | |
11 #include "content/browser/renderer_host/render_process_host_impl.h" | |
12 #include "content/public/browser/render_frame_host.h" | |
13 #include "device/bluetooth/bluetooth_gatt_characteristic.h" | |
14 | |
15 using device::BluetoothGattService; | |
16 | |
17 namespace content { | |
18 | |
19 namespace { | |
20 | |
21 blink::mojom::WebBluetoothError GetWebError(CacheQueryOutcome outcome) { | |
Jeffrey Yasskin
2016/03/25 00:48:23
I think this duplication will also go away if you
ortuno
2016/03/29 17:58:34
Done. \o/
| |
22 switch (outcome) { | |
23 case CacheQueryOutcome::BAD_RENDERER: | |
24 NOTREACHED(); | |
25 return blink::mojom::WebBluetoothError::DEVICE_NO_LONGER_IN_RANGE; | |
26 case CacheQueryOutcome::SUCCESS: | |
27 return blink::mojom::WebBluetoothError::SUCCESS; | |
28 case CacheQueryOutcome::NO_DEVICE: | |
29 return blink::mojom::WebBluetoothError::DEVICE_NO_LONGER_IN_RANGE; | |
30 case CacheQueryOutcome::NO_SERVICE: | |
31 return blink::mojom::WebBluetoothError::SERVICE_NO_LONGER_EXISTS; | |
32 case CacheQueryOutcome::NO_CHARACTERISTIC: | |
33 return blink::mojom::WebBluetoothError::CHARACTERISTIC_NO_LONGER_EXISTS; | |
34 } | |
35 NOTREACHED(); | |
36 return blink::mojom::WebBluetoothError::DEVICE_NO_LONGER_IN_RANGE; | |
37 } | |
38 | |
39 blink::mojom::WebBluetoothError TranslateGATTErrorAndRecord( | |
40 BluetoothGattService::GattErrorCode error_code, | |
41 UMAGATTOperation operation) { | |
42 switch (error_code) { | |
43 case BluetoothGattService::GATT_ERROR_UNKNOWN: | |
44 RecordGATTOperationOutcome(operation, UMAGATTOperationOutcome::UNKNOWN); | |
45 return blink::mojom::WebBluetoothError::GATT_UNKNOWN_ERROR; | |
46 case BluetoothGattService::GATT_ERROR_FAILED: | |
47 RecordGATTOperationOutcome(operation, UMAGATTOperationOutcome::FAILED); | |
48 return blink::mojom::WebBluetoothError::GATT_UNKNOWN_FAILURE; | |
49 case BluetoothGattService::GATT_ERROR_IN_PROGRESS: | |
50 RecordGATTOperationOutcome(operation, | |
51 UMAGATTOperationOutcome::IN_PROGRESS); | |
52 return blink::mojom::WebBluetoothError::GATT_OPERATION_IN_PROGRESS; | |
53 case BluetoothGattService::GATT_ERROR_INVALID_LENGTH: | |
54 RecordGATTOperationOutcome(operation, | |
55 UMAGATTOperationOutcome::INVALID_LENGTH); | |
56 return blink::mojom::WebBluetoothError::GATT_INVALID_ATTRIBUTE_LENGTH; | |
57 case BluetoothGattService::GATT_ERROR_NOT_PERMITTED: | |
58 RecordGATTOperationOutcome(operation, | |
59 UMAGATTOperationOutcome::NOT_PERMITTED); | |
60 return blink::mojom::WebBluetoothError::GATT_NOT_PERMITTED; | |
61 case BluetoothGattService::GATT_ERROR_NOT_AUTHORIZED: | |
62 RecordGATTOperationOutcome(operation, | |
63 UMAGATTOperationOutcome::NOT_AUTHORIZED); | |
64 return blink::mojom::WebBluetoothError::GATT_NOT_AUTHORIZED; | |
65 case BluetoothGattService::GATT_ERROR_NOT_PAIRED: | |
66 RecordGATTOperationOutcome(operation, | |
67 UMAGATTOperationOutcome::NOT_PAIRED); | |
68 return blink::mojom::WebBluetoothError::GATT_NOT_PAIRED; | |
69 case BluetoothGattService::GATT_ERROR_NOT_SUPPORTED: | |
70 RecordGATTOperationOutcome(operation, | |
71 UMAGATTOperationOutcome::NOT_SUPPORTED); | |
72 return blink::mojom::WebBluetoothError::GATT_NOT_SUPPORTED; | |
73 } | |
74 NOTREACHED(); | |
75 return blink::mojom::WebBluetoothError::GATT_UNTRANSLATED_ERROR_CODE; | |
76 } | |
77 | |
78 } // namespace | |
79 | |
80 using CacheQueryResult = BluetoothDispatcherHost::CacheQueryResult; | |
81 | |
82 WebBluetoothServiceImpl::WebBluetoothServiceImpl( | |
83 RenderFrameHost* render_frame_host, | |
84 blink::mojom::WebBluetoothServiceRequest request) | |
85 : render_frame_host_(render_frame_host), | |
86 render_process_host_(render_frame_host->GetProcess()), | |
87 binding_(this, std::move(request)), | |
88 weak_ptr_factory_(this) { | |
89 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
90 | |
91 // Bind all future weak pointers to the UI thread. | |
92 weak_ptr_on_ui_thread_ = weak_ptr_factory_.GetWeakPtr(); | |
93 weak_ptr_on_ui_thread_.get(); // Associates with UI thread. | |
94 } | |
95 | |
96 WebBluetoothServiceImpl::~WebBluetoothServiceImpl() {} | |
97 | |
98 void WebBluetoothServiceImpl::RemoteCharacteristicWriteValue( | |
99 const mojo::String& characteristic_instance_id, | |
100 mojo::Array<uint8_t> value, | |
101 const RemoteCharacteristicWriteValueCallback& callback) { | |
102 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
103 RecordWebBluetoothFunctionCall( | |
104 UMAWebBluetoothFunction::CHARACTERISTIC_WRITE_VALUE); | |
105 | |
106 // We perform the length check on the renderer side. So if we | |
107 // get a value with length > 512, we can assume it's a hostile | |
108 // renderer and kill it. | |
109 if (value.size() > 512) { | |
110 CrashRendererAndClosePipe(bad_message::BDH_INVALID_WRITE_VALUE_LENGTH); | |
111 return; | |
112 } | |
113 | |
114 const CacheQueryResult query_result = | |
115 GetBluetoothDispatcherHost()->QueryCacheForCharacteristic( | |
116 GetOrigin(), characteristic_instance_id); | |
117 | |
118 if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) { | |
119 binding_.Close(); | |
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), | |
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( | |
Jeffrey Yasskin
2016/03/25 00:48:23
Probably keep the comment that "// TranslateGATTEr
ortuno
2016/03/29 17:58:34
It's now called TranslateGATTErrorAndRecord. Do yo
Jeffrey Yasskin
2016/03/29 20:30:02
Good point, probably not.
| |
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::CrashRendererAndClosePipe( | |
166 bad_message::BadMessageReason reason) { | |
167 bad_message::ReceivedBadMessage(render_process_host_, reason); | |
168 binding_.Close(); | |
169 } | |
170 | |
171 url::Origin WebBluetoothServiceImpl::GetOrigin() { | |
172 return render_frame_host_->GetLastCommittedOrigin(); | |
173 } | |
174 | |
175 } // namespace content | |
OLD | NEW |