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

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

Issue 2466223002: Implement WebBluetooth getDescriptor[s] (Closed)
Patch Set: Remove macos restriction 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 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 // We will also need to unregister a characteristic once all the event 113 // We will also need to unregister a characteristic once all the event
112 // listeners have been removed. See http://crbug.com/541390 114 // listeners have been removed. See http://crbug.com/541390
113 if (eventType == EventTypeNames::characteristicvaluechanged) { 115 if (eventType == EventTypeNames::characteristicvaluechanged) {
114 WebBluetooth* webbluetooth = 116 WebBluetooth* webbluetooth =
115 BluetoothSupplement::fromExecutionContext(getExecutionContext()); 117 BluetoothSupplement::fromExecutionContext(getExecutionContext());
116 webbluetooth->registerCharacteristicObject( 118 webbluetooth->registerCharacteristicObject(
117 m_webCharacteristic->characteristicInstanceID, this); 119 m_webCharacteristic->characteristicInstanceID, this);
118 } 120 }
119 } 121 }
120 122
121 class ReadValueCallback : public WebBluetoothReadValueCallbacks { 123 class GetDescriptorsCallback : public WebBluetoothGetDescriptorsCallbacks {
122 public: 124 public:
123 ReadValueCallback(BluetoothRemoteGATTCharacteristic* characteristic, 125 GetDescriptorsCallback(BluetoothRemoteGATTCharacteristic* characteristic,
124 ScriptPromiseResolver* resolver) 126 mojom::blink::WebBluetoothGATTQueryQuantity quantity,
127 ScriptPromiseResolver* resolver)
128 : m_characteristic(characteristic),
129 m_quantity(quantity),
130 m_resolver(resolver) {
131 // We always check that the device is connected before constructing this
132 // object.
133 CHECK(m_characteristic->gatt()->connected());
134 m_characteristic->gatt()->AddToActiveAlgorithms(m_resolver.get());
135 }
136
137 void onSuccess(const WebVector<WebBluetoothRemoteGATTDescriptorInit*>&
138 webDescriptors) override {
139 if (!m_resolver->getExecutionContext() ||
140 m_resolver->getExecutionContext()->isContextDestroyed())
141 return;
142
143 // If the resolver is not in the set of ActiveAlgorithms then the frame
144 // disconnected so we reject.
145 if (!m_characteristic->gatt()->RemoveFromActiveAlgorithms(
146 m_resolver.get())) {
147 m_resolver->reject(
148 DOMException::create(NetworkError, kGATTServerDisconnected));
149 return;
150 }
151
152 if (m_quantity == mojom::blink::WebBluetoothGATTQueryQuantity::SINGLE) {
153 DCHECK_EQ(1u, webDescriptors.size());
154 m_resolver->resolve(
155 m_characteristic->gatt()
156 ->device()
157 ->getOrCreateBluetoothRemoteGATTDescriptor(
158 WTF::wrapUnique(webDescriptors[0]), m_characteristic));
159 return;
160 }
161
162 HeapVector<Member<BluetoothRemoteGATTDescriptor>> descriptors;
163 descriptors.reserveInitialCapacity(webDescriptors.size());
164 for (WebBluetoothRemoteGATTDescriptorInit* webDescriptor : webDescriptors) {
165 descriptors.append(m_characteristic->gatt()
166 ->device()
167 ->getOrCreateBluetoothRemoteGATTDescriptor(
168 WTF::wrapUnique(webDescriptor), m_characteristi c));
169 }
170 m_resolver->resolve(descriptors);
171 }
172
173 void onError(
174 int32_t
175 error /* Corresponds to WebBluetoothResult in web_bluetooth.mojom */)
176 override {
177 if (!m_resolver->getExecutionContext() ||
178 m_resolver->getExecutionContext()->isContextDestroyed())
179 return;
180
181 // If the resolver is not in the set of ActiveAlgorithms then the frame
182 // disconnected so we reject.
183 if (!m_characteristic->gatt()->RemoveFromActiveAlgorithms(
184 m_resolver.get())) {
185 m_resolver->reject(
186 DOMException::create(NetworkError, kGATTServerDisconnected));
187 return;
188 }
189
190 m_resolver->reject(BluetoothError::take(m_resolver, error));
191 }
192
193 private:
194 Persistent<BluetoothRemoteGATTCharacteristic> m_characteristic;
195 mojom::blink::WebBluetoothGATTQueryQuantity m_quantity;
196 const Persistent<ScriptPromiseResolver> m_resolver;
197 };
198
199 ScriptPromise BluetoothRemoteGATTCharacteristic::getDescriptor(
200 ScriptState* scriptState,
201 const StringOrUnsignedLong& descriptorUUID,
202 ExceptionState& exceptionState) {
203 String descriptor =
204 BluetoothUUID::getDescriptor(descriptorUUID, exceptionState);
205 if (exceptionState.hadException())
206 return exceptionState.reject(scriptState);
207
208 return getDescriptorsImpl(scriptState,
209 mojom::blink::WebBluetoothGATTQueryQuantity::SINGLE,
210 descriptor);
211 }
212
213 ScriptPromise BluetoothRemoteGATTCharacteristic::getDescriptors(
214 ScriptState* scriptState,
215 ExceptionState&) {
216 return getDescriptorsImpl(
217 scriptState, mojom::blink::WebBluetoothGATTQueryQuantity::MULTIPLE);
218 }
219
220 ScriptPromise BluetoothRemoteGATTCharacteristic::getDescriptors(
221 ScriptState* scriptState,
222 const StringOrUnsignedLong& descriptorUUID,
223 ExceptionState& exceptionState) {
224 String descriptor =
225 BluetoothUUID::getDescriptor(descriptorUUID, exceptionState);
226 if (exceptionState.hadException())
227 return exceptionState.reject(scriptState);
228
229 return getDescriptorsImpl(
230 scriptState, mojom::blink::WebBluetoothGATTQueryQuantity::MULTIPLE,
231 descriptor);
232 }
233
234 class CharacteristicReadValueCallback : public WebBluetoothReadValueCallbacks {
235 public:
236 CharacteristicReadValueCallback(
237 BluetoothRemoteGATTCharacteristic* characteristic,
238 ScriptPromiseResolver* resolver)
125 : m_characteristic(characteristic), m_resolver(resolver) { 239 : m_characteristic(characteristic), m_resolver(resolver) {
126 // We always check that the device is connected before constructing this 240 // We always check that the device is connected before constructing this
127 // object. 241 // object.
128 CHECK(m_characteristic->gatt()->connected()); 242 CHECK(m_characteristic->gatt()->connected());
129 m_characteristic->gatt()->AddToActiveAlgorithms(m_resolver.get()); 243 m_characteristic->gatt()->AddToActiveAlgorithms(m_resolver.get());
130 } 244 }
131 245
132 void onSuccess(const WebVector<uint8_t>& value) override { 246 void onSuccess(const WebVector<uint8_t>& value) override {
133 if (!m_resolver->getExecutionContext() || 247 if (!m_resolver->getExecutionContext() ||
134 m_resolver->getExecutionContext()->isContextDestroyed()) 248 m_resolver->getExecutionContext()->isContextDestroyed())
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 return ScriptPromise::rejectWithDOMException( 298 return ScriptPromise::rejectWithDOMException(
185 scriptState, 299 scriptState,
186 DOMException::create(InvalidStateError, kInvalidCharacteristic)); 300 DOMException::create(InvalidStateError, kInvalidCharacteristic));
187 } 301 }
188 302
189 WebBluetooth* webbluetooth = 303 WebBluetooth* webbluetooth =
190 BluetoothSupplement::fromScriptState(scriptState); 304 BluetoothSupplement::fromScriptState(scriptState);
191 305
192 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); 306 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
193 ScriptPromise promise = resolver->promise(); 307 ScriptPromise promise = resolver->promise();
194 webbluetooth->readValue(m_webCharacteristic->characteristicInstanceID, 308 webbluetooth->characteristicReadValue(
195 new ReadValueCallback(this, resolver)); 309 m_webCharacteristic->characteristicInstanceID,
310 new CharacteristicReadValueCallback(this, resolver));
196 311
197 return promise; 312 return promise;
198 } 313 }
199 314
200 class WriteValueCallback : public WebBluetoothWriteValueCallbacks { 315 class CharacteristicWriteValueCallback
316 : public WebBluetoothWriteValueCallbacks {
201 public: 317 public:
202 WriteValueCallback(BluetoothRemoteGATTCharacteristic* characteristic, 318 CharacteristicWriteValueCallback(
203 ScriptPromiseResolver* resolver) 319 BluetoothRemoteGATTCharacteristic* characteristic,
320 ScriptPromiseResolver* resolver)
204 : m_characteristic(characteristic), m_resolver(resolver) { 321 : m_characteristic(characteristic), m_resolver(resolver) {
205 // We always check that the device is connected before constructing this 322 // We always check that the device is connected before constructing this
206 // object. 323 // object.
207 CHECK(m_characteristic->gatt()->connected()); 324 CHECK(m_characteristic->gatt()->connected());
208 m_characteristic->gatt()->AddToActiveAlgorithms(m_resolver.get()); 325 m_characteristic->gatt()->AddToActiveAlgorithms(m_resolver.get());
209 } 326 }
210 327
211 void onSuccess(const WebVector<uint8_t>& value) override { 328 void onSuccess(const WebVector<uint8_t>& value) override {
212 if (!m_resolver->getExecutionContext() || 329 if (!m_resolver->getExecutionContext() ||
213 m_resolver->getExecutionContext()->isContextDestroyed()) 330 m_resolver->getExecutionContext()->isContextDestroyed())
(...skipping 12 matching lines...) Expand all
226 m_resolver->resolve(); 343 m_resolver->resolve();
227 } 344 }
228 345
229 void onError( 346 void onError(
230 int32_t 347 int32_t
231 error /* Corresponds to WebBluetoothResult in web_bluetooth.mojom */) 348 error /* Corresponds to WebBluetoothResult in web_bluetooth.mojom */)
232 override { 349 override {
233 if (!m_resolver->getExecutionContext() || 350 if (!m_resolver->getExecutionContext() ||
234 m_resolver->getExecutionContext()->isContextDestroyed()) 351 m_resolver->getExecutionContext()->isContextDestroyed())
235 return; 352 return;
236
237 if (!m_characteristic->gatt()->RemoveFromActiveAlgorithms( 353 if (!m_characteristic->gatt()->RemoveFromActiveAlgorithms(
238 m_resolver.get())) { 354 m_resolver.get())) {
239 m_resolver->reject( 355 m_resolver->reject(
240 DOMException::create(NetworkError, kGATTServerDisconnected)); 356 DOMException::create(NetworkError, kGATTServerDisconnected));
241 return; 357 return;
242 } 358 }
243 359
244 m_resolver->reject(BluetoothError::take(m_resolver, error)); 360 m_resolver->reject(BluetoothError::take(m_resolver, error));
245 } 361 }
246 362
(...skipping 30 matching lines...) Expand all
277 return ScriptPromise::rejectWithDOMException( 393 return ScriptPromise::rejectWithDOMException(
278 scriptState, DOMException::create(InvalidModificationError, 394 scriptState, DOMException::create(InvalidModificationError,
279 "Value can't exceed 512 bytes.")); 395 "Value can't exceed 512 bytes."));
280 396
281 // Let valueVector be a copy of the bytes held by value. 397 // Let valueVector be a copy of the bytes held by value.
282 WebVector<uint8_t> valueVector(value.bytes(), value.byteLength()); 398 WebVector<uint8_t> valueVector(value.bytes(), value.byteLength());
283 399
284 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); 400 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
285 401
286 ScriptPromise promise = resolver->promise(); 402 ScriptPromise promise = resolver->promise();
287 webbluetooth->writeValue(m_webCharacteristic->characteristicInstanceID, 403 webbluetooth->characteristicWriteValue(
288 valueVector, new WriteValueCallback(this, resolver)); 404 m_webCharacteristic->characteristicInstanceID, valueVector,
405 new CharacteristicWriteValueCallback(this, resolver));
289 406
290 return promise; 407 return promise;
291 } 408 }
292 409
293 class NotificationsCallback : public WebBluetoothNotificationsCallbacks { 410 class NotificationsCallback : public WebBluetoothNotificationsCallbacks {
294 public: 411 public:
295 NotificationsCallback(BluetoothRemoteGATTCharacteristic* characteristic, 412 NotificationsCallback(BluetoothRemoteGATTCharacteristic* characteristic,
296 ScriptPromiseResolver* resolver) 413 ScriptPromiseResolver* resolver)
297 : m_characteristic(characteristic), m_resolver(resolver) { 414 : m_characteristic(characteristic), m_resolver(resolver) {
298 // We always check that the device is connected before constructing this 415 // We always check that the device is connected before constructing this
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 498
382 WebBluetooth* webbluetooth = 499 WebBluetooth* webbluetooth =
383 BluetoothSupplement::fromScriptState(scriptState); 500 BluetoothSupplement::fromScriptState(scriptState);
384 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); 501 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
385 ScriptPromise promise = resolver->promise(); 502 ScriptPromise promise = resolver->promise();
386 webbluetooth->stopNotifications(m_webCharacteristic->characteristicInstanceID, 503 webbluetooth->stopNotifications(m_webCharacteristic->characteristicInstanceID,
387 new NotificationsCallback(this, resolver)); 504 new NotificationsCallback(this, resolver));
388 return promise; 505 return promise;
389 } 506 }
390 507
508 ScriptPromise BluetoothRemoteGATTCharacteristic::getDescriptorsImpl(
509 ScriptState* scriptState,
510 mojom::blink::WebBluetoothGATTQueryQuantity quantity,
511 const String& descriptor) {
512 WebBluetooth* webbluetooth =
513 BluetoothSupplement::fromScriptState(scriptState);
514
515 if (!gatt()->connected()) {
516 return ScriptPromise::rejectWithDOMException(
517 scriptState,
518 DOMException::create(NetworkError, kGATTServerNotConnected));
519 }
520
521 if (!gatt()->device()->isValidCharacteristic(
522 m_webCharacteristic->characteristicInstanceID)) {
523 return ScriptPromise::rejectWithDOMException(
524 scriptState,
525 DOMException::create(InvalidStateError, kInvalidCharacteristic));
526 }
527
528 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
529 ScriptPromise promise = resolver->promise();
530
531 webbluetooth->getDescriptors(
532 m_webCharacteristic->characteristicInstanceID,
533 static_cast<int32_t>(quantity), descriptor,
534 new GetDescriptorsCallback(this, quantity, resolver));
535
536 return promise;
537 }
538
391 DEFINE_TRACE(BluetoothRemoteGATTCharacteristic) { 539 DEFINE_TRACE(BluetoothRemoteGATTCharacteristic) {
392 visitor->trace(m_service); 540 visitor->trace(m_service);
393 visitor->trace(m_properties); 541 visitor->trace(m_properties);
394 visitor->trace(m_value); 542 visitor->trace(m_value);
395 EventTargetWithInlineData::trace(visitor); 543 EventTargetWithInlineData::trace(visitor);
396 SuspendableObject::trace(visitor); 544 SuspendableObject::trace(visitor);
397 } 545 }
398 546
399 } // namespace blink 547 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698