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

Side by Side Diff: device/bluetooth/bluetooth_socket_chromeos.cc

Issue 851123002: Manage profiles in BluetoothAdapter on ChromeOS (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix profile memory leaks when adapter is gone Created 5 years, 10 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "device/bluetooth/bluetooth_socket_chromeos.h" 5 #include "device/bluetooth/bluetooth_socket_chromeos.h"
6 6
7 #include <queue> 7 #include <queue>
8 #include <string> 8 #include <string>
9 9
10 #include "base/basictypes.h" 10 #include "base/basictypes.h"
(...skipping 10 matching lines...) Expand all
21 #include "base/threading/worker_pool.h" 21 #include "base/threading/worker_pool.h"
22 #include "chromeos/dbus/bluetooth_device_client.h" 22 #include "chromeos/dbus/bluetooth_device_client.h"
23 #include "chromeos/dbus/bluetooth_profile_manager_client.h" 23 #include "chromeos/dbus/bluetooth_profile_manager_client.h"
24 #include "chromeos/dbus/bluetooth_profile_service_provider.h" 24 #include "chromeos/dbus/bluetooth_profile_service_provider.h"
25 #include "chromeos/dbus/dbus_thread_manager.h" 25 #include "chromeos/dbus/dbus_thread_manager.h"
26 #include "dbus/bus.h" 26 #include "dbus/bus.h"
27 #include "dbus/file_descriptor.h" 27 #include "dbus/file_descriptor.h"
28 #include "dbus/object_path.h" 28 #include "dbus/object_path.h"
29 #include "device/bluetooth/bluetooth_adapter.h" 29 #include "device/bluetooth/bluetooth_adapter.h"
30 #include "device/bluetooth/bluetooth_adapter_chromeos.h" 30 #include "device/bluetooth/bluetooth_adapter_chromeos.h"
31 #include "device/bluetooth/bluetooth_adapter_profile_chromeos.h"
31 #include "device/bluetooth/bluetooth_device.h" 32 #include "device/bluetooth/bluetooth_device.h"
32 #include "device/bluetooth/bluetooth_device_chromeos.h" 33 #include "device/bluetooth/bluetooth_device_chromeos.h"
33 #include "device/bluetooth/bluetooth_socket.h" 34 #include "device/bluetooth/bluetooth_socket.h"
34 #include "device/bluetooth/bluetooth_socket_net.h" 35 #include "device/bluetooth/bluetooth_socket_net.h"
35 #include "device/bluetooth/bluetooth_socket_thread.h" 36 #include "device/bluetooth/bluetooth_socket_thread.h"
36 #include "net/base/ip_endpoint.h" 37 #include "net/base/ip_endpoint.h"
37 #include "net/base/net_errors.h" 38 #include "net/base/net_errors.h"
38 #include "third_party/cros_system_api/dbus/service_constants.h" 39 #include "third_party/cros_system_api/dbus/service_constants.h"
39 40
40 using device::BluetoothAdapter; 41 using device::BluetoothAdapter;
(...skipping 28 matching lines...) Expand all
69 70
70 BluetoothSocketChromeOS::ConnectionRequest::ConnectionRequest() 71 BluetoothSocketChromeOS::ConnectionRequest::ConnectionRequest()
71 : accepting(false), 72 : accepting(false),
72 cancelled(false) {} 73 cancelled(false) {}
73 74
74 BluetoothSocketChromeOS::ConnectionRequest::~ConnectionRequest() {} 75 BluetoothSocketChromeOS::ConnectionRequest::~ConnectionRequest() {}
75 76
76 BluetoothSocketChromeOS::BluetoothSocketChromeOS( 77 BluetoothSocketChromeOS::BluetoothSocketChromeOS(
77 scoped_refptr<base::SequencedTaskRunner> ui_task_runner, 78 scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
78 scoped_refptr<BluetoothSocketThread> socket_thread) 79 scoped_refptr<BluetoothSocketThread> socket_thread)
79 : BluetoothSocketNet(ui_task_runner, socket_thread) { 80 : BluetoothSocketNet(ui_task_runner, socket_thread), profile_(nullptr) {
80 } 81 }
81 82
82 BluetoothSocketChromeOS::~BluetoothSocketChromeOS() { 83 BluetoothSocketChromeOS::~BluetoothSocketChromeOS() {
83 DCHECK(object_path_.value().empty()); 84 DCHECK(!profile_);
84 DCHECK(profile_.get() == NULL);
85 85
86 if (adapter_.get()) { 86 if (adapter_.get()) {
87 adapter_->RemoveObserver(this); 87 adapter_->RemoveObserver(this);
88 adapter_ = NULL; 88 adapter_ = NULL;
89 } 89 }
90 } 90 }
91 91
92 void BluetoothSocketChromeOS::Connect( 92 void BluetoothSocketChromeOS::Connect(
93 const BluetoothDeviceChromeOS* device, 93 const BluetoothDeviceChromeOS* device,
94 const BluetoothUUID& uuid, 94 const BluetoothUUID& uuid,
95 SecurityLevel security_level, 95 SecurityLevel security_level,
96 const base::Closure& success_callback, 96 const base::Closure& success_callback,
97 const ErrorCompletionCallback& error_callback) { 97 const ErrorCompletionCallback& error_callback) {
98 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); 98 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
99 DCHECK(object_path_.value().empty()); 99 DCHECK(!profile_);
100 DCHECK(!profile_.get());
101 100
102 if (!uuid.IsValid()) { 101 if (!uuid.IsValid()) {
103 error_callback.Run(kInvalidUUID); 102 error_callback.Run(kInvalidUUID);
104 return; 103 return;
105 } 104 }
106 105
107 device_address_ = device->GetAddress(); 106 device_address_ = device->GetAddress();
108 device_path_ = device->object_path(); 107 device_path_ = device->object_path();
109 uuid_ = uuid; 108 uuid_ = uuid;
110 options_.reset(new BluetoothProfileManagerClient::Options()); 109 options_.reset(new BluetoothProfileManagerClient::Options());
111 if (security_level == SECURITY_LEVEL_LOW) 110 if (security_level == SECURITY_LEVEL_LOW)
112 options_->require_authentication.reset(new bool(false)); 111 options_->require_authentication.reset(new bool(false));
113 112
114 RegisterProfile(success_callback, error_callback); 113 RegisterProfile(device->adapter(), success_callback, error_callback);
115 } 114 }
116 115
117 void BluetoothSocketChromeOS::Listen( 116 void BluetoothSocketChromeOS::Listen(
118 scoped_refptr<BluetoothAdapter> adapter, 117 scoped_refptr<BluetoothAdapter> adapter,
119 SocketType socket_type, 118 SocketType socket_type,
120 const BluetoothUUID& uuid, 119 const BluetoothUUID& uuid,
121 const BluetoothAdapter::ServiceOptions& service_options, 120 const BluetoothAdapter::ServiceOptions& service_options,
122 const base::Closure& success_callback, 121 const base::Closure& success_callback,
123 const ErrorCompletionCallback& error_callback) { 122 const ErrorCompletionCallback& error_callback) {
124 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); 123 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
125 DCHECK(object_path_.value().empty()); 124 DCHECK(!profile_);
126 DCHECK(!profile_.get());
127 125
128 if (!uuid.IsValid()) { 126 if (!uuid.IsValid()) {
129 error_callback.Run(kInvalidUUID); 127 error_callback.Run(kInvalidUUID);
130 return; 128 return;
131 } 129 }
132 130
133 adapter_ = adapter; 131 adapter_ = adapter;
134 adapter_->AddObserver(this); 132 adapter_->AddObserver(this);
135 133
136 uuid_ = uuid; 134 uuid_ = uuid;
137 options_.reset(new BluetoothProfileManagerClient::Options()); 135 options_.reset(new BluetoothProfileManagerClient::Options());
138 if (service_options.name) 136 if (service_options.name)
139 options_->name.reset(new std::string(*service_options.name)); 137 options_->name.reset(new std::string(*service_options.name));
140 138
141 switch (socket_type) { 139 switch (socket_type) {
142 case kRfcomm: 140 case kRfcomm:
143 options_->channel.reset( 141 options_->channel.reset(
144 new uint16(service_options.channel ? *service_options.channel : 0)); 142 new uint16(service_options.channel ? *service_options.channel : 0));
145 break; 143 break;
146 case kL2cap: 144 case kL2cap:
147 options_->psm.reset( 145 options_->psm.reset(
148 new uint16(service_options.psm ? *service_options.psm : 0)); 146 new uint16(service_options.psm ? *service_options.psm : 0));
149 break; 147 break;
150 default: 148 default:
151 NOTREACHED(); 149 NOTREACHED();
152 } 150 }
153 151
154 RegisterProfile(success_callback, error_callback); 152 RegisterProfile(static_cast<BluetoothAdapterChromeOS*>(adapter_.get()),
153 success_callback, error_callback);
155 } 154 }
156 155
157 void BluetoothSocketChromeOS::Close() { 156 void BluetoothSocketChromeOS::Close() {
158 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); 157 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
159 158
160 if (profile_) 159 if (profile_)
161 UnregisterProfile(); 160 UnregisterProfile();
162 161
163 // In the case below, where an asynchronous task gets posted on the socket 162 // In the case below, where an asynchronous task gets posted on the socket
164 // thread in BluetoothSocketNet::Close, a reference will be held to this 163 // thread in BluetoothSocketNet::Close, a reference will be held to this
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 accept_request_.reset(new AcceptRequest); 208 accept_request_.reset(new AcceptRequest);
210 accept_request_->success_callback = success_callback; 209 accept_request_->success_callback = success_callback;
211 accept_request_->error_callback = error_callback; 210 accept_request_->error_callback = error_callback;
212 211
213 if (connection_request_queue_.size() >= 1) { 212 if (connection_request_queue_.size() >= 1) {
214 AcceptConnectionRequest(); 213 AcceptConnectionRequest();
215 } 214 }
216 } 215 }
217 216
218 void BluetoothSocketChromeOS::RegisterProfile( 217 void BluetoothSocketChromeOS::RegisterProfile(
218 BluetoothAdapterChromeOS* adapter,
219 const base::Closure& success_callback, 219 const base::Closure& success_callback,
220 const ErrorCompletionCallback& error_callback) { 220 const ErrorCompletionCallback& error_callback) {
221 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); 221 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
222 DCHECK(object_path_.value().empty()); 222 DCHECK(!profile_);
223 DCHECK(!profile_.get()); 223 DCHECK(adapter);
224 224
225 // The object path is relatively meaningless, but has to be unique, so for 225 // If the adapter is not present, this is a listening socket and the
226 // connecting profiles use a combination of the device address and profile 226 // adapter isn't running yet. Report success and carry on;
227 // UUID. 227 // the profile will be registered when the daemon becomes available.
228 std::string device_address_path, uuid_path; 228 if (!adapter->IsPresent()) {
229 base::ReplaceChars(device_address_, ":-", "_", &device_address_path); 229 VLOG(1) << uuid_.canonical_value() << " on " << device_path_.value()
230 base::ReplaceChars(uuid_.canonical_value(), ":-", "_", &uuid_path); 230 << ": Delaying profile registration.";
231 if (!device_address_path.empty()) { 231 base::MessageLoop::current()->PostTask(FROM_HERE, success_callback);
232 object_path_ = dbus::ObjectPath("/org/chromium/bluetooth_profile/" + 232 return;
233 device_address_path + "/" + uuid_path);
234 } else {
235 object_path_ = dbus::ObjectPath("/org/chromium/bluetooth_profile/" +
236 uuid_path);
237 } 233 }
238 234
239 // Create the service provider for the profile object. 235 VLOG(1) << uuid_.canonical_value() << " on " << device_path_.value()
240 dbus::Bus* system_bus = DBusThreadManager::Get()->GetSystemBus(); 236 << ": Acquiring profile.";
241 profile_.reset(BluetoothProfileServiceProvider::Create(
242 system_bus, object_path_, this));
243 DCHECK(profile_.get());
244 237
245 // Before reaching out to the Bluetooth Daemon to register a listening socket, 238 adapter->UseProfile(
246 // make sure it's actually running. If not, report success and carry on; 239 uuid_, device_path_, *options_, this,
247 // the profile will be registered when the daemon becomes available. 240 base::Bind(&BluetoothSocketChromeOS::OnRegisterProfile, this,
248 if (adapter_.get() && !adapter_->IsPresent()) { 241 success_callback, error_callback),
249 VLOG(1) << object_path_.value() << ": Delaying profile registration."; 242 base::Bind(&BluetoothSocketChromeOS::OnRegisterProfileError, this,
243 error_callback));
244 }
245
246 void BluetoothSocketChromeOS::OnRegisterProfile(
247 const base::Closure& success_callback,
248 const ErrorCompletionCallback& error_callback,
249 BluetoothAdapterProfileChromeOS* profile) {
250 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
251 DCHECK(!profile_);
252
253 profile_ = profile;
254
255 if (device_path_.value().empty()) {
256 VLOG(1) << uuid_.canonical_value() << ": Profile registered.";
250 success_callback.Run(); 257 success_callback.Run();
251 return; 258 return;
252 } 259 }
253 260
254 VLOG(1) << object_path_.value() << ": Registering profile."; 261 VLOG(1) << uuid_.canonical_value() << ": Got profile, connecting to "
255 DBusThreadManager::Get()->GetBluetoothProfileManagerClient()-> 262 << device_path_.value();
256 RegisterProfile(
257 object_path_,
258 uuid_.canonical_value(),
259 *options_,
260 base::Bind(&BluetoothSocketChromeOS::OnRegisterProfile,
261 this,
262 success_callback,
263 error_callback),
264 base::Bind(&BluetoothSocketChromeOS::OnRegisterProfileError,
265 this,
266 error_callback));
267 }
268 263
269 void BluetoothSocketChromeOS::OnRegisterProfile( 264 DBusThreadManager::Get()->GetBluetoothDeviceClient()->ConnectProfile(
270 const base::Closure& success_callback, 265 device_path_, uuid_.canonical_value(),
271 const ErrorCompletionCallback& error_callback) { 266 base::Bind(&BluetoothSocketChromeOS::OnConnectProfile, this,
272 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); 267 success_callback),
273 if (!device_path_.value().empty()) { 268 base::Bind(&BluetoothSocketChromeOS::OnConnectProfileError, this,
274 VLOG(1) << object_path_.value() << ": Profile registered, connecting to " 269 error_callback));
275 << device_path_.value();
276
277 DBusThreadManager::Get()->GetBluetoothDeviceClient()->
278 ConnectProfile(
279 device_path_,
280 uuid_.canonical_value(),
281 base::Bind(
282 &BluetoothSocketChromeOS::OnConnectProfile,
283 this,
284 success_callback),
285 base::Bind(
286 &BluetoothSocketChromeOS::OnConnectProfileError,
287 this,
288 error_callback));
289 } else {
290 VLOG(1) << object_path_.value() << ": Profile registered.";
291 success_callback.Run();
292 }
293 } 270 }
294 271
295 void BluetoothSocketChromeOS::OnRegisterProfileError( 272 void BluetoothSocketChromeOS::OnRegisterProfileError(
296 const ErrorCompletionCallback& error_callback, 273 const ErrorCompletionCallback& error_callback,
297 const std::string& error_name,
298 const std::string& error_message) { 274 const std::string& error_message) {
299 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); 275 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
300 LOG(WARNING) << object_path_.value() << ": Failed to register profile: " 276
301 << error_name << ": " << error_message; 277 LOG(WARNING) << uuid_.canonical_value()
278 << ": Failed to register profile: " << error_message;
302 error_callback.Run(error_message); 279 error_callback.Run(error_message);
303 } 280 }
304 281
305 void BluetoothSocketChromeOS::OnConnectProfile( 282 void BluetoothSocketChromeOS::OnConnectProfile(
306 const base::Closure& success_callback) { 283 const base::Closure& success_callback) {
307 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); 284 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
308 VLOG(1) << object_path_.value() << ": Profile connected."; 285 DCHECK(profile_);
286
287 VLOG(1) << profile_->object_path().value() << ": Profile connected.";
309 UnregisterProfile(); 288 UnregisterProfile();
310 success_callback.Run(); 289 success_callback.Run();
311 } 290 }
312 291
313 void BluetoothSocketChromeOS::OnConnectProfileError( 292 void BluetoothSocketChromeOS::OnConnectProfileError(
314 const ErrorCompletionCallback& error_callback, 293 const ErrorCompletionCallback& error_callback,
315 const std::string& error_name, 294 const std::string& error_name,
316 const std::string& error_message) { 295 const std::string& error_message) {
317 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); 296 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
318 LOG(WARNING) << object_path_.value() << ": Failed to connect profile: " 297 DCHECK(profile_);
319 << error_name << ": " << error_message; 298
299 LOG(WARNING) << profile_->object_path().value()
300 << ": Failed to connect profile: " << error_name << ": "
301 << error_message;
320 UnregisterProfile(); 302 UnregisterProfile();
321 error_callback.Run(error_message); 303 error_callback.Run(error_message);
322 } 304 }
323 305
324 void BluetoothSocketChromeOS::AdapterPresentChanged(BluetoothAdapter* adapter, 306 void BluetoothSocketChromeOS::AdapterPresentChanged(BluetoothAdapter* adapter,
325 bool present) { 307 bool present) {
326 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); 308 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
327 DCHECK(!object_path_.value().empty());
328 DCHECK(profile_.get());
329 309
330 if (!present) 310 if (!present) {
311 // Adapter removed, the profile is now invalid.
312 UnregisterProfile();
331 return; 313 return;
314 }
332 315
333 VLOG(1) << object_path_.value() << ": Re-register profile."; 316 DCHECK(!profile_);
334 DBusThreadManager::Get()->GetBluetoothProfileManagerClient()-> 317
335 RegisterProfile( 318 VLOG(1) << uuid_.canonical_value() << " on " << device_path_.value()
336 object_path_, 319 << ": Acquiring profile.";
337 uuid_.canonical_value(), 320
338 *options_, 321 static_cast<BluetoothAdapterChromeOS*>(adapter)->UseProfile(
339 base::Bind(&BluetoothSocketChromeOS::OnInternalRegisterProfile, 322 uuid_, device_path_, *options_, this,
340 this), 323 base::Bind(&BluetoothSocketChromeOS::OnInternalRegisterProfile, this),
341 base::Bind(&BluetoothSocketChromeOS::OnInternalRegisterProfileError, 324 base::Bind(&BluetoothSocketChromeOS::OnInternalRegisterProfileError,
342 this)); 325 this));
343 } 326 }
344 327
345 void BluetoothSocketChromeOS::OnInternalRegisterProfile() { 328 void BluetoothSocketChromeOS::OnInternalRegisterProfile(
329 BluetoothAdapterProfileChromeOS* profile) {
346 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); 330 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
331 DCHECK(!profile_);
347 332
348 VLOG(1) << object_path_.value() << ": Profile re-registered"; 333 profile_ = profile;
334
335 VLOG(1) << uuid_.canonical_value() << ": Profile re-registered";
349 } 336 }
350 337
351 void BluetoothSocketChromeOS::OnInternalRegisterProfileError( 338 void BluetoothSocketChromeOS::OnInternalRegisterProfileError(
352 const std::string& error_name,
353 const std::string& error_message) { 339 const std::string& error_message) {
354 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); 340 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
355 341
356 // It's okay if the profile already exists, it means we registered it on 342 LOG(WARNING) << "Failed to re-register profile: " << error_message;
357 // initialization.
358 if (error_name == bluetooth_profile_manager::kErrorAlreadyExists)
359 return;
360
361 LOG(WARNING) << object_path_.value() << ": Failed to re-register profile: "
362 << error_name << ": " << error_message;
363 } 343 }
364 344
365 void BluetoothSocketChromeOS::Released() { 345 void BluetoothSocketChromeOS::Released() {
366 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); 346 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
367 VLOG(1) << object_path_.value() << ": Release"; 347 DCHECK(profile_);
348
349 VLOG(1) << profile_->object_path().value() << ": Release";
368 } 350 }
369 351
370 void BluetoothSocketChromeOS::NewConnection( 352 void BluetoothSocketChromeOS::NewConnection(
371 const dbus::ObjectPath& device_path, 353 const dbus::ObjectPath& device_path,
372 scoped_ptr<dbus::FileDescriptor> fd, 354 scoped_ptr<dbus::FileDescriptor> fd,
373 const BluetoothProfileServiceProvider::Delegate::Options& options, 355 const BluetoothProfileServiceProvider::Delegate::Options& options,
374 const ConfirmationCallback& callback) { 356 const ConfirmationCallback& callback) {
375 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); 357 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
376 VLOG(1) << object_path_.value() << ": New connection from device: " 358
377 << device_path.value(); 359 VLOG(1) << uuid_.canonical_value()
360 << ": New connection from device: " << device_path.value();
378 361
379 if (!device_path_.value().empty()) { 362 if (!device_path_.value().empty()) {
380 DCHECK(device_path_ == device_path); 363 DCHECK(device_path_ == device_path);
381 364
382 socket_thread()->task_runner()->PostTask( 365 socket_thread()->task_runner()->PostTask(
383 FROM_HERE, 366 FROM_HERE,
384 base::Bind( 367 base::Bind(
385 &BluetoothSocketChromeOS::DoNewConnection, 368 &BluetoothSocketChromeOS::DoNewConnection,
386 this, 369 this,
387 device_path_, 370 device_path_,
388 base::Passed(&fd), 371 base::Passed(&fd),
389 options, 372 options,
390 callback)); 373 callback));
391 } else { 374 } else {
392 linked_ptr<ConnectionRequest> request(new ConnectionRequest()); 375 linked_ptr<ConnectionRequest> request(new ConnectionRequest());
393 request->device_path = device_path; 376 request->device_path = device_path;
394 request->fd = fd.Pass(); 377 request->fd = fd.Pass();
395 request->options = options; 378 request->options = options;
396 request->callback = callback; 379 request->callback = callback;
397 380
398 connection_request_queue_.push(request); 381 connection_request_queue_.push(request);
399 VLOG(1) << object_path_.value() << ": Connection is now pending."; 382 VLOG(1) << uuid_.canonical_value() << ": Connection is now pending.";
400 if (accept_request_) { 383 if (accept_request_) {
401 AcceptConnectionRequest(); 384 AcceptConnectionRequest();
402 } 385 }
403 } 386 }
404 } 387 }
405 388
406 void BluetoothSocketChromeOS::RequestDisconnection( 389 void BluetoothSocketChromeOS::RequestDisconnection(
407 const dbus::ObjectPath& device_path, 390 const dbus::ObjectPath& device_path,
408 const ConfirmationCallback& callback) { 391 const ConfirmationCallback& callback) {
409 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); 392 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
410 VLOG(1) << object_path_.value() << ": Request disconnection"; 393 DCHECK(profile_);
394
395 VLOG(1) << profile_->object_path().value() << ": Request disconnection";
411 callback.Run(SUCCESS); 396 callback.Run(SUCCESS);
412 } 397 }
413 398
414 void BluetoothSocketChromeOS::Cancel() { 399 void BluetoothSocketChromeOS::Cancel() {
415 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); 400 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
416 VLOG(1) << object_path_.value() << ": Cancel"; 401 DCHECK(profile_);
402
403 VLOG(1) << profile_->object_path().value() << ": Cancel";
417 404
418 if (!connection_request_queue_.size()) 405 if (!connection_request_queue_.size())
419 return; 406 return;
420 407
421 // If the front request is being accepted mark it as cancelled, otherwise 408 // If the front request is being accepted mark it as cancelled, otherwise
422 // just pop it from the queue. 409 // just pop it from the queue.
423 linked_ptr<ConnectionRequest> request = connection_request_queue_.front(); 410 linked_ptr<ConnectionRequest> request = connection_request_queue_.front();
424 if (!request->accepting) { 411 if (!request->accepting) {
425 request->cancelled = true; 412 request->cancelled = true;
426 } else { 413 } else {
427 connection_request_queue_.pop(); 414 connection_request_queue_.pop();
428 } 415 }
429 } 416 }
430 417
431 void BluetoothSocketChromeOS::AcceptConnectionRequest() { 418 void BluetoothSocketChromeOS::AcceptConnectionRequest() {
432 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); 419 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
433 DCHECK(accept_request_.get()); 420 DCHECK(accept_request_.get());
434 DCHECK(connection_request_queue_.size() >= 1); 421 DCHECK(connection_request_queue_.size() >= 1);
422 DCHECK(profile_);
435 423
436 VLOG(1) << object_path_.value() << ": Accepting pending connection."; 424 VLOG(1) << profile_->object_path().value()
425 << ": Accepting pending connection.";
437 426
438 linked_ptr<ConnectionRequest> request = connection_request_queue_.front(); 427 linked_ptr<ConnectionRequest> request = connection_request_queue_.front();
439 request->accepting = true; 428 request->accepting = true;
440 429
441 BluetoothDeviceChromeOS* device = 430 BluetoothDeviceChromeOS* device =
442 static_cast<BluetoothAdapterChromeOS*>(adapter_.get())-> 431 static_cast<BluetoothAdapterChromeOS*>(adapter_.get())->
443 GetDeviceWithPath(request->device_path); 432 GetDeviceWithPath(request->device_path);
444 DCHECK(device); 433 DCHECK(device);
445 434
446 scoped_refptr<BluetoothSocketChromeOS> client_socket = 435 scoped_refptr<BluetoothSocketChromeOS> client_socket =
(...skipping 20 matching lines...) Expand all
467 456
468 void BluetoothSocketChromeOS::DoNewConnection( 457 void BluetoothSocketChromeOS::DoNewConnection(
469 const dbus::ObjectPath& device_path, 458 const dbus::ObjectPath& device_path,
470 scoped_ptr<dbus::FileDescriptor> fd, 459 scoped_ptr<dbus::FileDescriptor> fd,
471 const BluetoothProfileServiceProvider::Delegate::Options& options, 460 const BluetoothProfileServiceProvider::Delegate::Options& options,
472 const ConfirmationCallback& callback) { 461 const ConfirmationCallback& callback) {
473 DCHECK(socket_thread()->task_runner()->RunsTasksOnCurrentThread()); 462 DCHECK(socket_thread()->task_runner()->RunsTasksOnCurrentThread());
474 base::ThreadRestrictions::AssertIOAllowed(); 463 base::ThreadRestrictions::AssertIOAllowed();
475 fd->CheckValidity(); 464 fd->CheckValidity();
476 465
477 VLOG(1) << object_path_.value() << ": Validity check complete."; 466 VLOG(1) << uuid_.canonical_value() << ": Validity check complete.";
478 if (!fd->is_valid()) { 467 if (!fd->is_valid()) {
479 LOG(WARNING) << object_path_.value() << " :" << fd->value() 468 LOG(WARNING) << uuid_.canonical_value() << " :" << fd->value()
480 << ": Invalid file descriptor received from Bluetooth Daemon."; 469 << ": Invalid file descriptor received from Bluetooth Daemon.";
481 ui_task_runner()->PostTask(FROM_HERE, 470 ui_task_runner()->PostTask(FROM_HERE,
482 base::Bind(callback, REJECTED));; 471 base::Bind(callback, REJECTED));;
483 return; 472 return;
484 } 473 }
485 474
486 if (tcp_socket()) { 475 if (tcp_socket()) {
487 LOG(WARNING) << object_path_.value() << ": Already connected"; 476 LOG(WARNING) << uuid_.canonical_value() << ": Already connected";
488 ui_task_runner()->PostTask(FROM_HERE, 477 ui_task_runner()->PostTask(FROM_HERE,
489 base::Bind(callback, REJECTED));; 478 base::Bind(callback, REJECTED));;
490 return; 479 return;
491 } 480 }
492 481
493 ResetTCPSocket(); 482 ResetTCPSocket();
494 483
495 // Note: We don't have a meaningful |IPEndPoint|, but that is ok since the 484 // Note: We don't have a meaningful |IPEndPoint|, but that is ok since the
496 // TCPSocket implementation does not actually require one. 485 // TCPSocket implementation does not actually require one.
497 int net_result = tcp_socket()->AdoptConnectedSocket(fd->value(), 486 int net_result = tcp_socket()->AdoptConnectedSocket(fd->value(),
498 net::IPEndPoint()); 487 net::IPEndPoint());
499 if (net_result != net::OK) { 488 if (net_result != net::OK) {
500 LOG(WARNING) << object_path_.value() << ": Error adopting socket: " 489 LOG(WARNING) << uuid_.canonical_value() << ": Error adopting socket: "
501 << std::string(net::ErrorToString(net_result)); 490 << std::string(net::ErrorToString(net_result));
502 ui_task_runner()->PostTask(FROM_HERE, 491 ui_task_runner()->PostTask(FROM_HERE,
503 base::Bind(callback, REJECTED));; 492 base::Bind(callback, REJECTED));;
504 return; 493 return;
505 } 494 }
506 495
507 VLOG(2) << object_path_.value() << ": Taking descriptor, confirming success."; 496 VLOG(2) << uuid_.canonical_value()
497 << ": Taking descriptor, confirming success.";
508 fd->TakeValue(); 498 fd->TakeValue();
509 ui_task_runner()->PostTask(FROM_HERE, 499 ui_task_runner()->PostTask(FROM_HERE,
510 base::Bind(callback, SUCCESS));; 500 base::Bind(callback, SUCCESS));;
511 } 501 }
512 502
513 void BluetoothSocketChromeOS::OnNewConnection( 503 void BluetoothSocketChromeOS::OnNewConnection(
514 scoped_refptr<BluetoothSocket> socket, 504 scoped_refptr<BluetoothSocket> socket,
515 const ConfirmationCallback& callback, 505 const ConfirmationCallback& callback,
516 Status status) { 506 Status status) {
517 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); 507 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
(...skipping 29 matching lines...) Expand all
547 537
548 while (connection_request_queue_.size() > 0) { 538 while (connection_request_queue_.size() > 0) {
549 linked_ptr<ConnectionRequest> request = connection_request_queue_.front(); 539 linked_ptr<ConnectionRequest> request = connection_request_queue_.front();
550 request->callback.Run(REJECTED); 540 request->callback.Run(REJECTED);
551 connection_request_queue_.pop(); 541 connection_request_queue_.pop();
552 } 542 }
553 } 543 }
554 544
555 void BluetoothSocketChromeOS::UnregisterProfile() { 545 void BluetoothSocketChromeOS::UnregisterProfile() {
556 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); 546 DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
557 DCHECK(!object_path_.value().empty()); 547 DCHECK(profile_);
558 DCHECK(profile_.get());
559 548
560 VLOG(1) << object_path_.value() << ": Unregister profile"; 549 VLOG(1) << profile_->object_path().value() << ": Release profile";
561 DBusThreadManager::Get()->GetBluetoothProfileManagerClient()->
562 UnregisterProfile(
563 object_path_,
564 base::Bind(&BluetoothSocketChromeOS::OnUnregisterProfile,
565 this,
566 object_path_),
567 base::Bind(&BluetoothSocketChromeOS::OnUnregisterProfileError,
568 this,
569 object_path_));
570 550
571 profile_.reset(); 551 profile_->RemoveDelegate(
572 object_path_ = dbus::ObjectPath(""); 552 device_path_,
553 base::Bind(&BluetoothSocketChromeOS::ReleaseProfile, this, profile_));
554
555 profile_ = nullptr;
573 } 556 }
574 557
575 void BluetoothSocketChromeOS::OnUnregisterProfile( 558 void BluetoothSocketChromeOS::ReleaseProfile(
576 const dbus::ObjectPath& object_path) { 559 BluetoothAdapterProfileChromeOS* profile) {
577 VLOG(1) << object_path.value() << ": Profile unregistered"; 560 if (adapter_)
578 } 561 static_cast<BluetoothAdapterChromeOS*>(adapter_.get())
579 562 ->ReleaseProfile(uuid_);
580 void BluetoothSocketChromeOS::OnUnregisterProfileError( 563 else
581 const dbus::ObjectPath& object_path, 564 delete profile;
582 const std::string& error_name,
583 const std::string& error_message) {
584 // It's okay if the profile doesn't exist, it means we haven't registered it
585 // yet.
586 if (error_name == bluetooth_profile_manager::kErrorDoesNotExist)
587 return;
588
589 LOG(WARNING) << object_path_.value() << ": Failed to unregister profile: "
590 << error_name << ": " << error_message;
591 } 565 }
592 566
593 } // namespace chromeos 567 } // namespace chromeos
OLDNEW
« no previous file with comments | « device/bluetooth/bluetooth_socket_chromeos.h ('k') | device/bluetooth/bluetooth_socket_chromeos_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698