Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(624)

Side by Side Diff: third_party/WebKit/Source/modules/bluetooth/BluetoothRemoteGATTCharacteristic.cpp

Issue 2466223002: Implement WebBluetooth getDescriptor[s] (Closed)
Patch Set: Removing BDH_INVALID_DESCRIPTOR_ID Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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(BluetoothRemoteGATTCharacteristic* characteristic,
126 ScriptPromiseResolver* resolver) 128 mojom::blink::WebBluetoothGATTQueryQuantity quantity,
129 ScriptPromiseResolver* resolver)
130 : m_characteristic(characteristic),
131 m_quantity(quantity),
132 m_resolver(resolver) {
133 // We always check that the device is connected before constructing this
134 // object.
135 CHECK(m_characteristic->gatt()->connected());
dcheng 2016/12/09 08:17:57 Why is this a CHECK? Either we should handle the e
dougt 2016/12/09 19:20:07 Hrm. I think this should be handled properly and
scheib 2016/12/10 01:12:59 DCHECK is right here. (dougt, see https://chromium
136 m_characteristic->gatt()->AddToActiveAlgorithms(m_resolver.get());
137 }
138
139 void onSuccess(const WebVector<WebBluetoothRemoteGATTDescriptorInit*>&
140 webDescriptors) override {
141 if (!m_resolver->getExecutionContext() ||
142 m_resolver->getExecutionContext()->isContextDestroyed())
143 return;
144
145 // If the resolver is not in the set of ActiveAlgorithms then the frame
146 // disconnected so we reject.
147 if (!m_characteristic->gatt()->RemoveFromActiveAlgorithms(
148 m_resolver.get())) {
149 m_resolver->reject(
150 DOMException::create(NetworkError, kGATTServerDisconnected));
151 return;
152 }
153
154 if (m_quantity == mojom::blink::WebBluetoothGATTQueryQuantity::SINGLE) {
155 DCHECK_EQ(1u, webDescriptors.size());
156 m_resolver->resolve(
157 m_characteristic->gatt()
158 ->device()
159 ->getOrCreateBluetoothRemoteGATTDescriptor(
160 wrapUnique(webDescriptors[0]), m_characteristic));
161 return;
162 }
163
164 HeapVector<Member<BluetoothRemoteGATTDescriptor>> descriptors;
165 descriptors.reserveInitialCapacity(webDescriptors.size());
166 for (WebBluetoothRemoteGATTDescriptorInit* webDescriptor : webDescriptors) {
167 descriptors.append(m_characteristic->gatt()
168 ->device()
169 ->getOrCreateBluetoothRemoteGATTDescriptor(
170 wrapUnique(webDescriptor), m_characteristic));
dcheng 2016/12/09 08:17:57 It seems slightly surprising to me that we're tran
dougt 2016/12/09 19:20:07 Another question for ortuno or vince -- not sure w
scheib 2016/12/10 01:12:59 Related to the comment in content/renderer/bluetoo
ortuno 2016/12/11 22:12:21 I first introduced the raw pointers pattern in htt
171 }
172 m_resolver->resolve(descriptors);
173 }
174
175 void onError(
176 int32_t
177 error /* Corresponds to WebBluetoothResult in web_bluetooth.mojom */)
178 override {
179 if (!m_resolver->getExecutionContext() ||
180 m_resolver->getExecutionContext()->isContextDestroyed())
181 return;
182
183 // If the resolver is not in the set of ActiveAlgorithms then the frame
184 // disconnected so we reject.
185 if (!m_characteristic->gatt()->RemoveFromActiveAlgorithms(
186 m_resolver.get())) {
187 m_resolver->reject(
188 DOMException::create(NetworkError, kGATTServerDisconnected));
189 return;
190 }
191
192 m_resolver->reject(BluetoothError::take(m_resolver, error));
193 }
194
195 private:
196 Persistent<BluetoothRemoteGATTCharacteristic> m_characteristic;
197 mojom::blink::WebBluetoothGATTQueryQuantity m_quantity;
198 const Persistent<ScriptPromiseResolver> m_resolver;
199 };
200
201 ScriptPromise BluetoothRemoteGATTCharacteristic::getDescriptor(
202 ScriptState* scriptState,
203 const StringOrUnsignedLong& descriptorUUID,
204 ExceptionState& exceptionState) {
205 String descriptor =
206 BluetoothUUID::getDescriptor(descriptorUUID, exceptionState);
207 if (exceptionState.hadException())
208 return exceptionState.reject(scriptState);
209
210 return getDescriptorsImpl(scriptState,
211 mojom::blink::WebBluetoothGATTQueryQuantity::SINGLE,
212 descriptor);
213 }
214
215 ScriptPromise BluetoothRemoteGATTCharacteristic::getDescriptors(
216 ScriptState* scriptState,
217 ExceptionState&) {
218 return getDescriptorsImpl(
219 scriptState, mojom::blink::WebBluetoothGATTQueryQuantity::MULTIPLE);
220 }
221
222 ScriptPromise BluetoothRemoteGATTCharacteristic::getDescriptors(
223 ScriptState* scriptState,
224 const StringOrUnsignedLong& descriptorUUID,
225 ExceptionState& exceptionState) {
226 String descriptor =
227 BluetoothUUID::getDescriptor(descriptorUUID, exceptionState);
228 if (exceptionState.hadException())
229 return exceptionState.reject(scriptState);
230
231 return getDescriptorsImpl(
232 scriptState, mojom::blink::WebBluetoothGATTQueryQuantity::MULTIPLE,
233 descriptor);
234 }
235
236 class CharacteristicReadValueCallback : public WebBluetoothReadValueCallbacks {
237 public:
238 CharacteristicReadValueCallback(
239 BluetoothRemoteGATTCharacteristic* characteristic,
240 ScriptPromiseResolver* resolver)
127 : m_characteristic(characteristic), m_resolver(resolver) { 241 : m_characteristic(characteristic), m_resolver(resolver) {
128 // We always check that the device is connected before constructing this 242 // We always check that the device is connected before constructing this
129 // object. 243 // object.
130 CHECK(m_characteristic->gatt()->connected()); 244 CHECK(m_characteristic->gatt()->connected());
131 m_characteristic->gatt()->AddToActiveAlgorithms(m_resolver.get()); 245 m_characteristic->gatt()->AddToActiveAlgorithms(m_resolver.get());
132 } 246 }
133 247
134 void onSuccess(const WebVector<uint8_t>& value) override { 248 void onSuccess(const WebVector<uint8_t>& value) override {
135 if (!m_resolver->getExecutionContext() || 249 if (!m_resolver->getExecutionContext() ||
136 m_resolver->getExecutionContext()->isContextDestroyed()) 250 m_resolver->getExecutionContext()->isContextDestroyed())
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 return ScriptPromise::rejectWithDOMException( 300 return ScriptPromise::rejectWithDOMException(
187 scriptState, 301 scriptState,
188 DOMException::create(InvalidStateError, kInvalidCharacteristic)); 302 DOMException::create(InvalidStateError, kInvalidCharacteristic));
189 } 303 }
190 304
191 WebBluetooth* webbluetooth = 305 WebBluetooth* webbluetooth =
192 BluetoothSupplement::fromScriptState(scriptState); 306 BluetoothSupplement::fromScriptState(scriptState);
193 307
194 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); 308 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
195 ScriptPromise promise = resolver->promise(); 309 ScriptPromise promise = resolver->promise();
196 webbluetooth->readValue(m_webCharacteristic->characteristicInstanceID, 310 webbluetooth->characteristicReadValue(
197 new ReadValueCallback(this, resolver)); 311 m_webCharacteristic->characteristicInstanceID,
312 new CharacteristicReadValueCallback(this, resolver));
198 313
199 return promise; 314 return promise;
200 } 315 }
201 316
202 class WriteValueCallback : public WebBluetoothWriteValueCallbacks { 317 class CharacteristicWriteValueCallback
318 : public WebBluetoothWriteValueCallbacks {
203 public: 319 public:
204 WriteValueCallback(BluetoothRemoteGATTCharacteristic* characteristic, 320 CharacteristicWriteValueCallback(
205 ScriptPromiseResolver* resolver) 321 BluetoothRemoteGATTCharacteristic* characteristic,
322 ScriptPromiseResolver* resolver)
206 : m_characteristic(characteristic), m_resolver(resolver) { 323 : m_characteristic(characteristic), m_resolver(resolver) {
207 // We always check that the device is connected before constructing this 324 // We always check that the device is connected before constructing this
208 // object. 325 // object.
209 CHECK(m_characteristic->gatt()->connected()); 326 CHECK(m_characteristic->gatt()->connected());
210 m_characteristic->gatt()->AddToActiveAlgorithms(m_resolver.get()); 327 m_characteristic->gatt()->AddToActiveAlgorithms(m_resolver.get());
211 } 328 }
212 329
213 void onSuccess(const WebVector<uint8_t>& value) override { 330 void onSuccess(const WebVector<uint8_t>& value) override {
214 if (!m_resolver->getExecutionContext() || 331 if (!m_resolver->getExecutionContext() ||
215 m_resolver->getExecutionContext()->isContextDestroyed()) 332 m_resolver->getExecutionContext()->isContextDestroyed())
(...skipping 12 matching lines...) Expand all
228 m_resolver->resolve(); 345 m_resolver->resolve();
229 } 346 }
230 347
231 void onError( 348 void onError(
232 int32_t 349 int32_t
233 error /* Corresponds to WebBluetoothResult in web_bluetooth.mojom */) 350 error /* Corresponds to WebBluetoothResult in web_bluetooth.mojom */)
234 override { 351 override {
235 if (!m_resolver->getExecutionContext() || 352 if (!m_resolver->getExecutionContext() ||
236 m_resolver->getExecutionContext()->isContextDestroyed()) 353 m_resolver->getExecutionContext()->isContextDestroyed())
237 return; 354 return;
238
239 if (!m_characteristic->gatt()->RemoveFromActiveAlgorithms( 355 if (!m_characteristic->gatt()->RemoveFromActiveAlgorithms(
240 m_resolver.get())) { 356 m_resolver.get())) {
241 m_resolver->reject( 357 m_resolver->reject(
242 DOMException::create(NetworkError, kGATTServerDisconnected)); 358 DOMException::create(NetworkError, kGATTServerDisconnected));
243 return; 359 return;
244 } 360 }
245 361
246 m_resolver->reject(BluetoothError::take(m_resolver, error)); 362 m_resolver->reject(BluetoothError::take(m_resolver, error));
247 } 363 }
248 364
(...skipping 30 matching lines...) Expand all
279 return ScriptPromise::rejectWithDOMException( 395 return ScriptPromise::rejectWithDOMException(
280 scriptState, DOMException::create(InvalidModificationError, 396 scriptState, DOMException::create(InvalidModificationError,
281 "Value can't exceed 512 bytes.")); 397 "Value can't exceed 512 bytes."));
282 398
283 // Let valueVector be a copy of the bytes held by value. 399 // Let valueVector be a copy of the bytes held by value.
284 WebVector<uint8_t> valueVector(value.bytes(), value.byteLength()); 400 WebVector<uint8_t> valueVector(value.bytes(), value.byteLength());
285 401
286 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); 402 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
287 403
288 ScriptPromise promise = resolver->promise(); 404 ScriptPromise promise = resolver->promise();
289 webbluetooth->writeValue(m_webCharacteristic->characteristicInstanceID, 405 webbluetooth->characteristicWriteValue(
290 valueVector, new WriteValueCallback(this, resolver)); 406 m_webCharacteristic->characteristicInstanceID, valueVector,
407 new CharacteristicWriteValueCallback(this, resolver));
291 408
292 return promise; 409 return promise;
293 } 410 }
294 411
295 class NotificationsCallback : public WebBluetoothNotificationsCallbacks { 412 class NotificationsCallback : public WebBluetoothNotificationsCallbacks {
296 public: 413 public:
297 NotificationsCallback(BluetoothRemoteGATTCharacteristic* characteristic, 414 NotificationsCallback(BluetoothRemoteGATTCharacteristic* characteristic,
298 ScriptPromiseResolver* resolver) 415 ScriptPromiseResolver* resolver)
299 : m_characteristic(characteristic), m_resolver(resolver) { 416 : m_characteristic(characteristic), m_resolver(resolver) {
300 // We always check that the device is connected before constructing this 417 // We always check that the device is connected before constructing this
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 508
392 WebBluetooth* webbluetooth = 509 WebBluetooth* webbluetooth =
393 BluetoothSupplement::fromScriptState(scriptState); 510 BluetoothSupplement::fromScriptState(scriptState);
394 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); 511 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
395 ScriptPromise promise = resolver->promise(); 512 ScriptPromise promise = resolver->promise();
396 webbluetooth->stopNotifications(m_webCharacteristic->characteristicInstanceID, 513 webbluetooth->stopNotifications(m_webCharacteristic->characteristicInstanceID,
397 new NotificationsCallback(this, resolver)); 514 new NotificationsCallback(this, resolver));
398 return promise; 515 return promise;
399 } 516 }
400 517
518 ScriptPromise BluetoothRemoteGATTCharacteristic::getDescriptorsImpl(
519 ScriptState* scriptState,
520 mojom::blink::WebBluetoothGATTQueryQuantity quantity,
521 const String& descriptor) {
522 #if OS(MACOSX)
523 // TODO(crbug.com/624017): Remove when descriptors are implemented on MacOS.
524 return ScriptPromise::rejectWithDOMException(
525 scriptState, DOMException::create(NotSupportedError,
526 "getDescriptor[s] is not implemented "
527 "yet. See https://goo.gl/J6ASzs"));
528 #endif // OS(MACOSX)
529 WebBluetooth* webbluetooth =
530 BluetoothSupplement::fromScriptState(scriptState);
531
532 if (!gatt()->connected()) {
533 return ScriptPromise::rejectWithDOMException(
534 scriptState,
535 DOMException::create(NetworkError, kGATTServerNotConnected));
536 }
537
538 if (!gatt()->device()->isValidCharacteristic(
539 m_webCharacteristic->characteristicInstanceID)) {
540 return ScriptPromise::rejectWithDOMException(
541 scriptState,
542 DOMException::create(InvalidStateError, kInvalidCharacteristic));
543 }
544
545 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
546 ScriptPromise promise = resolver->promise();
547
548 webbluetooth->getDescriptors(
549 m_webCharacteristic->characteristicInstanceID,
550 static_cast<int32_t>(quantity), descriptor,
551 new GetDescriptorsCallback(this, quantity, resolver));
552
553 return promise;
554 }
555
401 DEFINE_TRACE(BluetoothRemoteGATTCharacteristic) { 556 DEFINE_TRACE(BluetoothRemoteGATTCharacteristic) {
402 visitor->trace(m_service); 557 visitor->trace(m_service);
403 visitor->trace(m_properties); 558 visitor->trace(m_properties);
404 visitor->trace(m_value); 559 visitor->trace(m_value);
405 EventTargetWithInlineData::trace(visitor); 560 EventTargetWithInlineData::trace(visitor);
406 ActiveDOMObject::trace(visitor); 561 ActiveDOMObject::trace(visitor);
407 } 562 }
408 563
409 } // namespace blink 564 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698