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

Unified Diff: third_party/WebKit/Source/modules/bluetooth/BluetoothRemoteGATTDescriptor.cpp

Issue 2466223002: Implement WebBluetooth getDescriptor[s] (Closed)
Patch Set: Addressing code review comments from ortuno (still working on test changes) Created 4 years, 1 month 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/modules/bluetooth/BluetoothRemoteGATTDescriptor.cpp
diff --git a/third_party/WebKit/Source/modules/bluetooth/BluetoothRemoteGATTDescriptor.cpp b/third_party/WebKit/Source/modules/bluetooth/BluetoothRemoteGATTDescriptor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ddbfe71ee31d80a608ed0632631d41b08d412d70
--- /dev/null
+++ b/third_party/WebKit/Source/modules/bluetooth/BluetoothRemoteGATTDescriptor.cpp
@@ -0,0 +1,201 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "modules/bluetooth/BluetoothRemoteGATTDescriptor.h"
+
+#include "bindings/core/v8/CallbackPromiseAdapter.h"
+#include "bindings/core/v8/ScriptPromise.h"
+#include "bindings/core/v8/ScriptPromiseResolver.h"
+#include "core/dom/DOMDataView.h"
+#include "core/dom/DOMException.h"
+#include "core/dom/ExceptionCode.h"
+#include "core/events/Event.h"
+#include "core/inspector/ConsoleMessage.h"
+#include "modules/bluetooth/BluetoothError.h"
+#include "modules/bluetooth/BluetoothRemoteGATTService.h"
+#include "modules/bluetooth/BluetoothSupplement.h"
+#include "public/platform/modules/bluetooth/WebBluetooth.h"
+#include <memory>
+
+namespace blink {
+
+namespace {
+const char kGATTServerDisconnected[] =
+ "GATT Server disconnected while performing a GATT operation.";
+const char kGATTServerNotConnected[] =
+ "GATT Server is disconnected. Cannot perform GATT operations.";
+
+DOMDataView* ConvertWebVectorToDataView(const WebVector<uint8_t>& webVector) {
+ static_assert(sizeof(*webVector.data()) == 1,
+ "uint8_t should be a single byte");
+ DOMArrayBuffer* domBuffer =
+ DOMArrayBuffer::create(webVector.data(), webVector.size());
+ return DOMDataView::create(domBuffer, 0, webVector.size());
+}
+
+} // anonymous namespace
+
+BluetoothRemoteGATTDescriptor::BluetoothRemoteGATTDescriptor(
+ std::unique_ptr<WebBluetoothRemoteGATTDescriptorInit> webDescriptor,
+ BluetoothRemoteGATTCharacteristic* characteristic)
+ : m_webDescriptor(std::move(webDescriptor)),
+ m_characteristic(characteristic) {}
+
+BluetoothRemoteGATTDescriptor* BluetoothRemoteGATTDescriptor::take(
+ std::unique_ptr<WebBluetoothRemoteGATTDescriptorInit> webDescriptor,
+ BluetoothRemoteGATTCharacteristic* characteristic) {
+ if (!webDescriptor) {
+ return nullptr;
+ }
+ BluetoothRemoteGATTDescriptor* descriptor = new BluetoothRemoteGATTDescriptor(
+ std::move(webDescriptor), characteristic);
+ return descriptor;
+}
+
+void BluetoothRemoteGATTDescriptor::setValue(DOMDataView* domDataView) {
+ m_value = domDataView;
+}
+
+class DescriptorReadValueCallback : public WebBluetoothReadValueCallbacks {
+ public:
+ DescriptorReadValueCallback(BluetoothRemoteGATTDescriptor* descriptor,
+ ScriptPromiseResolver* resolver)
+ : m_descriptor(descriptor), m_resolver(resolver) {
+ // We always check that the device is connected before constructing this
+ // object.
+ CHECK(m_descriptor->getGatt()->connected());
+ m_descriptor->getGatt()->AddToActiveAlgorithms(m_resolver.get());
+ }
+
+ void onSuccess(const WebVector<uint8_t>& value) override {
+ if (!m_resolver->getExecutionContext() ||
+ m_resolver->getExecutionContext()->activeDOMObjectsAreStopped())
+ return;
+
+ if (!m_descriptor->getGatt()->RemoveFromActiveAlgorithms(
+ m_resolver.get())) {
+ m_resolver->reject(
+ DOMException::create(NetworkError, kGATTServerDisconnected));
+ return;
+ }
+
+ DOMDataView* domDataView = ConvertWebVectorToDataView(value);
+ if (m_descriptor)
+ m_descriptor->setValue(domDataView);
+
+ m_resolver->resolve(domDataView);
+ }
+
+ void onError(
+ int32_t
+ error /* Corresponds to WebBluetoothResult in web_bluetooth.mojom */)
+ override {
+ if (!m_resolver->getExecutionContext() ||
+ m_resolver->getExecutionContext()->activeDOMObjectsAreStopped())
+ return;
+
+ if (!m_descriptor->getGatt()->RemoveFromActiveAlgorithms(
+ m_resolver.get())) {
+ m_resolver->reject(
+ DOMException::create(NetworkError, kGATTServerDisconnected));
+ return;
+ }
+
+ m_resolver->reject(BluetoothError::take(m_resolver, error));
+ }
+
+ private:
+ WeakPersistent<BluetoothRemoteGATTDescriptor> m_descriptor;
+ Persistent<ScriptPromiseResolver> m_resolver;
+};
+
+ScriptPromise BluetoothRemoteGATTDescriptor::readValue(
+ ScriptState* scriptState) {
+ if (!getGatt()->connected()) {
+ return ScriptPromise::rejectWithDOMException(
+ scriptState,
+ DOMException::create(NetworkError, kGATTServerNotConnected));
+ }
+
+ WebBluetooth* webbluetooth =
+ BluetoothSupplement::fromScriptState(scriptState);
+
+ ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
+ ScriptPromise promise = resolver->promise();
+
+ webbluetooth->descriptorReadValue(
+ m_webDescriptor->descriptorInstanceID,
+ new DescriptorReadValueCallback(this, resolver));
+ return promise;
+}
+
+class DescriptorWriteValueCallback : public WebBluetoothWriteValueCallbacks {
+ public:
+ DescriptorWriteValueCallback(BluetoothRemoteGATTDescriptor* descriptor,
+ ScriptPromiseResolver* resolver)
+ : m_webDescriptor(descriptor), m_resolver(resolver) {}
+
+ void onSuccess(const WebVector<uint8_t>& value) override {
+ if (!m_resolver->getExecutionContext() ||
+ m_resolver->getExecutionContext()->activeDOMObjectsAreStopped())
+ return;
+
+ if (m_webDescriptor) {
+ m_webDescriptor->setValue(ConvertWebVectorToDataView(value));
+ }
+ m_resolver->resolve();
+ }
+
+ void onError(
+ int32_t
+ error /* Corresponds to WebBluetoothResult in web_bluetooth.mojom */)
+ override {
+ if (!m_resolver->getExecutionContext() ||
+ m_resolver->getExecutionContext()->activeDOMObjectsAreStopped())
+ return;
+ m_resolver->reject(BluetoothError::take(m_resolver, error));
+ }
+
+ private:
+ WeakPersistent<BluetoothRemoteGATTDescriptor> m_webDescriptor;
+ Persistent<ScriptPromiseResolver> m_resolver;
+};
+
+ScriptPromise BluetoothRemoteGATTDescriptor::writeValue(
+ ScriptState* scriptState,
+ const DOMArrayPiece& value) {
+ WebBluetooth* webbluetooth =
+ BluetoothSupplement::fromScriptState(scriptState);
+
+ // Partial implementation of writeValue algorithm:
+ // https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetoothgattdescriptor-writevalue
+
+ // If bytes is more than 512 bytes long (the maximum length of an attribute
+ // value, per Long Attribute Values) return a promise rejected with an
+ // InvalidModificationError and abort.
+ if (value.byteLength() > 512) {
+ return ScriptPromise::rejectWithDOMException(
+ scriptState, DOMException::create(InvalidModificationError,
+ "Value can't exceed 512 bytes."));
+ }
+
+ // Let valueVector be a copy of the bytes held by value.
+ WebVector<uint8_t> valueVector(value.bytes(), value.byteLength());
+
+ ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
+
+ ScriptPromise promise = resolver->promise();
+ webbluetooth->descriptorWriteValue(
+ m_webDescriptor->descriptorInstanceID, valueVector,
+ new DescriptorWriteValueCallback(this, resolver));
+
+ return promise;
+}
+
+DEFINE_TRACE(BluetoothRemoteGATTDescriptor) {
+ visitor->trace(m_characteristic);
+ visitor->trace(m_value);
+}
+
+} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698