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
3 // found in the LICENSE file.
5 #include "device/bluetooth/bluetooth_adapter_profile_chromeos.h"
10 #include "base/logging.h"
11 #include "base/strings/string_util.h"
12 #include "chromeos/dbus/bluetooth_profile_service_provider.h"
13 #include "chromeos/dbus/dbus_thread_manager.h"
15 #include "dbus/object_path.h"
16 #include "device/bluetooth/bluetooth_adapter_chromeos.h"
17 #include "device/bluetooth/bluetooth_uuid.h"
22 BluetoothAdapterProfileChromeOS
* BluetoothAdapterProfileChromeOS::Register(
23 const device::BluetoothUUID
& uuid
,
24 const BluetoothProfileManagerClient::Options
& options
,
25 const BluetoothAdapterChromeOS::ProfileRegisteredCallback
& success_callback
,
26 const BluetoothProfileManagerClient::ErrorCallback
& error_callback
) {
27 BluetoothAdapterProfileChromeOS
* profile
=
28 new BluetoothAdapterProfileChromeOS(uuid
);
30 VLOG(1) << "Registering profile: " << profile
->object_path().value();
31 DBusThreadManager::Get()->GetBluetoothProfileManagerClient()->RegisterProfile(
32 profile
->object_path(),
33 uuid
.canonical_value(),
35 base::Bind(success_callback
, profile
),
41 BluetoothAdapterProfileChromeOS::BluetoothAdapterProfileChromeOS(
42 const device::BluetoothUUID
& uuid
)
43 : uuid_(uuid
), weak_ptr_factory_(this) {
44 std::string uuid_path
;
45 base::ReplaceChars(uuid
.canonical_value(), ":-", "_", &uuid_path
);
47 dbus::ObjectPath("/org/chromium/bluetooth_profile/" + uuid_path
);
49 dbus::Bus
* system_bus
= DBusThreadManager::Get()->GetSystemBus();
51 BluetoothProfileServiceProvider::Create(system_bus
, object_path_
, this));
52 DCHECK(profile_
.get());
55 BluetoothAdapterProfileChromeOS::~BluetoothAdapterProfileChromeOS() {
58 bool BluetoothAdapterProfileChromeOS::SetDelegate(
59 const dbus::ObjectPath
& device_path
,
60 BluetoothProfileServiceProvider::Delegate
* delegate
) {
62 VLOG(1) << "SetDelegate: " << object_path_
.value() << " dev "
63 << device_path
.value();
65 if (delegates_
.find(device_path
.value()) != delegates_
.end()) {
69 delegates_
[device_path
.value()] = delegate
;
73 void BluetoothAdapterProfileChromeOS::RemoveDelegate(
74 const dbus::ObjectPath
& device_path
,
75 const base::Closure
& unregistered_callback
) {
76 VLOG(1) << object_path_
.value() << " dev " << device_path
.value()
77 << ": RemoveDelegate";
79 if (delegates_
.find(device_path
.value()) == delegates_
.end())
82 delegates_
.erase(device_path
.value());
84 if (delegates_
.size() != 0)
87 VLOG(1) << device_path
.value() << " No delegates left, unregistering.";
89 // No users left, release the profile.
90 DBusThreadManager::Get()
91 ->GetBluetoothProfileManagerClient()
93 object_path_
, unregistered_callback
,
94 base::Bind(&BluetoothAdapterProfileChromeOS::OnUnregisterProfileError
,
95 weak_ptr_factory_
.GetWeakPtr(), unregistered_callback
));
98 void BluetoothAdapterProfileChromeOS::OnUnregisterProfileError(
99 const base::Closure
& unregistered_callback
,
100 const std::string
& error_name
,
101 const std::string
& error_message
) {
102 LOG(WARNING
) << this->object_path().value()
103 << ": Failed to unregister profile: " << error_name
<< ": "
106 unregistered_callback
.Run();
109 // BluetoothProfileServiceProvider::Delegate:
110 void BluetoothAdapterProfileChromeOS::Released() {
111 VLOG(1) << object_path_
.value() << ": Release";
114 void BluetoothAdapterProfileChromeOS::NewConnection(
115 const dbus::ObjectPath
& device_path
,
116 scoped_ptr
<dbus::FileDescriptor
> fd
,
117 const BluetoothProfileServiceProvider::Delegate::Options
& options
,
118 const ConfirmationCallback
& callback
) {
119 dbus::ObjectPath delegate_path
= device_path
;
121 if (delegates_
.find(device_path
.value()) == delegates_
.end())
122 delegate_path
= dbus::ObjectPath("");
124 if (delegates_
.find(delegate_path
.value()) == delegates_
.end()) {
125 VLOG(1) << object_path_
.value() << ": New connection for device "
126 << device_path
.value() << " which has no delegates!";
127 callback
.Run(REJECTED
);
131 delegates_
[delegate_path
.value()]->NewConnection(device_path
, fd
.Pass(),
135 void BluetoothAdapterProfileChromeOS::RequestDisconnection(
136 const dbus::ObjectPath
& device_path
,
137 const ConfirmationCallback
& callback
) {
138 dbus::ObjectPath delegate_path
= device_path
;
140 if (delegates_
.find(device_path
.value()) == delegates_
.end())
141 delegate_path
= dbus::ObjectPath("");
143 if (delegates_
.find(delegate_path
.value()) == delegates_
.end()) {
144 VLOG(1) << object_path_
.value() << ": RequestDisconnection for device "
145 << device_path
.value() << " which has no delegates!";
149 delegates_
[delegate_path
.value()]->RequestDisconnection(device_path
,
153 void BluetoothAdapterProfileChromeOS::Cancel() {
154 // Cancel() should only go to a delegate accepting connections.
155 if (delegates_
.find("") == delegates_
.end()) {
156 VLOG(1) << object_path_
.value() << ": Cancel with no delegate!";
160 delegates_
[""]->Cancel();
163 } // namespace chromeos