Chromium Code Reviews| 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(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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |