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

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

Issue 2466223002: Implement WebBluetooth getDescriptor[s] (Closed)
Patch Set: Addressing code review comments from ortuno (still working on test changes) 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(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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698