Index: third_party/WebKit/Source/modules/bluetooth/BluetoothRemoteGATTServer.cpp |
diff --git a/third_party/WebKit/Source/modules/bluetooth/BluetoothRemoteGATTServer.cpp b/third_party/WebKit/Source/modules/bluetooth/BluetoothRemoteGATTServer.cpp |
index a88dff4023bbf68c97cec57a01bfebda60770cb4..69e3dc41881fb18ec6c199240439d16d4f929546 100644 |
--- a/third_party/WebKit/Source/modules/bluetooth/BluetoothRemoteGATTServer.cpp |
+++ b/third_party/WebKit/Source/modules/bluetooth/BluetoothRemoteGATTServer.cpp |
@@ -18,6 +18,13 @@ |
namespace blink { |
+namespace { |
+ |
+const char kGATTServerDisconnected[] = "GATT Server disconnected while retrieving services."; |
+const char kGATTServerNotConnected[] = "GATT Server is disconnected. Cannot retrieve services."; |
+ |
+} |
+ |
BluetoothRemoteGATTServer::BluetoothRemoteGATTServer(BluetoothDevice* device) |
: m_device(device) |
, m_connected(false) |
@@ -29,8 +36,24 @@ BluetoothRemoteGATTServer* BluetoothRemoteGATTServer::create(BluetoothDevice* de |
return new BluetoothRemoteGATTServer(device); |
} |
+void BluetoothRemoteGATTServer::AddToActiveAlgorithms(ScriptPromiseResolver* resolver) |
+{ |
+ auto result = m_activeAlgorithms.add(resolver); |
+ CHECK(result.isNewEntry); |
+} |
+ |
+bool BluetoothRemoteGATTServer::RemoveFromActiveAlgorithms(ScriptPromiseResolver* resolver) |
+{ |
+ if (!m_activeAlgorithms.contains(resolver)) { |
+ return false; |
+ } |
+ m_activeAlgorithms.remove(resolver); |
+ return true; |
+} |
+ |
DEFINE_TRACE(BluetoothRemoteGATTServer) |
{ |
+ visitor->trace(m_activeAlgorithms); |
visitor->trace(m_device); |
} |
@@ -76,6 +99,7 @@ void BluetoothRemoteGATTServer::disconnect(ScriptState* scriptState) |
if (!m_connected) |
return; |
m_connected = false; |
+ 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.
|
WebBluetooth* webbluetooth = BluetoothSupplement::fromScriptState(scriptState); |
webbluetooth->disconnect(device()->id()); |
device()->dispatchEvent(Event::createBubble(EventTypeNames::gattserverdisconnected)); |
@@ -88,13 +112,25 @@ public: |
GetPrimaryServicesCallback(BluetoothDevice* device, mojom::blink::WebBluetoothGATTQueryQuantity quantity, ScriptPromiseResolver* resolver) |
: m_device(device) |
, m_quantity(quantity) |
- , m_resolver(resolver) {} |
+ , m_resolver(resolver) |
+ { |
+ 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.
|
+ m_device->gatt()->AddToActiveAlgorithms(m_resolver.get()); |
+ } |
+ } |
void onSuccess(const WebVector<WebBluetoothRemoteGATTService*>& webServices) override |
{ |
if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContext()->activeDOMObjectsAreStopped()) |
return; |
+ // If the resolver is not in the set of ActiveAlgorithms then the frame |
+ // disconnected so we reject. |
+ if (!m_device->gatt()->RemoveFromActiveAlgorithms(m_resolver.get())) { |
+ m_resolver->reject(DOMException::create(NetworkError, kGATTServerDisconnected)); |
+ return; |
+ } |
+ |
if (m_quantity == mojom::blink::WebBluetoothGATTQueryQuantity::SINGLE) { |
DCHECK_EQ(1u, webServices.size()); |
m_resolver->resolve(BluetoothRemoteGATTService::take(m_resolver, wrapUnique(webServices[0]), m_device)); |
@@ -113,6 +149,8 @@ public: |
{ |
if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContext()->activeDOMObjectsAreStopped()) |
return; |
+ |
+ m_device->gatt()->RemoveFromActiveAlgorithms(m_resolver.get()); |
m_resolver->reject(BluetoothError::take(m_resolver, error)); |
} |
private: |
@@ -146,6 +184,10 @@ ScriptPromise BluetoothRemoteGATTServer::getPrimaryServices(ScriptState* scriptS |
ScriptPromise BluetoothRemoteGATTServer::getPrimaryServicesImpl(ScriptState* scriptState, mojom::blink::WebBluetoothGATTQueryQuantity quantity, String servicesUUID) |
{ |
+ if (!connected()) { |
+ return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(NetworkError, kGATTServerNotConnected)); |
+ } |
+ |
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); |
ScriptPromise promise = resolver->promise(); |