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 m_activeAlgorithms.clear(); | |
Jeffrey Yasskin
2016/07/28 22:45:14
Maybe use ClearActiveAlgorithms() here in case tha
ortuno
2016/07/29 16:11:51
Done.
| |
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 if (m_device->gatt()->connected()) { | |
Jeffrey Yasskin
2016/07/28 22:45:14
Maybe CHECK that it's connected, since the caller
ortuno
2016/07/29 16:11:51
Done.
| |
118 m_device->gatt()->AddToActiveAlgorithms(m_resolver.get()); | |
119 } | |
120 } | |
92 | 121 |
93 void onSuccess(const WebVector<WebBluetoothRemoteGATTService*>& webServices) override | 122 void onSuccess(const WebVector<WebBluetoothRemoteGATTService*>& webServices) override |
94 { | 123 { |
95 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped()) | 124 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped()) |
96 return; | 125 return; |
97 | 126 |
127 // If the resolver is not in the set of ActiveAlgorithms then the frame | |
128 // disconnected so we reject. | |
129 if (!m_device->gatt()->RemoveFromActiveAlgorithms(m_resolver.get())) { | |
130 m_resolver->reject(DOMException::create(NetworkError, kGATTServerDis connected)); | |
131 return; | |
132 } | |
133 | |
98 if (m_quantity == mojom::blink::WebBluetoothGATTQueryQuantity::SINGLE) { | 134 if (m_quantity == mojom::blink::WebBluetoothGATTQueryQuantity::SINGLE) { |
99 DCHECK_EQ(1u, webServices.size()); | 135 DCHECK_EQ(1u, webServices.size()); |
100 m_resolver->resolve(BluetoothRemoteGATTService::take(m_resolver, wra pUnique(webServices[0]), m_device)); | 136 m_resolver->resolve(BluetoothRemoteGATTService::take(m_resolver, wra pUnique(webServices[0]), m_device)); |
101 return; | 137 return; |
102 } | 138 } |
103 | 139 |
104 HeapVector<Member<BluetoothRemoteGATTService>> services; | 140 HeapVector<Member<BluetoothRemoteGATTService>> services; |
105 services.reserveInitialCapacity(webServices.size()); | 141 services.reserveInitialCapacity(webServices.size()); |
106 for (WebBluetoothRemoteGATTService* webService : webServices) { | 142 for (WebBluetoothRemoteGATTService* webService : webServices) { |
107 services.append(BluetoothRemoteGATTService::take(m_resolver, wrapUni que(webService), m_device)); | 143 services.append(BluetoothRemoteGATTService::take(m_resolver, wrapUni que(webService), m_device)); |
108 } | 144 } |
109 m_resolver->resolve(services); | 145 m_resolver->resolve(services); |
110 } | 146 } |
111 | 147 |
112 void onError(int32_t error /* Corresponds to WebBluetoothError in web_blueto oth.mojom */) override | 148 void onError(int32_t error /* Corresponds to WebBluetoothError in web_blueto oth.mojom */) override |
113 { | 149 { |
114 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped()) | 150 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex t()->activeDOMObjectsAreStopped()) |
115 return; | 151 return; |
152 | |
153 m_device->gatt()->RemoveFromActiveAlgorithms(m_resolver.get()); | |
116 m_resolver->reject(BluetoothError::take(m_resolver, error)); | 154 m_resolver->reject(BluetoothError::take(m_resolver, error)); |
117 } | 155 } |
118 private: | 156 private: |
119 Persistent<BluetoothDevice> m_device; | 157 Persistent<BluetoothDevice> m_device; |
120 mojom::blink::WebBluetoothGATTQueryQuantity m_quantity; | 158 mojom::blink::WebBluetoothGATTQueryQuantity m_quantity; |
121 Persistent<ScriptPromiseResolver> m_resolver; | 159 Persistent<ScriptPromiseResolver> m_resolver; |
122 }; | 160 }; |
123 | 161 |
124 ScriptPromise BluetoothRemoteGATTServer::getPrimaryService(ScriptState* scriptSt ate, const StringOrUnsignedLong& service, ExceptionState& exceptionState) | 162 ScriptPromise BluetoothRemoteGATTServer::getPrimaryService(ScriptState* scriptSt ate, const StringOrUnsignedLong& service, ExceptionState& exceptionState) |
125 { | 163 { |
(...skipping 13 matching lines...) Expand all Loading... | |
139 return getPrimaryServicesImpl(scriptState, mojom::blink::WebBluetoothGATTQue ryQuantity::MULTIPLE, serviceUUID); | 177 return getPrimaryServicesImpl(scriptState, mojom::blink::WebBluetoothGATTQue ryQuantity::MULTIPLE, serviceUUID); |
140 } | 178 } |
141 | 179 |
142 ScriptPromise BluetoothRemoteGATTServer::getPrimaryServices(ScriptState* scriptS tate, ExceptionState&) | 180 ScriptPromise BluetoothRemoteGATTServer::getPrimaryServices(ScriptState* scriptS tate, ExceptionState&) |
143 { | 181 { |
144 return getPrimaryServicesImpl(scriptState, mojom::blink::WebBluetoothGATTQue ryQuantity::MULTIPLE); | 182 return getPrimaryServicesImpl(scriptState, mojom::blink::WebBluetoothGATTQue ryQuantity::MULTIPLE); |
145 } | 183 } |
146 | 184 |
147 ScriptPromise BluetoothRemoteGATTServer::getPrimaryServicesImpl(ScriptState* scr iptState, mojom::blink::WebBluetoothGATTQueryQuantity quantity, String servicesU UID) | 185 ScriptPromise BluetoothRemoteGATTServer::getPrimaryServicesImpl(ScriptState* scr iptState, mojom::blink::WebBluetoothGATTQueryQuantity quantity, String servicesU UID) |
148 { | 186 { |
187 if (!connected()) { | |
188 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(NetworkError, kGATTServerNotConnected)); | |
189 } | |
190 | |
149 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; | 191 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; |
150 ScriptPromise promise = resolver->promise(); | 192 ScriptPromise promise = resolver->promise(); |
151 | 193 |
152 WebBluetooth* webbluetooth = BluetoothSupplement::fromScriptState(scriptStat e); | 194 WebBluetooth* webbluetooth = BluetoothSupplement::fromScriptState(scriptStat e); |
153 webbluetooth->getPrimaryServices(device()->id(), static_cast<int32_t>(quanti ty), servicesUUID, new GetPrimaryServicesCallback(device(), quantity, resolver)) ; | 195 webbluetooth->getPrimaryServices(device()->id(), static_cast<int32_t>(quanti ty), servicesUUID, new GetPrimaryServicesCallback(device(), quantity, resolver)) ; |
154 | 196 |
155 return promise; | 197 return promise; |
156 } | 198 } |
157 | 199 |
158 } // namespace blink | 200 } // namespace blink |
OLD | NEW |