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

Side by Side Diff: third_party/WebKit/Source/modules/bluetooth/BluetoothRemoteGATTServer.cpp

Issue 2752663002: Remove RemoteServerDisconnect() from web_bluetooth.mojom (Closed)
Patch Set: address scheib@'s comments Created 3 years, 8 months 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 unified diff | Download patch
OLDNEW
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/Bluetooth.h" 13 #include "modules/bluetooth/Bluetooth.h"
14 #include "modules/bluetooth/BluetoothDevice.h" 14 #include "modules/bluetooth/BluetoothDevice.h"
15 #include "modules/bluetooth/BluetoothError.h" 15 #include "modules/bluetooth/BluetoothError.h"
16 #include "modules/bluetooth/BluetoothRemoteGATTService.h" 16 #include "modules/bluetooth/BluetoothRemoteGATTService.h"
17 #include "modules/bluetooth/BluetoothUUID.h" 17 #include "modules/bluetooth/BluetoothUUID.h"
18 #include "mojo/public/cpp/bindings/associated_interface_ptr.h"
19 #include <utility> 18 #include <utility>
20 19
21 namespace blink { 20 namespace blink {
22 21
23 BluetoothRemoteGATTServer::BluetoothRemoteGATTServer(ExecutionContext* context, 22 BluetoothRemoteGATTServer::BluetoothRemoteGATTServer(ExecutionContext* context,
24 BluetoothDevice* device) 23 BluetoothDevice* device)
25 : ContextLifecycleObserver(context), m_device(device), m_connected(false) {} 24 : ContextLifecycleObserver(context),
25 m_clientBinding(this),
26 m_device(device),
27 m_connected(false) {}
26 28
27 BluetoothRemoteGATTServer* BluetoothRemoteGATTServer::Create( 29 BluetoothRemoteGATTServer* BluetoothRemoteGATTServer::Create(
28 ExecutionContext* context, 30 ExecutionContext* context,
29 BluetoothDevice* device) { 31 BluetoothDevice* device) {
30 return new BluetoothRemoteGATTServer(context, device); 32 return new BluetoothRemoteGATTServer(context, device);
31 } 33 }
32 34
33 void BluetoothRemoteGATTServer::contextDestroyed(ExecutionContext*) { 35 void BluetoothRemoteGATTServer::contextDestroyed(ExecutionContext*) {
34 Dispose(); 36 Dispose();
35 } 37 }
36 38
37 void BluetoothRemoteGATTServer::GATTServerDisconnected() { 39 void BluetoothRemoteGATTServer::GATTServerDisconnected() {
38 DispatchDisconnected(); 40 // This function can only be called if |m_clientBinding| is bound and
41 // |m_clientBinding| can only be bound if |m_connected| is true.
ortuno 2017/03/30 04:20:48 I might be missing something here but m_clientBind
juncai 2017/03/30 18:44:57 Done.
42 // Therefore we skip Step 2 of Responding to Disconnection.
43 // https://webbluetoothcg.github.io/web-bluetooth/#disconnection-events
44 DCHECK(m_clientBinding.is_bound());
45 CleanupDisconnectedDevice(true /* dispatchEvent */);
39 } 46 }
40 47
41 void BluetoothRemoteGATTServer::AddToActiveAlgorithms( 48 void BluetoothRemoteGATTServer::AddToActiveAlgorithms(
42 ScriptPromiseResolver* resolver) { 49 ScriptPromiseResolver* resolver) {
43 auto result = m_activeAlgorithms.insert(resolver); 50 auto result = m_activeAlgorithms.insert(resolver);
44 CHECK(result.isNewEntry); 51 CHECK(result.isNewEntry);
45 } 52 }
46 53
47 bool BluetoothRemoteGATTServer::RemoveFromActiveAlgorithms( 54 bool BluetoothRemoteGATTServer::RemoveFromActiveAlgorithms(
48 ScriptPromiseResolver* resolver) { 55 ScriptPromiseResolver* resolver) {
49 if (!m_activeAlgorithms.contains(resolver)) { 56 if (!m_activeAlgorithms.contains(resolver)) {
50 return false; 57 return false;
51 } 58 }
52 m_activeAlgorithms.erase(resolver); 59 m_activeAlgorithms.erase(resolver);
53 return true; 60 return true;
54 } 61 }
55 62
56 void BluetoothRemoteGATTServer::DisconnectIfConnected() { 63 void BluetoothRemoteGATTServer::CleanupDisconnectedDevice(bool dispatchEvent) {
57 if (m_connected) { 64 // This implements the specification "clean up the disconnected device"
58 SetConnected(false); 65 // algorithm:
59 ClearActiveAlgorithms(); 66 // https://webbluetoothcg.github.io/web-bluetooth/#clean-up-the-disconnected-d evice
60 mojom::blink::WebBluetoothService* service = 67 DCHECK(m_connected);
61 m_device->bluetooth()->Service(); 68 SetConnected(false);
62 service->RemoteServerDisconnect(m_device->id()); 69 ClearActiveAlgorithms();
70 m_device->ClearAttributeInstanceMap();
71 // TODO(juncai): Below this line there are steps in the above specification
72 // which we are not explicitly handling here (clearing representedService,
73 // notification & indications). Need to add comment here explaining why no
ortuno 2017/03/30 04:20:48 Clearing the represented services, characteristics
juncai 2017/03/30 18:44:57 Done.
74 // explicit actions are needed.
75 if (dispatchEvent) {
76 m_device->dispatchEvent(
77 Event::createBubble(EventTypeNames::gattserverdisconnected));
63 } 78 }
64 } 79 }
65 80
66 void BluetoothRemoteGATTServer::CleanupDisconnectedDeviceAndFireEvent() { 81 void BluetoothRemoteGATTServer::HandleClientConnectionError() {
67 DCHECK(m_connected);
68 SetConnected(false);
69 ClearActiveAlgorithms();
70 m_device->ClearAttributeInstanceMapAndFireEvent();
71 }
72
73 void BluetoothRemoteGATTServer::DispatchDisconnected() {
74 if (!m_connected) { 82 if (!m_connected) {
75 return; 83 return;
76 } 84 }
77 CleanupDisconnectedDeviceAndFireEvent(); 85 CleanupDisconnectedDevice(true /* dispatchEvent */);
78 } 86 }
79 87
80 void BluetoothRemoteGATTServer::Dispose() { 88 void BluetoothRemoteGATTServer::Dispose() {
81 DisconnectIfConnected(); 89 if (!m_connected) {
82 // The pipe to this object must be closed when is marked unreachable to 90 return;
83 // prevent messages from being dispatched before lazy sweeping. 91 }
84 m_clientBindings.CloseAllBindings(); 92 // The object is being garbage collected or the context is being destroyed,
93 // so no need to dispatch a gattserverdisconnected event.
94 CleanupDisconnectedDevice(false /* dispatchEvent */);
95 DCHECK(m_clientBinding.is_bound());
96 m_clientBinding.Close();
85 } 97 }
86 98
87 DEFINE_TRACE(BluetoothRemoteGATTServer) { 99 DEFINE_TRACE(BluetoothRemoteGATTServer) {
88 visitor->trace(m_activeAlgorithms); 100 visitor->trace(m_activeAlgorithms);
89 visitor->trace(m_device); 101 visitor->trace(m_device);
90 ContextLifecycleObserver::trace(visitor); 102 ContextLifecycleObserver::trace(visitor);
91 } 103 }
92 104
93 void BluetoothRemoteGATTServer::ConnectCallback( 105 void BluetoothRemoteGATTServer::ConnectCallback(
94 ScriptPromiseResolver* resolver, 106 ScriptPromiseResolver* resolver,
95 mojom::blink::WebBluetoothResult result) { 107 mojom::blink::WebBluetoothResult result) {
96 if (!resolver->getExecutionContext() || 108 if (!resolver->getExecutionContext() ||
97 resolver->getExecutionContext()->isContextDestroyed()) 109 resolver->getExecutionContext()->isContextDestroyed())
98 return; 110 return;
99 111
100 if (result == mojom::blink::WebBluetoothResult::SUCCESS) { 112 if (result == mojom::blink::WebBluetoothResult::SUCCESS) {
101 SetConnected(true); 113 SetConnected(true);
102 resolver->resolve(this); 114 resolver->resolve(this);
103 } else { 115 } else {
104 resolver->reject(BluetoothError::CreateDOMException(result)); 116 resolver->reject(BluetoothError::CreateDOMException(result));
105 } 117 }
106 } 118 }
107 119
108 ScriptPromise BluetoothRemoteGATTServer::connect(ScriptState* scriptState) { 120 ScriptPromise BluetoothRemoteGATTServer::connect(ScriptState* scriptState) {
109 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); 121 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
110 ScriptPromise promise = resolver->promise(); 122 ScriptPromise promise = resolver->promise();
111 123
112 mojom::blink::WebBluetoothService* service = m_device->bluetooth()->Service(); 124 if (m_connected) {
ortuno 2017/03/30 04:20:48 hmm I think this is breaking spec'ed behavior e.g.
juncai 2017/03/30 18:44:57 hmm... I am not sure I understand it. When the sec
ortuno 2017/03/31 06:07:28 According to step 5.2 of the connect() algorithm i
113 mojom::blink::WebBluetoothServerClientAssociatedPtrInfo ptrInfo; 125 resolver->resolve(this);
114 auto request = mojo::MakeRequest(&ptrInfo); 126 } else {
115 m_clientBindings.AddBinding(this, std::move(request)); 127 mojom::blink::WebBluetoothService* service =
128 m_device->bluetooth()->Service();
129 mojom::blink::WebBluetoothServerClientAssociatedPtrInfo ptrInfo;
130 m_clientBinding.Bind(&ptrInfo);
131 m_clientBinding.set_connection_error_handler(convertToBaseCallback(
ortuno 2017/03/30 04:20:48 Since you are binding this here and in the browser
juncai 2017/03/30 18:44:57 Yes, only if |m_connected| is true. And in that si
ortuno 2017/03/31 06:07:28 I think the fact that the client is receiving conn
132 WTF::bind(&BluetoothRemoteGATTServer::HandleClientConnectionError,
133 wrapWeakPersistent(this))));
116 134
117 service->RemoteServerConnect( 135 service->RemoteServerConnect(
118 m_device->id(), std::move(ptrInfo), 136 m_device->id(), std::move(ptrInfo),
119 convertToBaseCallback( 137 convertToBaseCallback(
120 WTF::bind(&BluetoothRemoteGATTServer::ConnectCallback, 138 WTF::bind(&BluetoothRemoteGATTServer::ConnectCallback,
121 wrapPersistent(this), wrapPersistent(resolver)))); 139 wrapPersistent(this), wrapPersistent(resolver))));
140 }
122 141
123 return promise; 142 return promise;
124 } 143 }
125 144
126 void BluetoothRemoteGATTServer::disconnect(ScriptState* scriptState) { 145 void BluetoothRemoteGATTServer::disconnect(ScriptState* scriptState) {
127 if (!m_connected) 146 ClearActiveAlgorithms();
dcheng 2017/03/28 02:25:01 Just curious: how come we need to ClearActiveAlgor
ortuno 2017/03/30 04:20:48 I asked the same in the spec a while ago :) The an
juncai 2017/03/30 18:44:57 comment added. Done.
juncai 2017/03/30 18:44:57 Thanks Gio for the explanation!
147 if (!m_connected) {
128 return; 148 return;
129 CleanupDisconnectedDeviceAndFireEvent(); 149 }
130 m_clientBindings.CloseAllBindings(); 150 CleanupDisconnectedDevice(true /* dispatchEvent */);
131 mojom::blink::WebBluetoothService* service = m_device->bluetooth()->Service(); 151 DCHECK(m_clientBinding.is_bound());
132 service->RemoteServerDisconnect(m_device->id()); 152 // Implicitly signals disconnect via the connection_error_handler.
153 m_clientBinding.Close();
133 } 154 }
134 155
135 // Callback that allows us to resolve the promise with a single service or 156 // Callback that allows us to resolve the promise with a single service or
136 // with a vector owning the services. 157 // with a vector owning the services.
137 void BluetoothRemoteGATTServer::GetPrimaryServicesCallback( 158 void BluetoothRemoteGATTServer::GetPrimaryServicesCallback(
138 const String& requestedServiceUUID, 159 const String& requestedServiceUUID,
139 mojom::blink::WebBluetoothGATTQueryQuantity quantity, 160 mojom::blink::WebBluetoothGATTQueryQuantity quantity,
140 ScriptPromiseResolver* resolver, 161 ScriptPromiseResolver* resolver,
141 mojom::blink::WebBluetoothResult result, 162 mojom::blink::WebBluetoothResult result,
142 Optional<Vector<mojom::blink::WebBluetoothRemoteGATTServicePtr>> services) { 163 Optional<Vector<mojom::blink::WebBluetoothRemoteGATTServicePtr>> services) {
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 service->RemoteServerGetPrimaryServices( 254 service->RemoteServerGetPrimaryServices(
234 m_device->id(), quantity, servicesUUID, 255 m_device->id(), quantity, servicesUUID,
235 convertToBaseCallback( 256 convertToBaseCallback(
236 WTF::bind(&BluetoothRemoteGATTServer::GetPrimaryServicesCallback, 257 WTF::bind(&BluetoothRemoteGATTServer::GetPrimaryServicesCallback,
237 wrapPersistent(this), servicesUUID, quantity, 258 wrapPersistent(this), servicesUUID, quantity,
238 wrapPersistent(resolver)))); 259 wrapPersistent(resolver))));
239 return promise; 260 return promise;
240 } 261 }
241 262
242 } // namespace blink 263 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698