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

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

Issue 15020009: Bluetooth: remove legacy backend (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 7 years, 7 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "device/bluetooth/bluetooth_device_chromeos.h"
6
7 #include <map>
8 #include <string>
9 #include <vector>
10
11 #include "base/bind.h"
12 #include "base/command_line.h"
13 #include "base/logging.h"
14 #include "base/memory/scoped_vector.h"
15 #include "base/memory/weak_ptr.h"
16 #include "base/string16.h"
17 #include "base/string_util.h"
18 #include "base/values.h"
19 #include "chromeos/dbus/bluetooth_adapter_client.h"
20 #include "chromeos/dbus/bluetooth_agent_service_provider.h"
21 #include "chromeos/dbus/bluetooth_device_client.h"
22 #include "chromeos/dbus/bluetooth_input_client.h"
23 #include "chromeos/dbus/bluetooth_out_of_band_client.h"
24 #include "chromeos/dbus/dbus_thread_manager.h"
25 #include "chromeos/dbus/introspectable_client.h"
26 #include "dbus/bus.h"
27 #include "dbus/object_path.h"
28 #include "device/bluetooth/bluetooth_adapter_chromeos.h"
29 #include "device/bluetooth/bluetooth_out_of_band_pairing_data.h"
30 #include "device/bluetooth/bluetooth_service_record.h"
31 #include "device/bluetooth/bluetooth_service_record_chromeos.h"
32 #include "device/bluetooth/bluetooth_socket_chromeos.h"
33 #include "device/bluetooth/bluetooth_utils.h"
34 #include "third_party/cros_system_api/dbus/service_constants.h"
35
36 using device::BluetoothDevice;
37 using device::BluetoothOutOfBandPairingData;
38 using device::BluetoothServiceRecord;
39 using device::BluetoothSocket;
40
41 namespace {
42
43 void DoNothingServiceRecordList(const BluetoothDevice::ServiceRecordList&) {}
44
45 } // namespace
46
47 namespace chromeos {
48
49 BluetoothDeviceChromeOS::BluetoothDeviceChromeOS(
50 BluetoothAdapterChromeOS* adapter)
51 : BluetoothDevice(),
52 adapter_(adapter),
53 bluetooth_class_(0),
54 paired_(false),
55 trusted_(false),
56 connected_(false),
57 connectable_(true),
58 connecting_(false),
59 pairing_delegate_(NULL),
60 connecting_applications_counter_(0),
61 connecting_calls_(0),
62 service_records_loaded_(false),
63 weak_ptr_factory_(this) {
64 }
65
66 BluetoothDeviceChromeOS::~BluetoothDeviceChromeOS() {
67 }
68
69 uint32 BluetoothDeviceChromeOS::GetBluetoothClass() const {
70 return bluetooth_class_;
71 }
72
73 std::string BluetoothDeviceChromeOS::GetDeviceName() const {
74 return name_;
75 }
76
77 std::string BluetoothDeviceChromeOS::GetAddress() const {
78 return address_;
79 }
80
81 uint16 BluetoothDeviceChromeOS::GetVendorID() const {
82 return 0;
83 }
84
85 uint16 BluetoothDeviceChromeOS::GetProductID() const {
86 return 0;
87 }
88
89 uint16 BluetoothDeviceChromeOS::GetDeviceID() const {
90 return 0;
91 }
92
93 bool BluetoothDeviceChromeOS::IsPaired() const {
94 return paired_ || trusted_;
95 }
96
97 bool BluetoothDeviceChromeOS::IsConnected() const {
98 return connected_;
99 }
100
101 bool BluetoothDeviceChromeOS::IsConnectable() const {
102 return connectable_;
103 }
104
105 bool BluetoothDeviceChromeOS::IsConnecting() const {
106 return connecting_;
107 }
108
109 BluetoothDeviceChromeOS::ServiceList
110 BluetoothDeviceChromeOS::GetServices() const {
111 return service_uuids_;
112 }
113
114 void BluetoothDeviceChromeOS::GetServiceRecords(
115 const ServiceRecordsCallback& callback,
116 const ErrorCallback& error_callback) {
117 DBusThreadManager::Get()->GetBluetoothDeviceClient()->
118 DiscoverServices(
119 object_path_,
120 "", // empty pattern to browse all services
121 base::Bind(&BluetoothDeviceChromeOS::CollectServiceRecordsCallback,
122 weak_ptr_factory_.GetWeakPtr(),
123 callback,
124 base::Bind(
125 &BluetoothDeviceChromeOS::OnGetServiceRecordsError,
126 weak_ptr_factory_.GetWeakPtr(),
127 callback,
128 error_callback)));
129 }
130
131 void BluetoothDeviceChromeOS::ProvidesServiceWithName(
132 const std::string& name,
133 const ProvidesServiceCallback& callback) {
134 GetServiceRecords(
135 base::Bind(&BluetoothDeviceChromeOS::SearchServicesForNameCallback,
136 weak_ptr_factory_.GetWeakPtr(),
137 name,
138 callback),
139 base::Bind(&BluetoothDeviceChromeOS::SearchServicesForNameErrorCallback,
140 weak_ptr_factory_.GetWeakPtr(),
141 callback));
142 }
143
144 bool BluetoothDeviceChromeOS::ExpectingPinCode() const {
145 return !pincode_callback_.is_null();
146 }
147
148 bool BluetoothDeviceChromeOS::ExpectingPasskey() const {
149 return !passkey_callback_.is_null();
150 }
151
152 bool BluetoothDeviceChromeOS::ExpectingConfirmation() const {
153 return !confirmation_callback_.is_null();
154 }
155
156 void BluetoothDeviceChromeOS::Connect(
157 PairingDelegate* pairing_delegate,
158 const base::Closure& callback,
159 const ConnectErrorCallback& error_callback) {
160 // This is safe because Connect() and its callbacks are called in the same
161 // thread.
162 connecting_calls_++;
163 if (!connecting_) {
164 connecting_ = true;
165 adapter_->NotifyDeviceChanged(this);
166 }
167 connecting_ = !!connecting_calls_;
168 // Set the decrement to be issued when either callback is called.
169 base::Closure wrapped_callback = base::Bind(
170 &BluetoothDeviceChromeOS::OnConnectCallbackCalled,
171 weak_ptr_factory_.GetWeakPtr(),
172 callback);
173 ConnectErrorCallback wrapped_error_callback = base::Bind(
174 &BluetoothDeviceChromeOS::OnConnectErrorCallbackCalled,
175 weak_ptr_factory_.GetWeakPtr(),
176 error_callback);
177
178 if (IsPaired()) {
179 // Connection to already paired device.
180 ConnectApplications(wrapped_callback, wrapped_error_callback);
181
182 } else if (!pairing_delegate || !IsPairable()) {
183 // No pairing delegate supplied, or unpairable device; initiate
184 // low-security connection only.
185 DBusThreadManager::Get()->GetBluetoothAdapterClient()->
186 CreateDevice(adapter_->object_path_,
187 address_,
188 base::Bind(&BluetoothDeviceChromeOS::OnCreateDevice,
189 weak_ptr_factory_.GetWeakPtr(),
190 wrapped_callback,
191 wrapped_error_callback),
192 base::Bind(&BluetoothDeviceChromeOS::OnCreateDeviceError,
193 weak_ptr_factory_.GetWeakPtr(),
194 wrapped_error_callback));
195 } else {
196 // Initiate high-security connection with pairing.
197 DCHECK(!pairing_delegate_);
198 pairing_delegate_ = pairing_delegate;
199
200 // The agent path is relatively meaningless, we use the device address
201 // to generate it as we only support one pairing attempt at a time for
202 // a given bluetooth device.
203 DCHECK(agent_.get() == NULL);
204
205 std::string agent_path_basename;
206 ReplaceChars(address_, ":", "_", &agent_path_basename);
207 dbus::ObjectPath agent_path("/org/chromium/bluetooth_agent/" +
208 agent_path_basename);
209
210 dbus::Bus* system_bus = DBusThreadManager::Get()->GetSystemBus();
211 if (system_bus) {
212 agent_.reset(BluetoothAgentServiceProvider::Create(system_bus,
213 agent_path,
214 this));
215 } else {
216 agent_.reset(NULL);
217 }
218
219 VLOG(1) << "Pairing: " << address_;
220 DBusThreadManager::Get()->GetBluetoothAdapterClient()->
221 CreatePairedDevice(
222 adapter_->object_path_,
223 address_,
224 agent_path,
225 bluetooth_agent::kDisplayYesNoCapability,
226 base::Bind(&BluetoothDeviceChromeOS::OnCreateDevice,
227 weak_ptr_factory_.GetWeakPtr(),
228 wrapped_callback,
229 wrapped_error_callback),
230 base::Bind(&BluetoothDeviceChromeOS::OnCreateDeviceError,
231 weak_ptr_factory_.GetWeakPtr(),
232 wrapped_error_callback));
233 }
234 }
235
236 void BluetoothDeviceChromeOS::SetPinCode(const std::string& pincode) {
237 if (!agent_.get() || pincode_callback_.is_null())
238 return;
239
240 pincode_callback_.Run(SUCCESS, pincode);
241 pincode_callback_.Reset();
242 }
243
244 void BluetoothDeviceChromeOS::SetPasskey(uint32 passkey) {
245 if (!agent_.get() || passkey_callback_.is_null())
246 return;
247
248 passkey_callback_.Run(SUCCESS, passkey);
249 passkey_callback_.Reset();
250 }
251
252 void BluetoothDeviceChromeOS::ConfirmPairing() {
253 if (!agent_.get() || confirmation_callback_.is_null())
254 return;
255
256 confirmation_callback_.Run(SUCCESS);
257 confirmation_callback_.Reset();
258 }
259
260 void BluetoothDeviceChromeOS::RejectPairing() {
261 if (!agent_.get())
262 return;
263
264 if (!pincode_callback_.is_null()) {
265 pincode_callback_.Run(REJECTED, "");
266 pincode_callback_.Reset();
267 }
268 if (!passkey_callback_.is_null()) {
269 passkey_callback_.Run(REJECTED, 0);
270 passkey_callback_.Reset();
271 }
272 if (!confirmation_callback_.is_null()) {
273 confirmation_callback_.Run(REJECTED);
274 confirmation_callback_.Reset();
275 }
276 }
277
278 void BluetoothDeviceChromeOS::CancelPairing() {
279 bool have_callback = false;
280 if (agent_.get()) {
281 if (!pincode_callback_.is_null()) {
282 pincode_callback_.Run(CANCELLED, "");
283 pincode_callback_.Reset();
284 have_callback = true;
285 }
286 if (!passkey_callback_.is_null()) {
287 passkey_callback_.Run(CANCELLED, 0);
288 passkey_callback_.Reset();
289 have_callback = true;
290 }
291 if (!confirmation_callback_.is_null()) {
292 confirmation_callback_.Run(CANCELLED);
293 confirmation_callback_.Reset();
294 have_callback = true;
295 }
296 }
297
298 if (!have_callback) {
299 // User cancels the pairing process.
300 DBusThreadManager::Get()->GetBluetoothAdapterClient()->CancelDeviceCreation(
301 adapter_->object_path_,
302 address_,
303 base::Bind(&BluetoothDeviceChromeOS::OnCancelDeviceCreation,
304 weak_ptr_factory_.GetWeakPtr()));
305
306 pairing_delegate_ = NULL;
307 agent_.reset();
308 }
309 }
310
311 void BluetoothDeviceChromeOS::Disconnect(const base::Closure& callback,
312 const ErrorCallback& error_callback) {
313 DBusThreadManager::Get()->GetBluetoothDeviceClient()->
314 Disconnect(object_path_,
315 base::Bind(&BluetoothDeviceChromeOS::DisconnectCallback,
316 weak_ptr_factory_.GetWeakPtr(),
317 callback,
318 error_callback));
319
320 }
321
322 void BluetoothDeviceChromeOS::Forget(const ErrorCallback& error_callback) {
323 DBusThreadManager::Get()->GetBluetoothAdapterClient()->
324 RemoveDevice(adapter_->object_path_,
325 object_path_,
326 base::Bind(&BluetoothDeviceChromeOS::ForgetCallback,
327 weak_ptr_factory_.GetWeakPtr(),
328 error_callback));
329 }
330
331 void BluetoothDeviceChromeOS::ConnectToService(const std::string& service_uuid,
332 const SocketCallback& callback) {
333 GetServiceRecords(
334 base::Bind(&BluetoothDeviceChromeOS::GetServiceRecordsForConnectCallback,
335 weak_ptr_factory_.GetWeakPtr(),
336 service_uuid,
337 callback),
338 base::Bind(
339 &BluetoothDeviceChromeOS::GetServiceRecordsForConnectErrorCallback,
340 weak_ptr_factory_.GetWeakPtr(),
341 callback));
342 }
343
344 void BluetoothDeviceChromeOS::ConnectToProfile(
345 device::BluetoothProfile* profile,
346 const base::Closure& callback,
347 const ErrorCallback& error_callback) {
348 // TODO(keybuk): implement
349 }
350
351 void BluetoothDeviceChromeOS::SetOutOfBandPairingData(
352 const BluetoothOutOfBandPairingData& data,
353 const base::Closure& callback,
354 const ErrorCallback& error_callback) {
355 DBusThreadManager::Get()->GetBluetoothOutOfBandClient()->
356 AddRemoteData(
357 object_path_,
358 address_,
359 data,
360 base::Bind(&BluetoothDeviceChromeOS::OnRemoteDataCallback,
361 weak_ptr_factory_.GetWeakPtr(),
362 callback,
363 error_callback));
364 }
365
366 void BluetoothDeviceChromeOS::ClearOutOfBandPairingData(
367 const base::Closure& callback,
368 const ErrorCallback& error_callback) {
369 DBusThreadManager::Get()->GetBluetoothOutOfBandClient()->
370 RemoveRemoteData(
371 object_path_,
372 address_,
373 base::Bind(&BluetoothDeviceChromeOS::OnRemoteDataCallback,
374 weak_ptr_factory_.GetWeakPtr(),
375 callback,
376 error_callback));
377 }
378
379 void BluetoothDeviceChromeOS::SetObjectPath(
380 const dbus::ObjectPath& object_path) {
381 DCHECK(object_path_ == dbus::ObjectPath(""));
382 object_path_ = object_path;
383 }
384
385 void BluetoothDeviceChromeOS::RemoveObjectPath() {
386 DCHECK(object_path_ != dbus::ObjectPath(""));
387 object_path_ = dbus::ObjectPath("");
388 }
389
390 void BluetoothDeviceChromeOS::Update(
391 const BluetoothDeviceClient::Properties* properties,
392 bool update_state) {
393 std::string address = properties->address.value();
394 std::string name = properties->name.value();
395 uint32 bluetooth_class = properties->bluetooth_class.value();
396 const std::vector<std::string>& uuids = properties->uuids.value();
397
398 if (!address.empty())
399 address_ = address;
400 if (!name.empty())
401 name_ = name;
402 if (bluetooth_class)
403 bluetooth_class_ = bluetooth_class;
404 if (!uuids.empty()) {
405 service_uuids_.clear();
406 service_uuids_.assign(uuids.begin(), uuids.end());
407 }
408
409 if (update_state) {
410 // When the device reconnects and we don't have any service records for it,
411 // try to update the cache or fail silently.
412 if (!service_records_loaded_ && !connected_ &&
413 properties->connected.value())
414 GetServiceRecords(base::Bind(&DoNothingServiceRecordList),
415 base::Bind(&base::DoNothing));
416
417 paired_ = properties->paired.value();
418 trusted_ = properties->trusted.value();
419 connected_ = properties->connected.value();
420 }
421 }
422
423 void BluetoothDeviceChromeOS::OnCreateDevice(
424 const base::Closure& callback,
425 const ConnectErrorCallback& error_callback,
426 const dbus::ObjectPath& device_path) {
427 VLOG(1) << "Connection successful: " << device_path.value();
428 if (object_path_.value().empty()) {
429 object_path_ = device_path;
430 } else {
431 LOG_IF(WARNING, object_path_ != device_path)
432 << "Conflicting device paths for objects, result gave: "
433 << device_path.value() << " but signal gave: "
434 << object_path_.value();
435 }
436
437 SetTrusted();
438
439 // In parallel with the |trusted| property change, call GetServiceRecords to
440 // retrieve the SDP from the device and then, either on success or failure,
441 // call ConnectApplications.
442 GetServiceRecords(
443 base::Bind(&BluetoothDeviceChromeOS::OnInitialGetServiceRecords,
444 weak_ptr_factory_.GetWeakPtr(),
445 callback,
446 error_callback),
447 base::Bind(&BluetoothDeviceChromeOS::OnInitialGetServiceRecordsError,
448 weak_ptr_factory_.GetWeakPtr(),
449 callback,
450 error_callback));
451 }
452
453 void BluetoothDeviceChromeOS::OnCreateDeviceError(
454 const ConnectErrorCallback& error_callback,
455 const std::string& error_name,
456 const std::string& error_message) {
457 // The default |error_code| is an unknown error.
458 ConnectErrorCode error_code = ERROR_UNKNOWN;
459
460 // Report any error in the log, even if we know the possible source of it.
461 LOG(WARNING) << "Connection failed (on CreatePairedDevice): "
462 << "\"" << name_ << "\" (" << address_ << "): "
463 << error_name << ": \"" << error_message << "\"";
464
465 // Determines the right error code from error_name, assuming the error name
466 // comes from CreatePairedDevice bluez function.
467 if (error_name == bluetooth_adapter::kErrorConnectionAttemptFailed) {
468 error_code = ERROR_FAILED;
469 } else if (error_name == bluetooth_adapter::kErrorAuthenticationFailed) {
470 error_code = ERROR_AUTH_FAILED;
471 } else if (error_name == bluetooth_adapter::kErrorAuthenticationRejected) {
472 error_code = ERROR_AUTH_REJECTED;
473 } else if (error_name == bluetooth_adapter::kErrorAuthenticationTimeout) {
474 error_code = ERROR_AUTH_TIMEOUT;
475 }
476 error_callback.Run(error_code);
477 }
478
479 void BluetoothDeviceChromeOS::CollectServiceRecordsCallback(
480 const ServiceRecordsCallback& callback,
481 const ErrorCallback& error_callback,
482 const dbus::ObjectPath& device_path,
483 const BluetoothDeviceClient::ServiceMap& service_map,
484 bool success) {
485 if (!success) {
486 error_callback.Run();
487 return;
488 }
489
490 // Update the cache. No other thread is executing a GetServiceRecords
491 // callback, so it is safe to delete the previous objects here.
492 service_records_.clear();
493 // TODO(deymo): Perhaps don't update the cache if the new SDP information is
494 // empty and we had something before. Some devices only answer this
495 // information while paired, and this callback could be called in any order if
496 // several calls to GetServiceRecords are made while initial pairing with the
497 // device. This requires more investigation.
498 for (BluetoothDeviceClient::ServiceMap::const_iterator i =
499 service_map.begin(); i != service_map.end(); ++i) {
500 service_records_.push_back(
501 new BluetoothServiceRecordChromeOS(address_, i->second));
502 }
503 service_records_loaded_ = true;
504
505 callback.Run(service_records_);
506 }
507
508 void BluetoothDeviceChromeOS::SetTrusted() {
509 // Unconditionally send the property change, rather than checking the value
510 // first; there's no harm in doing this and it solves any race conditions
511 // with the property becoming true or false and this call happening before
512 // we get the D-Bus signal about the earlier change.
513 DBusThreadManager::Get()->GetBluetoothDeviceClient()->
514 GetProperties(object_path_)->trusted.Set(
515 true,
516 base::Bind(
517 &BluetoothDeviceChromeOS::OnSetTrusted,
518 weak_ptr_factory_.GetWeakPtr()));
519 }
520
521 void BluetoothDeviceChromeOS::OnSetTrusted(bool success) {
522 LOG_IF(WARNING, !success) << "Failed to set device as trusted: " << address_;
523 }
524
525 void BluetoothDeviceChromeOS::OnInitialGetServiceRecords(
526 const base::Closure& callback,
527 const ConnectErrorCallback& error_callback,
528 const ServiceRecordList& list) {
529 // Connect application-layer protocols.
530 ConnectApplications(callback, error_callback);
531 }
532
533 void BluetoothDeviceChromeOS::OnInitialGetServiceRecordsError(
534 const base::Closure& callback,
535 const ConnectErrorCallback& error_callback) {
536 // Ignore the error retrieving the service records and continue.
537 LOG(WARNING) << "Error retrieving SDP for " << address_ << " after pairing.";
538 // Connect application-layer protocols.
539 ConnectApplications(callback, error_callback);
540 }
541
542 void BluetoothDeviceChromeOS::OnGetServiceRecordsError(
543 const ServiceRecordsCallback& callback,
544 const ErrorCallback& error_callback) {
545 if (service_records_loaded_) {
546 callback.Run(service_records_);
547 } else {
548 error_callback.Run();
549 }
550 }
551
552 void BluetoothDeviceChromeOS::OnConnectCallbackCalled(
553 const base::Closure& callback) {
554 // Update the connecting status.
555 bool prev_connecting = connecting_;
556 connecting_calls_--;
557 connecting_ = !!connecting_calls_;
558 callback.Run();
559 if (prev_connecting != connecting_) adapter_->NotifyDeviceChanged(this);
560 }
561
562 void BluetoothDeviceChromeOS::OnConnectErrorCallbackCalled(
563 const ConnectErrorCallback& error_callback,
564 enum ConnectErrorCode error_code) {
565 // Update the connecting status.
566 bool prev_connecting = connecting_;
567 connecting_calls_--;
568 connecting_ = !!connecting_calls_;
569 error_callback.Run(error_code);
570 if (prev_connecting != connecting_) adapter_->NotifyDeviceChanged(this);
571 }
572
573 void BluetoothDeviceChromeOS::ConnectApplications(
574 const base::Closure& callback,
575 const ConnectErrorCallback& error_callback) {
576 // Introspect the device object to determine supported applications.
577 DBusThreadManager::Get()->GetIntrospectableClient()->
578 Introspect(bluetooth_device::kBluetoothDeviceServiceName,
579 object_path_,
580 base::Bind(&BluetoothDeviceChromeOS::OnIntrospect,
581 weak_ptr_factory_.GetWeakPtr(),
582 callback,
583 error_callback));
584 }
585
586 void BluetoothDeviceChromeOS::OnIntrospect(
587 const base::Closure& callback,
588 const ConnectErrorCallback& error_callback,
589 const std::string& service_name,
590 const dbus::ObjectPath& device_path,
591 const std::string& xml_data,
592 bool success) {
593 if (!success) {
594 LOG(WARNING) << "Failed to determine supported applications: " << address_;
595 error_callback.Run(ERROR_UNKNOWN);
596 return;
597 }
598
599 // The introspection data for the device object may list one or more
600 // additional D-Bus interfaces that BlueZ supports for this particular
601 // device. Send appropraite Connect calls for each of those interfaces
602 // to connect all of the application protocols for this device.
603 std::vector<std::string> interfaces =
604 IntrospectableClient::GetInterfacesFromIntrospectResult(xml_data);
605
606 DCHECK_EQ(0, connecting_applications_counter_);
607 connecting_applications_counter_ = 0;
608 for (std::vector<std::string>::iterator iter = interfaces.begin();
609 iter != interfaces.end(); ++iter) {
610 if (*iter == bluetooth_input::kBluetoothInputInterface) {
611 connecting_applications_counter_++;
612 // Supports Input interface.
613 DBusThreadManager::Get()->GetBluetoothInputClient()->
614 Connect(object_path_,
615 base::Bind(&BluetoothDeviceChromeOS::OnConnect,
616 weak_ptr_factory_.GetWeakPtr(),
617 callback,
618 *iter),
619 base::Bind(&BluetoothDeviceChromeOS::OnConnectError,
620 weak_ptr_factory_.GetWeakPtr(),
621 error_callback, *iter));
622 }
623 }
624
625 // If OnConnect has been called for every call to Connect above, then this
626 // will decrement the counter to -1. In that case, call the callback
627 // directly as it has not been called by any of the OnConnect callbacks.
628 // This is safe because OnIntrospect and OnConnect run on the same thread.
629 connecting_applications_counter_--;
630 if (connecting_applications_counter_ == -1)
631 callback.Run();
632 }
633
634 void BluetoothDeviceChromeOS::OnConnect(const base::Closure& callback,
635 const std::string& interface_name,
636 const dbus::ObjectPath& device_path) {
637 VLOG(1) << "Application connection successful: " << device_path.value()
638 << ": " << interface_name;
639
640 connecting_applications_counter_--;
641 // |callback| should only be called once, meaning it cannot be called before
642 // all requests have been started. The extra decrement after all requests
643 // have been started, and the check for -1 instead of 0 below, insure only a
644 // single call to |callback| will occur (provided OnConnect and OnIntrospect
645 // run on the same thread, which is true).
646 if (connecting_applications_counter_ == -1) {
647 connecting_applications_counter_ = 0;
648 SetTrusted();
649 callback.Run();
650 }
651 }
652
653 void BluetoothDeviceChromeOS::OnConnectError(
654 const ConnectErrorCallback& error_callback,
655 const std::string& interface_name,
656 const dbus::ObjectPath& device_path,
657 const std::string& error_name,
658 const std::string& error_message) {
659 // The default |error_code| is an unknown error.
660 ConnectErrorCode error_code = ERROR_UNKNOWN;
661
662 // Report any error in the log, even if we know the possible source of it.
663 LOG(WARNING) << "Connection failed (on Connect): "
664 << interface_name << ": "
665 << "\"" << name_ << "\" (" << address_ << "): "
666 << error_name << ": \"" << error_message << "\"";
667
668 // Determines the right error code from error_name, assuming the error name
669 // comes from Connect bluez function.
670 if (error_name == bluetooth_adapter::kErrorFailed) {
671 error_code = ERROR_FAILED;
672 } else if (error_name == bluetooth_adapter::kErrorInProgress) {
673 error_code = ERROR_INPROGRESS;
674 } else if (error_name == bluetooth_adapter::kErrorNotSupported) {
675 error_code = ERROR_UNSUPPORTED_DEVICE;
676 }
677
678 error_callback.Run(error_code);
679 }
680
681 void BluetoothDeviceChromeOS::DisconnectCallback(
682 const base::Closure& callback,
683 const ErrorCallback& error_callback,
684 const dbus::ObjectPath& device_path,
685 bool success) {
686 DCHECK(device_path == object_path_);
687 if (success) {
688 VLOG(1) << "Disconnection successful: " << address_;
689 callback.Run();
690 } else {
691 if (connected_) {
692 LOG(WARNING) << "Disconnection failed: " << address_;
693 error_callback.Run();
694 } else {
695 VLOG(1) << "Disconnection failed on a already disconnected device: "
696 << address_;
697 callback.Run();
698 }
699 }
700 }
701
702 void BluetoothDeviceChromeOS::ForgetCallback(
703 const ErrorCallback& error_callback,
704 const dbus::ObjectPath& adapter_path,
705 bool success) {
706 // It's quite normal that this path never gets called on success; we use a
707 // weak pointer, and bluetoothd might send the DeviceRemoved signal before
708 // the method reply, in which case this object is deleted and the
709 // callback never takes place. Therefore don't do anything here for the
710 // success case.
711 if (!success) {
712 LOG(WARNING) << "Forget failed: " << address_;
713 error_callback.Run();
714 }
715 }
716
717 void BluetoothDeviceChromeOS::OnCancelDeviceCreation(
718 const dbus::ObjectPath& adapter_path,
719 bool success) {
720 if (!success)
721 LOG(WARNING) << "CancelDeviceCreation failed: " << address_;
722 }
723
724 void BluetoothDeviceChromeOS::SearchServicesForNameErrorCallback(
725 const ProvidesServiceCallback& callback) {
726 callback.Run(false);
727 }
728
729 void BluetoothDeviceChromeOS::SearchServicesForNameCallback(
730 const std::string& name,
731 const ProvidesServiceCallback& callback,
732 const ServiceRecordList& list) {
733 for (ServiceRecordList::const_iterator i = list.begin();
734 i != list.end(); ++i) {
735 if ((*i)->name() == name) {
736 callback.Run(true);
737 return;
738 }
739 }
740 callback.Run(false);
741 }
742
743 void BluetoothDeviceChromeOS::GetServiceRecordsForConnectErrorCallback(
744 const SocketCallback& callback) {
745 callback.Run(NULL);
746 }
747
748 void BluetoothDeviceChromeOS::GetServiceRecordsForConnectCallback(
749 const std::string& service_uuid,
750 const SocketCallback& callback,
751 const ServiceRecordList& list) {
752 for (ServiceRecordList::const_iterator i = list.begin();
753 i != list.end(); ++i) {
754 if ((*i)->uuid() == service_uuid) {
755 // If multiple service records are found, use the first one that works.
756 scoped_refptr<BluetoothSocket> socket(
757 BluetoothSocketChromeOS::CreateBluetoothSocket(**i));
758 if (socket.get() != NULL) {
759 callback.Run(socket);
760 return;
761 }
762 }
763 }
764 callback.Run(NULL);
765 }
766
767 void BluetoothDeviceChromeOS::OnRemoteDataCallback(
768 const base::Closure& callback,
769 const ErrorCallback& error_callback,
770 bool success) {
771 if (success)
772 callback.Run();
773 else
774 error_callback.Run();
775 }
776
777 void BluetoothDeviceChromeOS::DisconnectRequested(
778 const dbus::ObjectPath& object_path) {
779 DCHECK(object_path == object_path_);
780 }
781
782 void BluetoothDeviceChromeOS::Release() {
783 DCHECK(agent_.get());
784 VLOG(1) << "Release: " << address_;
785
786 DCHECK(pairing_delegate_);
787 pairing_delegate_->DismissDisplayOrConfirm();
788 pairing_delegate_ = NULL;
789
790 pincode_callback_.Reset();
791 passkey_callback_.Reset();
792 confirmation_callback_.Reset();
793
794 agent_.reset();
795 }
796
797 void BluetoothDeviceChromeOS::RequestPinCode(
798 const dbus::ObjectPath& device_path,
799 const PinCodeCallback& callback) {
800 DCHECK(agent_.get());
801 VLOG(1) << "RequestPinCode: " << device_path.value();
802
803 DCHECK(pairing_delegate_);
804 DCHECK(pincode_callback_.is_null());
805 pincode_callback_ = callback;
806 pairing_delegate_->RequestPinCode(this);
807 }
808
809 void BluetoothDeviceChromeOS::RequestPasskey(
810 const dbus::ObjectPath& device_path,
811 const PasskeyCallback& callback) {
812 DCHECK(agent_.get());
813 DCHECK(device_path == object_path_);
814 VLOG(1) << "RequestPasskey: " << device_path.value();
815
816 DCHECK(pairing_delegate_);
817 DCHECK(passkey_callback_.is_null());
818 passkey_callback_ = callback;
819 pairing_delegate_->RequestPasskey(this);
820 }
821
822 void BluetoothDeviceChromeOS::DisplayPinCode(
823 const dbus::ObjectPath& device_path,
824 const std::string& pincode) {
825 DCHECK(agent_.get());
826 DCHECK(device_path == object_path_);
827 VLOG(1) << "DisplayPinCode: " << device_path.value() << " " << pincode;
828
829 DCHECK(pairing_delegate_);
830 pairing_delegate_->DisplayPinCode(this, pincode);
831 }
832
833 void BluetoothDeviceChromeOS::DisplayPasskey(
834 const dbus::ObjectPath& device_path,
835 uint32 passkey) {
836 DCHECK(agent_.get());
837 DCHECK(device_path == object_path_);
838 VLOG(1) << "DisplayPasskey: " << device_path.value() << " " << passkey;
839
840 DCHECK(pairing_delegate_);
841 pairing_delegate_->DisplayPasskey(this, passkey);
842 }
843
844 void BluetoothDeviceChromeOS::RequestConfirmation(
845 const dbus::ObjectPath& device_path,
846 uint32 passkey,
847 const ConfirmationCallback& callback) {
848 DCHECK(agent_.get());
849 DCHECK(device_path == object_path_);
850 VLOG(1) << "RequestConfirmation: " << device_path.value() << " " << passkey;
851
852 DCHECK(pairing_delegate_);
853 DCHECK(confirmation_callback_.is_null());
854 confirmation_callback_ = callback;
855 pairing_delegate_->ConfirmPasskey(this, passkey);
856 }
857
858 void BluetoothDeviceChromeOS::Authorize(const dbus::ObjectPath& device_path,
859 const std::string& uuid,
860 const ConfirmationCallback& callback) {
861 DCHECK(agent_.get());
862 DCHECK(device_path == object_path_);
863 LOG(WARNING) << "Rejected authorization for service: " << uuid
864 << " requested from device: " << device_path.value();
865 callback.Run(REJECTED);
866 }
867
868 void BluetoothDeviceChromeOS::ConfirmModeChange(
869 Mode mode,
870 const ConfirmationCallback& callback) {
871 DCHECK(agent_.get());
872 LOG(WARNING) << "Rejected adapter-level mode change: " << mode
873 << " made on agent for device: " << address_;
874 callback.Run(REJECTED);
875 }
876
877 void BluetoothDeviceChromeOS::Cancel() {
878 DCHECK(agent_.get());
879 VLOG(1) << "Cancel: " << address_;
880
881 DCHECK(pairing_delegate_);
882 pairing_delegate_->DismissDisplayOrConfirm();
883 }
884
885
886 // static
887 BluetoothDeviceChromeOS* BluetoothDeviceChromeOS::Create(
888 BluetoothAdapterChromeOS* adapter) {
889 return new BluetoothDeviceChromeOS(adapter);
890 }
891
892 } // namespace chromeos
OLDNEW
« no previous file with comments | « device/bluetooth/bluetooth_device_chromeos.h ('k') | device/bluetooth/bluetooth_service_record_chromeos.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698