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

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

Issue 2466223002: Implement WebBluetooth getDescriptor[s] (Closed)
Patch Set: Rebase 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());
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()->activeDOMObjectsAreStopped())
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));
ortuno 2016/12/02 06:14:51 I like that we can test all of the characteristic'
dougt 2016/12/02 18:31:29 If anything, a possible spec bug? I am not really
ortuno 2016/12/07 08:05:12 hmm then we should change the message since this i
ortuno 2016/12/08 05:42:51 As discussed offline, I think it's fine to use the
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));
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()->activeDOMObjectsAreStopped())
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::getDescriptorsImpl(
ortuno 2016/12/02 06:14:51 nit: Order of declaration should match order of im
dougt 2016/12/02 18:31:29 Done.
202 ScriptState* scriptState,
203 mojom::blink::WebBluetoothGATTQueryQuantity quantity,
204 const String& descriptor) {
205 #if OS(MACOSX)
206 // TODO(ortuno): Remove when getDescriptor[s] is implemented.
ortuno 2016/12/02 06:14:51 nit: TODO(crbug.com/624017): Remove when descripto
dougt 2016/12/02 18:31:29 Done.
207 return ScriptPromise::rejectWithDOMException(
208 scriptState, DOMException::create(NotSupportedError,
209 "getDescriptor[s] is not implemented "
210 "yet. See https://goo.gl/J6ASzs"));
211 #endif // OS(MACOSX)
212 WebBluetooth* webbluetooth =
213 BluetoothSupplement::fromScriptState(scriptState);
214
215 if (!gatt()->connected()) {
216 return ScriptPromise::rejectWithDOMException(
217 scriptState,
218 DOMException::create(NetworkError, kGATTServerNotConnected));
219 }
220
221 if (!gatt()->device()->isValidCharacteristic(
222 m_webCharacteristic->characteristicInstanceID)) {
223 return ScriptPromise::rejectWithDOMException(
224 scriptState,
225 DOMException::create(InvalidStateError, kInvalidCharacteristic));
226 }
227
228 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
229 ScriptPromise promise = resolver->promise();
230
231 webbluetooth->getDescriptors(
232 m_webCharacteristic->characteristicInstanceID,
233 static_cast<int32_t>(quantity), descriptor,
234 new GetDescriptorsCallback(this, quantity, resolver));
235
236 return promise;
237 }
238
239 ScriptPromise BluetoothRemoteGATTCharacteristic::getDescriptor(
240 ScriptState* scriptState,
241 const StringOrUnsignedLong& descriptorUUID,
242 ExceptionState& exceptionState) {
243 String descriptor =
244 BluetoothUUID::getDescriptor(descriptorUUID, exceptionState);
245 if (exceptionState.hadException())
246 return exceptionState.reject(scriptState);
247
248 return getDescriptorsImpl(scriptState,
249 mojom::blink::WebBluetoothGATTQueryQuantity::SINGLE,
250 descriptor);
251 }
252
253 ScriptPromise BluetoothRemoteGATTCharacteristic::getDescriptors(
254 ScriptState* scriptState,
255 ExceptionState&) {
256 return getDescriptorsImpl(
257 scriptState, mojom::blink::WebBluetoothGATTQueryQuantity::MULTIPLE);
258 }
259
260 ScriptPromise BluetoothRemoteGATTCharacteristic::getDescriptors(
261 ScriptState* scriptState,
262 const StringOrUnsignedLong& descriptorUUID,
263 ExceptionState& exceptionState) {
264 String descriptor =
265 BluetoothUUID::getDescriptor(descriptorUUID, exceptionState);
266 if (exceptionState.hadException())
267 return exceptionState.reject(scriptState);
268
269 return getDescriptorsImpl(
270 scriptState, mojom::blink::WebBluetoothGATTQueryQuantity::MULTIPLE,
271 descriptor);
272 }
273
274 class CharacteristicReadValueCallback : public WebBluetoothReadValueCallbacks {
275 public:
276 CharacteristicReadValueCallback(
277 BluetoothRemoteGATTCharacteristic* characteristic,
278 ScriptPromiseResolver* resolver)
127 : m_characteristic(characteristic), m_resolver(resolver) { 279 : m_characteristic(characteristic), m_resolver(resolver) {
128 // We always check that the device is connected before constructing this 280 // We always check that the device is connected before constructing this
129 // object. 281 // object.
130 CHECK(m_characteristic->gatt()->connected()); 282 CHECK(m_characteristic->gatt()->connected());
131 m_characteristic->gatt()->AddToActiveAlgorithms(m_resolver.get()); 283 m_characteristic->gatt()->AddToActiveAlgorithms(m_resolver.get());
132 } 284 }
133 285
134 void onSuccess(const WebVector<uint8_t>& value) override { 286 void onSuccess(const WebVector<uint8_t>& value) override {
135 if (!m_resolver->getExecutionContext() || 287 if (!m_resolver->getExecutionContext() ||
136 m_resolver->getExecutionContext()->activeDOMObjectsAreStopped()) 288 m_resolver->getExecutionContext()->activeDOMObjectsAreStopped())
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 return ScriptPromise::rejectWithDOMException( 338 return ScriptPromise::rejectWithDOMException(
187 scriptState, 339 scriptState,
188 DOMException::create(InvalidStateError, kInvalidCharacteristic)); 340 DOMException::create(InvalidStateError, kInvalidCharacteristic));
189 } 341 }
190 342
191 WebBluetooth* webbluetooth = 343 WebBluetooth* webbluetooth =
192 BluetoothSupplement::fromScriptState(scriptState); 344 BluetoothSupplement::fromScriptState(scriptState);
193 345
194 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); 346 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
195 ScriptPromise promise = resolver->promise(); 347 ScriptPromise promise = resolver->promise();
196 webbluetooth->readValue(m_webCharacteristic->characteristicInstanceID, 348 webbluetooth->characteristicReadValue(
197 new ReadValueCallback(this, resolver)); 349 m_webCharacteristic->characteristicInstanceID,
350 new CharacteristicReadValueCallback(this, resolver));
198 351
199 return promise; 352 return promise;
200 } 353 }
201 354
202 class WriteValueCallback : public WebBluetoothWriteValueCallbacks { 355 class CharacteristicWriteValueCallback
356 : public WebBluetoothWriteValueCallbacks {
203 public: 357 public:
204 WriteValueCallback(BluetoothRemoteGATTCharacteristic* characteristic, 358 CharacteristicWriteValueCallback(
205 ScriptPromiseResolver* resolver) 359 BluetoothRemoteGATTCharacteristic* characteristic,
360 ScriptPromiseResolver* resolver)
206 : m_characteristic(characteristic), m_resolver(resolver) { 361 : m_characteristic(characteristic), m_resolver(resolver) {
207 // We always check that the device is connected before constructing this 362 // We always check that the device is connected before constructing this
208 // object. 363 // object.
209 CHECK(m_characteristic->gatt()->connected()); 364 CHECK(m_characteristic->gatt()->connected());
210 m_characteristic->gatt()->AddToActiveAlgorithms(m_resolver.get()); 365 m_characteristic->gatt()->AddToActiveAlgorithms(m_resolver.get());
211 } 366 }
212 367
213 void onSuccess(const WebVector<uint8_t>& value) override { 368 void onSuccess(const WebVector<uint8_t>& value) override {
214 if (!m_resolver->getExecutionContext() || 369 if (!m_resolver->getExecutionContext() ||
215 m_resolver->getExecutionContext()->activeDOMObjectsAreStopped()) 370 m_resolver->getExecutionContext()->activeDOMObjectsAreStopped())
(...skipping 12 matching lines...) Expand all
228 m_resolver->resolve(); 383 m_resolver->resolve();
229 } 384 }
230 385
231 void onError( 386 void onError(
232 int32_t 387 int32_t
233 error /* Corresponds to WebBluetoothResult in web_bluetooth.mojom */) 388 error /* Corresponds to WebBluetoothResult in web_bluetooth.mojom */)
234 override { 389 override {
235 if (!m_resolver->getExecutionContext() || 390 if (!m_resolver->getExecutionContext() ||
236 m_resolver->getExecutionContext()->activeDOMObjectsAreStopped()) 391 m_resolver->getExecutionContext()->activeDOMObjectsAreStopped())
237 return; 392 return;
238
239 if (!m_characteristic->gatt()->RemoveFromActiveAlgorithms( 393 if (!m_characteristic->gatt()->RemoveFromActiveAlgorithms(
240 m_resolver.get())) { 394 m_resolver.get())) {
241 m_resolver->reject( 395 m_resolver->reject(
242 DOMException::create(NetworkError, kGATTServerDisconnected)); 396 DOMException::create(NetworkError, kGATTServerDisconnected));
243 return; 397 return;
244 } 398 }
245 399
246 m_resolver->reject(BluetoothError::take(m_resolver, error)); 400 m_resolver->reject(BluetoothError::take(m_resolver, error));
247 } 401 }
248 402
(...skipping 30 matching lines...) Expand all
279 return ScriptPromise::rejectWithDOMException( 433 return ScriptPromise::rejectWithDOMException(
280 scriptState, DOMException::create(InvalidModificationError, 434 scriptState, DOMException::create(InvalidModificationError,
281 "Value can't exceed 512 bytes.")); 435 "Value can't exceed 512 bytes."));
282 436
283 // Let valueVector be a copy of the bytes held by value. 437 // Let valueVector be a copy of the bytes held by value.
284 WebVector<uint8_t> valueVector(value.bytes(), value.byteLength()); 438 WebVector<uint8_t> valueVector(value.bytes(), value.byteLength());
285 439
286 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); 440 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
287 441
288 ScriptPromise promise = resolver->promise(); 442 ScriptPromise promise = resolver->promise();
289 webbluetooth->writeValue(m_webCharacteristic->characteristicInstanceID, 443 webbluetooth->characteristicWriteValue(
290 valueVector, new WriteValueCallback(this, resolver)); 444 m_webCharacteristic->characteristicInstanceID, valueVector,
445 new CharacteristicWriteValueCallback(this, resolver));
291 446
292 return promise; 447 return promise;
293 } 448 }
294 449
295 class NotificationsCallback : public WebBluetoothNotificationsCallbacks { 450 class NotificationsCallback : public WebBluetoothNotificationsCallbacks {
296 public: 451 public:
297 NotificationsCallback(BluetoothRemoteGATTCharacteristic* characteristic, 452 NotificationsCallback(BluetoothRemoteGATTCharacteristic* characteristic,
298 ScriptPromiseResolver* resolver) 453 ScriptPromiseResolver* resolver)
299 : m_characteristic(characteristic), m_resolver(resolver) { 454 : m_characteristic(characteristic), m_resolver(resolver) {
300 // We always check that the device is connected before constructing this 455 // We always check that the device is connected before constructing this
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 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