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/BluetoothRemoteGATTServer.h" | 5 #include "modules/bluetooth/BluetoothRemoteGATTServer.h" |
6 | 6 |
7 #include "bindings/core/v8/CallbackPromiseAdapter.h" | 7 #include "bindings/core/v8/CallbackPromiseAdapter.h" |
8 #include "bindings/core/v8/ScriptPromise.h" | 8 #include "bindings/core/v8/ScriptPromise.h" |
9 #include "bindings/core/v8/ScriptPromiseResolver.h" | 9 #include "bindings/core/v8/ScriptPromiseResolver.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 "modules/bluetooth/BluetoothError.h" | 13 #include "modules/bluetooth/BluetoothError.h" |
14 #include "modules/bluetooth/BluetoothRemoteGATTService.h" | 14 #include "modules/bluetooth/BluetoothRemoteGATTService.h" |
15 #include "modules/bluetooth/BluetoothSupplement.h" | 15 #include "modules/bluetooth/BluetoothSupplement.h" |
16 #include "modules/bluetooth/BluetoothUUID.h" | 16 #include "modules/bluetooth/BluetoothUUID.h" |
17 #include "public/platform/modules/bluetooth/WebBluetooth.h" | 17 #include "public/platform/modules/bluetooth/WebBluetooth.h" |
18 | 18 |
19 namespace blink { | 19 namespace blink { |
20 | 20 |
| 21 namespace { |
| 22 |
| 23 const char kGATTServerDisconnected[] = "GATT Server disconnected while retrievin
g services."; |
| 24 const char kGATTServerNotConnected[] = "GATT Server is disconnected. Cannot retr
ieve services."; |
| 25 |
| 26 } |
| 27 |
21 BluetoothRemoteGATTServer::BluetoothRemoteGATTServer(BluetoothDevice* device) | 28 BluetoothRemoteGATTServer::BluetoothRemoteGATTServer(BluetoothDevice* device) |
22 : m_device(device) | 29 : m_device(device) |
23 , m_connected(false) | 30 , m_connected(false) |
24 { | 31 { |
25 } | 32 } |
26 | 33 |
27 BluetoothRemoteGATTServer* BluetoothRemoteGATTServer::create(BluetoothDevice* de
vice) | 34 BluetoothRemoteGATTServer* BluetoothRemoteGATTServer::create(BluetoothDevice* de
vice) |
28 { | 35 { |
29 return new BluetoothRemoteGATTServer(device); | 36 return new BluetoothRemoteGATTServer(device); |
30 } | 37 } |
31 | 38 |
| 39 void BluetoothRemoteGATTServer::AddToActiveAlgorithms(ScriptPromiseResolver* res
olver) |
| 40 { |
| 41 auto result = m_activeAlgorithms.add(resolver); |
| 42 CHECK(result.isNewEntry); |
| 43 } |
| 44 |
| 45 bool BluetoothRemoteGATTServer::RemoveFromActiveAlgorithms(ScriptPromiseResolver
* resolver) |
| 46 { |
| 47 if (!m_activeAlgorithms.contains(resolver)) { |
| 48 return false; |
| 49 } |
| 50 m_activeAlgorithms.remove(resolver); |
| 51 return true; |
| 52 } |
| 53 |
32 DEFINE_TRACE(BluetoothRemoteGATTServer) | 54 DEFINE_TRACE(BluetoothRemoteGATTServer) |
33 { | 55 { |
| 56 visitor->trace(m_activeAlgorithms); |
34 visitor->trace(m_device); | 57 visitor->trace(m_device); |
35 } | 58 } |
36 | 59 |
37 class ConnectCallback : public WebBluetoothRemoteGATTServerConnectCallbacks { | 60 class ConnectCallback : public WebBluetoothRemoteGATTServerConnectCallbacks { |
38 public: | 61 public: |
39 ConnectCallback(BluetoothDevice* device, ScriptPromiseResolver* resolver) | 62 ConnectCallback(BluetoothDevice* device, ScriptPromiseResolver* resolver) |
40 : m_device(device) | 63 : m_device(device) |
41 , m_resolver(resolver) {} | 64 , m_resolver(resolver) {} |
42 | 65 |
43 void onSuccess() override | 66 void onSuccess() override |
(...skipping 25 matching lines...) Expand all Loading... |
69 ScriptPromise promise = resolver->promise(); | 92 ScriptPromise promise = resolver->promise(); |
70 webbluetooth->connect(device()->id(), device(), new ConnectCallback(device()
, resolver)); | 93 webbluetooth->connect(device()->id(), device(), new ConnectCallback(device()
, resolver)); |
71 return promise; | 94 return promise; |
72 } | 95 } |
73 | 96 |
74 void BluetoothRemoteGATTServer::disconnect(ScriptState* scriptState) | 97 void BluetoothRemoteGATTServer::disconnect(ScriptState* scriptState) |
75 { | 98 { |
76 if (!m_connected) | 99 if (!m_connected) |
77 return; | 100 return; |
78 m_connected = false; | 101 m_connected = false; |
| 102 ClearActiveAlgorithms(); |
79 WebBluetooth* webbluetooth = BluetoothSupplement::fromScriptState(scriptStat
e); | 103 WebBluetooth* webbluetooth = BluetoothSupplement::fromScriptState(scriptStat
e); |
80 webbluetooth->disconnect(device()->id()); | 104 webbluetooth->disconnect(device()->id()); |
81 device()->dispatchEvent(Event::createBubble(EventTypeNames::gattserverdiscon
nected)); | 105 device()->dispatchEvent(Event::createBubble(EventTypeNames::gattserverdiscon
nected)); |
82 } | 106 } |
83 | 107 |
84 // Class that allows us to resolve the promise with a single service or | 108 // Class that allows us to resolve the promise with a single service or |
85 // with a vector owning the services. | 109 // with a vector owning the services. |
86 class GetPrimaryServicesCallback : public WebBluetoothGetPrimaryServicesCallback
s { | 110 class GetPrimaryServicesCallback : public WebBluetoothGetPrimaryServicesCallback
s { |
87 public: | 111 public: |
88 GetPrimaryServicesCallback(BluetoothDevice* device, mojom::blink::WebBluetoo
thGATTQueryQuantity quantity, ScriptPromiseResolver* resolver) | 112 GetPrimaryServicesCallback(BluetoothDevice* device, mojom::blink::WebBluetoo
thGATTQueryQuantity quantity, ScriptPromiseResolver* resolver) |
89 : m_device(device) | 113 : m_device(device) |
90 , m_quantity(quantity) | 114 , m_quantity(quantity) |
91 , m_resolver(resolver) {} | 115 , m_resolver(resolver) |
| 116 { |
| 117 // We always check that the device is connected before constructing this |
| 118 // object. |
| 119 CHECK(m_device->gatt()->connected()); |
| 120 m_device->gatt()->AddToActiveAlgorithms(m_resolver.get()); |
| 121 } |
92 | 122 |
93 void onSuccess(const WebVector<WebBluetoothRemoteGATTService*>& webServices)
override | 123 void onSuccess(const WebVector<WebBluetoothRemoteGATTService*>& webServices)
override |
94 { | 124 { |
95 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex
t()->activeDOMObjectsAreStopped()) | 125 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex
t()->activeDOMObjectsAreStopped()) |
96 return; | 126 return; |
97 | 127 |
| 128 // If the resolver is not in the set of ActiveAlgorithms then the frame |
| 129 // disconnected so we reject. |
| 130 if (!m_device->gatt()->RemoveFromActiveAlgorithms(m_resolver.get())) { |
| 131 m_resolver->reject(DOMException::create(NetworkError, kGATTServerDis
connected)); |
| 132 return; |
| 133 } |
| 134 |
98 if (m_quantity == mojom::blink::WebBluetoothGATTQueryQuantity::SINGLE) { | 135 if (m_quantity == mojom::blink::WebBluetoothGATTQueryQuantity::SINGLE) { |
99 DCHECK_EQ(1u, webServices.size()); | 136 DCHECK_EQ(1u, webServices.size()); |
100 m_resolver->resolve(BluetoothRemoteGATTService::take(m_resolver, wra
pUnique(webServices[0]), m_device)); | 137 m_resolver->resolve(BluetoothRemoteGATTService::take(m_resolver, wra
pUnique(webServices[0]), m_device)); |
101 return; | 138 return; |
102 } | 139 } |
103 | 140 |
104 HeapVector<Member<BluetoothRemoteGATTService>> services; | 141 HeapVector<Member<BluetoothRemoteGATTService>> services; |
105 services.reserveInitialCapacity(webServices.size()); | 142 services.reserveInitialCapacity(webServices.size()); |
106 for (WebBluetoothRemoteGATTService* webService : webServices) { | 143 for (WebBluetoothRemoteGATTService* webService : webServices) { |
107 services.append(BluetoothRemoteGATTService::take(m_resolver, wrapUni
que(webService), m_device)); | 144 services.append(BluetoothRemoteGATTService::take(m_resolver, wrapUni
que(webService), m_device)); |
108 } | 145 } |
109 m_resolver->resolve(services); | 146 m_resolver->resolve(services); |
110 } | 147 } |
111 | 148 |
112 void onError(int32_t error /* Corresponds to WebBluetoothError in web_blueto
oth.mojom */) override | 149 void onError(int32_t error /* Corresponds to WebBluetoothError in web_blueto
oth.mojom */) override |
113 { | 150 { |
114 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex
t()->activeDOMObjectsAreStopped()) | 151 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex
t()->activeDOMObjectsAreStopped()) |
115 return; | 152 return; |
| 153 |
| 154 m_device->gatt()->RemoveFromActiveAlgorithms(m_resolver.get()); |
116 m_resolver->reject(BluetoothError::take(m_resolver, error)); | 155 m_resolver->reject(BluetoothError::take(m_resolver, error)); |
117 } | 156 } |
118 private: | 157 private: |
119 Persistent<BluetoothDevice> m_device; | 158 Persistent<BluetoothDevice> m_device; |
120 mojom::blink::WebBluetoothGATTQueryQuantity m_quantity; | 159 mojom::blink::WebBluetoothGATTQueryQuantity m_quantity; |
121 Persistent<ScriptPromiseResolver> m_resolver; | 160 Persistent<ScriptPromiseResolver> m_resolver; |
122 }; | 161 }; |
123 | 162 |
124 ScriptPromise BluetoothRemoteGATTServer::getPrimaryService(ScriptState* scriptSt
ate, const StringOrUnsignedLong& service, ExceptionState& exceptionState) | 163 ScriptPromise BluetoothRemoteGATTServer::getPrimaryService(ScriptState* scriptSt
ate, const StringOrUnsignedLong& service, ExceptionState& exceptionState) |
125 { | 164 { |
(...skipping 13 matching lines...) Expand all Loading... |
139 return getPrimaryServicesImpl(scriptState, mojom::blink::WebBluetoothGATTQue
ryQuantity::MULTIPLE, serviceUUID); | 178 return getPrimaryServicesImpl(scriptState, mojom::blink::WebBluetoothGATTQue
ryQuantity::MULTIPLE, serviceUUID); |
140 } | 179 } |
141 | 180 |
142 ScriptPromise BluetoothRemoteGATTServer::getPrimaryServices(ScriptState* scriptS
tate, ExceptionState&) | 181 ScriptPromise BluetoothRemoteGATTServer::getPrimaryServices(ScriptState* scriptS
tate, ExceptionState&) |
143 { | 182 { |
144 return getPrimaryServicesImpl(scriptState, mojom::blink::WebBluetoothGATTQue
ryQuantity::MULTIPLE); | 183 return getPrimaryServicesImpl(scriptState, mojom::blink::WebBluetoothGATTQue
ryQuantity::MULTIPLE); |
145 } | 184 } |
146 | 185 |
147 ScriptPromise BluetoothRemoteGATTServer::getPrimaryServicesImpl(ScriptState* scr
iptState, mojom::blink::WebBluetoothGATTQueryQuantity quantity, String servicesU
UID) | 186 ScriptPromise BluetoothRemoteGATTServer::getPrimaryServicesImpl(ScriptState* scr
iptState, mojom::blink::WebBluetoothGATTQueryQuantity quantity, String servicesU
UID) |
148 { | 187 { |
| 188 if (!connected()) { |
| 189 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::
create(NetworkError, kGATTServerNotConnected)); |
| 190 } |
| 191 |
149 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; | 192 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; |
150 ScriptPromise promise = resolver->promise(); | 193 ScriptPromise promise = resolver->promise(); |
151 | 194 |
152 WebBluetooth* webbluetooth = BluetoothSupplement::fromScriptState(scriptStat
e); | 195 WebBluetooth* webbluetooth = BluetoothSupplement::fromScriptState(scriptStat
e); |
153 webbluetooth->getPrimaryServices(device()->id(), static_cast<int32_t>(quanti
ty), servicesUUID, new GetPrimaryServicesCallback(device(), quantity, resolver))
; | 196 webbluetooth->getPrimaryServices(device()->id(), static_cast<int32_t>(quanti
ty), servicesUUID, new GetPrimaryServicesCallback(device(), quantity, resolver))
; |
154 | 197 |
155 return promise; | 198 return promise; |
156 } | 199 } |
157 | 200 |
158 } // namespace blink | 201 } // namespace blink |
OLD | NEW |