OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "modules/bluetooth/BluetoothRemoteGATTCharacteristic.h" | 5 #include "modules/bluetooth/BluetoothRemoteGATTCharacteristic.h" |
6 | 6 |
7 #include "bindings/core/v8/ScriptPromise.h" | 7 #include "bindings/core/v8/ScriptPromise.h" |
8 #include "bindings/core/v8/ScriptPromiseResolver.h" | 8 #include "bindings/core/v8/ScriptPromiseResolver.h" |
9 #include "core/dom/DOMDataView.h" | 9 #include "core/dom/DOMDataView.h" |
10 #include "core/dom/DOMException.h" | 10 #include "core/dom/DOMException.h" |
11 #include "core/dom/ExceptionCode.h" | 11 #include "core/dom/ExceptionCode.h" |
12 #include "core/events/Event.h" | 12 #include "core/events/Event.h" |
13 #include "core/inspector/ConsoleMessage.h" | 13 #include "core/inspector/ConsoleMessage.h" |
14 #include "modules/bluetooth/BluetoothCharacteristicProperties.h" | 14 #include "modules/bluetooth/BluetoothCharacteristicProperties.h" |
15 #include "modules/bluetooth/BluetoothError.h" | 15 #include "modules/bluetooth/BluetoothError.h" |
16 #include "modules/bluetooth/BluetoothRemoteGATTDescriptor.h" | |
16 #include "modules/bluetooth/BluetoothRemoteGATTService.h" | 17 #include "modules/bluetooth/BluetoothRemoteGATTService.h" |
17 #include "modules/bluetooth/BluetoothSupplement.h" | 18 #include "modules/bluetooth/BluetoothSupplement.h" |
19 #include "modules/bluetooth/BluetoothUUID.h" | |
18 #include "public/platform/modules/bluetooth/WebBluetooth.h" | 20 #include "public/platform/modules/bluetooth/WebBluetooth.h" |
19 #include <memory> | 21 #include <memory> |
20 | 22 |
21 namespace blink { | 23 namespace blink { |
22 | 24 |
23 namespace { | 25 namespace { |
24 | 26 |
25 const char kGATTServerDisconnected[] = | 27 const char kGATTServerDisconnected[] = |
26 "GATT Server disconnected while performing a GATT operation."; | 28 "GATT Server disconnected while performing a GATT operation."; |
27 const char kGATTServerNotConnected[] = | 29 const char kGATTServerNotConnected[] = |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
113 // We will also need to unregister a characteristic once all the event | 115 // We will also need to unregister a characteristic once all the event |
114 // listeners have been removed. See http://crbug.com/541390 | 116 // listeners have been removed. See http://crbug.com/541390 |
115 if (eventType == EventTypeNames::characteristicvaluechanged) { | 117 if (eventType == EventTypeNames::characteristicvaluechanged) { |
116 WebBluetooth* webbluetooth = | 118 WebBluetooth* webbluetooth = |
117 BluetoothSupplement::fromExecutionContext(getExecutionContext()); | 119 BluetoothSupplement::fromExecutionContext(getExecutionContext()); |
118 webbluetooth->registerCharacteristicObject( | 120 webbluetooth->registerCharacteristicObject( |
119 m_webCharacteristic->characteristicInstanceID, this); | 121 m_webCharacteristic->characteristicInstanceID, this); |
120 } | 122 } |
121 } | 123 } |
122 | 124 |
123 class ReadValueCallback : public WebBluetoothReadValueCallbacks { | 125 class GetDescriptorsCallback : public WebBluetoothGetDescriptorsCallbacks { |
124 public: | 126 public: |
125 ReadValueCallback(BluetoothRemoteGATTCharacteristic* characteristic, | 127 GetDescriptorsCallback(BluetoothRemoteGATTService* service, |
126 ScriptPromiseResolver* resolver) | 128 BluetoothRemoteGATTCharacteristic* characteristic, |
129 mojom::blink::WebBluetoothGATTQueryQuantity quantity, | |
130 ScriptPromiseResolver* resolver) | |
131 : m_service(service), | |
132 m_characteristic(characteristic), | |
133 m_quantity(quantity), | |
134 m_resolver(resolver) { | |
135 // We always check that the device is connected before constructing this | |
136 // object. | |
137 CHECK(m_service->device()->gatt()->connected()); | |
138 m_service->device()->gatt()->AddToActiveAlgorithms(m_resolver.get()); | |
139 } | |
140 | |
141 void onSuccess(const WebVector<WebBluetoothRemoteGATTDescriptorInit*>& | |
142 webDescriptors) override { | |
143 if (!m_resolver->getExecutionContext() || | |
144 m_resolver->getExecutionContext()->activeDOMObjectsAreStopped()) | |
145 return; | |
146 | |
147 // If the resolver is not in the set of ActiveAlgorithms then the frame | |
148 // disconnected so we reject. | |
149 if (!m_service->device()->gatt()->RemoveFromActiveAlgorithms( | |
150 m_resolver.get())) { | |
151 m_resolver->reject( | |
152 DOMException::create(NetworkError, kGATTServerDisconnected)); | |
153 return; | |
154 } | |
155 | |
156 if (m_quantity == mojom::blink::WebBluetoothGATTQueryQuantity::SINGLE) { | |
157 DCHECK_EQ(1u, webDescriptors.size()); | |
158 // TODO(crbug.com/495270): Add the descriptor to the Attribute Instance | |
159 // Map when the map supports it. | |
160 m_resolver->resolve(BluetoothRemoteGATTDescriptor::take( | |
161 wrapUnique(webDescriptors[0]), m_characteristic)); | |
162 return; | |
163 } | |
164 | |
165 HeapVector<Member<BluetoothRemoteGATTDescriptor>> descriptors; | |
166 descriptors.reserveInitialCapacity(webDescriptors.size()); | |
167 for (WebBluetoothRemoteGATTDescriptorInit* webDescriptor : webDescriptors) { | |
168 // TODO(crbug.com/495270): Add the descriptor to the Attribute Instance | |
169 // Map when the map supports it. | |
170 descriptors.append(BluetoothRemoteGATTDescriptor::take( | |
171 wrapUnique(webDescriptor), m_characteristic)); | |
172 } | |
173 m_resolver->resolve(descriptors); | |
174 } | |
175 | |
176 void onError( | |
177 int32_t | |
178 error /* Corresponds to WebBluetoothResult in web_bluetooth.mojom */) | |
179 override { | |
180 if (!m_resolver->getExecutionContext() || | |
181 m_resolver->getExecutionContext()->activeDOMObjectsAreStopped()) | |
182 return; | |
183 | |
184 // If the resolver is not in the set of ActiveAlgorithms then the frame | |
185 // disconnected so we reject. | |
186 if (!m_service->device()->gatt()->RemoveFromActiveAlgorithms( | |
187 m_resolver.get())) { | |
188 m_resolver->reject( | |
189 DOMException::create(NetworkError, kGATTServerDisconnected)); | |
190 return; | |
191 } | |
192 | |
193 m_resolver->reject(BluetoothError::take(m_resolver, error)); | |
194 } | |
195 | |
196 private: | |
197 Persistent<BluetoothRemoteGATTService> m_service; | |
ortuno
2016/11/22 03:02:02
No need to pass in the service. You can use m_char
dougt
2016/11/29 22:50:48
Done.
| |
198 Persistent<BluetoothRemoteGATTCharacteristic> m_characteristic; | |
199 mojom::blink::WebBluetoothGATTQueryQuantity m_quantity; | |
200 const Persistent<ScriptPromiseResolver> m_resolver; | |
201 }; | |
202 | |
203 ScriptPromise BluetoothRemoteGATTCharacteristic::getDescriptorsImpl( | |
204 ScriptState* scriptState, | |
205 mojom::blink::WebBluetoothGATTQueryQuantity quantity, | |
206 const String& descriptor) { | |
207 WebBluetooth* webbluetooth = | |
208 BluetoothSupplement::fromScriptState(scriptState); | |
209 | |
ortuno
2016/11/22 03:02:02
Check the characteristic is still valid and also a
dougt
2016/11/29 22:50:48
A few lines below (216) I check to see if the char
| |
210 if (!gatt()->connected()) { | |
211 return ScriptPromise::rejectWithDOMException( | |
212 scriptState, | |
213 DOMException::create(NetworkError, kGATTServerNotConnected)); | |
214 } | |
215 | |
216 if (!gatt()->device()->isValidCharacteristic( | |
217 m_webCharacteristic->characteristicInstanceID)) { | |
218 return ScriptPromise::rejectWithDOMException( | |
219 scriptState, | |
220 DOMException::create(InvalidStateError, kInvalidCharacteristic)); | |
221 } | |
222 | |
223 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); | |
224 ScriptPromise promise = resolver->promise(); | |
225 | |
226 webbluetooth->getDescriptors( | |
227 m_webCharacteristic->characteristicInstanceID, | |
228 static_cast<int32_t>(quantity), descriptor, | |
229 new GetDescriptorsCallback(m_service, this, quantity, resolver)); | |
230 | |
231 return promise; | |
232 } | |
233 | |
234 ScriptPromise BluetoothRemoteGATTCharacteristic::getDescriptor( | |
235 ScriptState* scriptState, | |
236 const StringOrUnsignedLong& descriptorUUID, | |
237 ExceptionState& exceptionState) { | |
238 String descriptor = | |
239 BluetoothUUID::getDescriptor(descriptorUUID, exceptionState); | |
240 if (exceptionState.hadException()) | |
241 return exceptionState.reject(scriptState); | |
242 | |
243 return getDescriptorsImpl(scriptState, | |
244 mojom::blink::WebBluetoothGATTQueryQuantity::SINGLE, | |
245 descriptor); | |
246 } | |
247 | |
248 ScriptPromise BluetoothRemoteGATTCharacteristic::getDescriptors( | |
249 ScriptState* scriptState, | |
250 ExceptionState&) { | |
251 return getDescriptorsImpl( | |
252 scriptState, mojom::blink::WebBluetoothGATTQueryQuantity::MULTIPLE); | |
253 } | |
254 | |
255 ScriptPromise BluetoothRemoteGATTCharacteristic::getDescriptors( | |
256 ScriptState* scriptState, | |
257 const StringOrUnsignedLong& descriptorUUID, | |
258 ExceptionState& exceptionState) { | |
259 String descriptor = | |
260 BluetoothUUID::getDescriptor(descriptorUUID, exceptionState); | |
261 if (exceptionState.hadException()) | |
262 return exceptionState.reject(scriptState); | |
263 | |
264 return getDescriptorsImpl( | |
265 scriptState, mojom::blink::WebBluetoothGATTQueryQuantity::MULTIPLE, | |
266 descriptor); | |
267 } | |
268 | |
269 class CharacteristicReadValueCallback : public WebBluetoothReadValueCallbacks { | |
270 public: | |
271 CharacteristicReadValueCallback( | |
272 BluetoothRemoteGATTCharacteristic* characteristic, | |
273 ScriptPromiseResolver* resolver) | |
127 : m_characteristic(characteristic), m_resolver(resolver) { | 274 : m_characteristic(characteristic), m_resolver(resolver) { |
128 // We always check that the device is connected before constructing this | 275 // We always check that the device is connected before constructing this |
129 // object. | 276 // object. |
130 CHECK(m_characteristic->gatt()->connected()); | 277 CHECK(m_characteristic->gatt()->connected()); |
131 m_characteristic->gatt()->AddToActiveAlgorithms(m_resolver.get()); | 278 m_characteristic->gatt()->AddToActiveAlgorithms(m_resolver.get()); |
132 } | 279 } |
133 | 280 |
134 void onSuccess(const WebVector<uint8_t>& value) override { | 281 void onSuccess(const WebVector<uint8_t>& value) override { |
135 if (!m_resolver->getExecutionContext() || | 282 if (!m_resolver->getExecutionContext() || |
136 m_resolver->getExecutionContext()->activeDOMObjectsAreStopped()) | 283 m_resolver->getExecutionContext()->activeDOMObjectsAreStopped()) |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
186 return ScriptPromise::rejectWithDOMException( | 333 return ScriptPromise::rejectWithDOMException( |
187 scriptState, | 334 scriptState, |
188 DOMException::create(InvalidStateError, kInvalidCharacteristic)); | 335 DOMException::create(InvalidStateError, kInvalidCharacteristic)); |
189 } | 336 } |
190 | 337 |
191 WebBluetooth* webbluetooth = | 338 WebBluetooth* webbluetooth = |
192 BluetoothSupplement::fromScriptState(scriptState); | 339 BluetoothSupplement::fromScriptState(scriptState); |
193 | 340 |
194 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); | 341 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); |
195 ScriptPromise promise = resolver->promise(); | 342 ScriptPromise promise = resolver->promise(); |
196 webbluetooth->readValue(m_webCharacteristic->characteristicInstanceID, | 343 webbluetooth->characteristicReadValue( |
197 new ReadValueCallback(this, resolver)); | 344 m_webCharacteristic->characteristicInstanceID, |
345 new CharacteristicReadValueCallback(this, resolver)); | |
198 | 346 |
199 return promise; | 347 return promise; |
200 } | 348 } |
201 | 349 |
202 class WriteValueCallback : public WebBluetoothWriteValueCallbacks { | 350 class CharacteristicWriteValueCallback |
351 : public WebBluetoothWriteValueCallbacks { | |
203 public: | 352 public: |
204 WriteValueCallback(BluetoothRemoteGATTCharacteristic* characteristic, | 353 CharacteristicWriteValueCallback( |
205 ScriptPromiseResolver* resolver) | 354 BluetoothRemoteGATTCharacteristic* characteristic, |
355 ScriptPromiseResolver* resolver) | |
206 : m_characteristic(characteristic), m_resolver(resolver) { | 356 : m_characteristic(characteristic), m_resolver(resolver) { |
207 // We always check that the device is connected before constructing this | 357 // We always check that the device is connected before constructing this |
208 // object. | 358 // object. |
209 CHECK(m_characteristic->gatt()->connected()); | 359 CHECK(m_characteristic->gatt()->connected()); |
210 m_characteristic->gatt()->AddToActiveAlgorithms(m_resolver.get()); | 360 m_characteristic->gatt()->AddToActiveAlgorithms(m_resolver.get()); |
211 } | 361 } |
212 | 362 |
213 void onSuccess(const WebVector<uint8_t>& value) override { | 363 void onSuccess(const WebVector<uint8_t>& value) override { |
214 if (!m_resolver->getExecutionContext() || | 364 if (!m_resolver->getExecutionContext() || |
215 m_resolver->getExecutionContext()->activeDOMObjectsAreStopped()) | 365 m_resolver->getExecutionContext()->activeDOMObjectsAreStopped()) |
(...skipping 12 matching lines...) Expand all Loading... | |
228 m_resolver->resolve(); | 378 m_resolver->resolve(); |
229 } | 379 } |
230 | 380 |
231 void onError( | 381 void onError( |
232 int32_t | 382 int32_t |
233 error /* Corresponds to WebBluetoothResult in web_bluetooth.mojom */) | 383 error /* Corresponds to WebBluetoothResult in web_bluetooth.mojom */) |
234 override { | 384 override { |
235 if (!m_resolver->getExecutionContext() || | 385 if (!m_resolver->getExecutionContext() || |
236 m_resolver->getExecutionContext()->activeDOMObjectsAreStopped()) | 386 m_resolver->getExecutionContext()->activeDOMObjectsAreStopped()) |
237 return; | 387 return; |
238 | |
239 if (!m_characteristic->gatt()->RemoveFromActiveAlgorithms( | 388 if (!m_characteristic->gatt()->RemoveFromActiveAlgorithms( |
240 m_resolver.get())) { | 389 m_resolver.get())) { |
241 m_resolver->reject( | 390 m_resolver->reject( |
242 DOMException::create(NetworkError, kGATTServerDisconnected)); | 391 DOMException::create(NetworkError, kGATTServerDisconnected)); |
243 return; | 392 return; |
244 } | 393 } |
245 | 394 |
246 m_resolver->reject(BluetoothError::take(m_resolver, error)); | 395 m_resolver->reject(BluetoothError::take(m_resolver, error)); |
247 } | 396 } |
248 | 397 |
(...skipping 30 matching lines...) Expand all Loading... | |
279 return ScriptPromise::rejectWithDOMException( | 428 return ScriptPromise::rejectWithDOMException( |
280 scriptState, DOMException::create(InvalidModificationError, | 429 scriptState, DOMException::create(InvalidModificationError, |
281 "Value can't exceed 512 bytes.")); | 430 "Value can't exceed 512 bytes.")); |
282 | 431 |
283 // Let valueVector be a copy of the bytes held by value. | 432 // Let valueVector be a copy of the bytes held by value. |
284 WebVector<uint8_t> valueVector(value.bytes(), value.byteLength()); | 433 WebVector<uint8_t> valueVector(value.bytes(), value.byteLength()); |
285 | 434 |
286 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); | 435 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); |
287 | 436 |
288 ScriptPromise promise = resolver->promise(); | 437 ScriptPromise promise = resolver->promise(); |
289 webbluetooth->writeValue(m_webCharacteristic->characteristicInstanceID, | 438 webbluetooth->characteristicWriteValue( |
290 valueVector, new WriteValueCallback(this, resolver)); | 439 m_webCharacteristic->characteristicInstanceID, valueVector, |
440 new CharacteristicWriteValueCallback(this, resolver)); | |
291 | 441 |
292 return promise; | 442 return promise; |
293 } | 443 } |
294 | 444 |
295 class NotificationsCallback : public WebBluetoothNotificationsCallbacks { | 445 class NotificationsCallback : public WebBluetoothNotificationsCallbacks { |
296 public: | 446 public: |
297 NotificationsCallback(BluetoothRemoteGATTCharacteristic* characteristic, | 447 NotificationsCallback(BluetoothRemoteGATTCharacteristic* characteristic, |
298 ScriptPromiseResolver* resolver) | 448 ScriptPromiseResolver* resolver) |
299 : m_characteristic(characteristic), m_resolver(resolver) { | 449 : m_characteristic(characteristic), m_resolver(resolver) { |
300 // We always check that the device is connected before constructing this | 450 // We always check that the device is connected before constructing this |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
400 | 550 |
401 DEFINE_TRACE(BluetoothRemoteGATTCharacteristic) { | 551 DEFINE_TRACE(BluetoothRemoteGATTCharacteristic) { |
402 visitor->trace(m_service); | 552 visitor->trace(m_service); |
403 visitor->trace(m_properties); | 553 visitor->trace(m_properties); |
404 visitor->trace(m_value); | 554 visitor->trace(m_value); |
405 EventTargetWithInlineData::trace(visitor); | 555 EventTargetWithInlineData::trace(visitor); |
406 ActiveDOMObject::trace(visitor); | 556 ActiveDOMObject::trace(visitor); |
407 } | 557 } |
408 | 558 |
409 } // namespace blink | 559 } // namespace blink |
OLD | NEW |