summaryrefslogtreecommitdiffstats
path: root/device/bluetooth/bluetooth_adapter_profile_chromeos.cc
diff options
context:
space:
mode:
authorjamuraa <jamuraa@chromium.org>2015-01-30 15:50:29 -0800
committerCommit bot <commit-bot@chromium.org>2015-01-30 23:51:22 +0000
commitf3f0784e90e8d4a26b1aa3d57e435a01b44a99a2 (patch)
tree0dcda04a577c7543fc1ace0036e58e62379fd3d9 /device/bluetooth/bluetooth_adapter_profile_chromeos.cc
parentc7569a39d30b01d7585fb309754382e1c48eb067 (diff)
downloadchromium_src-f3f0784e90e8d4a26b1aa3d57e435a01b44a99a2.zip
chromium_src-f3f0784e90e8d4a26b1aa3d57e435a01b44a99a2.tar.gz
chromium_src-f3f0784e90e8d4a26b1aa3d57e435a01b44a99a2.tar.bz2
Manage profiles in BluetoothAdapter on ChromeOS
Profiles in bluez are not specific to a device. When client code tries to connect to two different devices, only one profile is created, managed by BluetoothAdapterChromeOS. dbus messages are multiplexed based on the device desired using new class BluetoothAdapterProfileChromeOS. This is a resubmit with bugfixes after https://codereview.chromium.org/851123002/ was reverted by https://codereview.chromium.org/868753006/ BUG=421207 Review URL: https://codereview.chromium.org/888913002 Cr-Commit-Position: refs/heads/master@{#314030}
Diffstat (limited to 'device/bluetooth/bluetooth_adapter_profile_chromeos.cc')
-rw-r--r--device/bluetooth/bluetooth_adapter_profile_chromeos.cc165
1 files changed, 165 insertions, 0 deletions
diff --git a/device/bluetooth/bluetooth_adapter_profile_chromeos.cc b/device/bluetooth/bluetooth_adapter_profile_chromeos.cc
new file mode 100644
index 0000000..2feff37
--- /dev/null
+++ b/device/bluetooth/bluetooth_adapter_profile_chromeos.cc
@@ -0,0 +1,165 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "device/bluetooth/bluetooth_adapter_profile_chromeos.h"
+
+#include <string>
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/strings/string_util.h"
+#include "chromeos/dbus/bluetooth_profile_service_provider.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "dbus/bus.h"
+#include "dbus/object_path.h"
+#include "device/bluetooth/bluetooth_adapter_chromeos.h"
+#include "device/bluetooth/bluetooth_uuid.h"
+
+namespace chromeos {
+
+// static
+BluetoothAdapterProfileChromeOS* BluetoothAdapterProfileChromeOS::Register(
+ BluetoothAdapterChromeOS* adapter,
+ const device::BluetoothUUID& uuid,
+ const BluetoothProfileManagerClient::Options& options,
+ const base::Closure& success_callback,
+ const BluetoothProfileManagerClient::ErrorCallback& error_callback) {
+ DCHECK(adapter);
+
+ BluetoothAdapterProfileChromeOS* profile =
+ new BluetoothAdapterProfileChromeOS(adapter, uuid);
+
+ VLOG(1) << "Registering profile: " << profile->object_path().value();
+ DBusThreadManager::Get()->GetBluetoothProfileManagerClient()->RegisterProfile(
+ profile->object_path(), uuid.canonical_value(), options, success_callback,
+ error_callback);
+
+ return profile;
+}
+
+BluetoothAdapterProfileChromeOS::BluetoothAdapterProfileChromeOS(
+ BluetoothAdapterChromeOS* adapter,
+ const device::BluetoothUUID& uuid)
+ : uuid_(uuid), adapter_(adapter), weak_ptr_factory_(this) {
+ std::string uuid_path;
+ base::ReplaceChars(uuid.canonical_value(), ":-", "_", &uuid_path);
+ object_path_ =
+ dbus::ObjectPath("/org/chromium/bluetooth_profile/" + uuid_path);
+
+ dbus::Bus* system_bus = DBusThreadManager::Get()->GetSystemBus();
+ profile_.reset(
+ BluetoothProfileServiceProvider::Create(system_bus, object_path_, this));
+ DCHECK(profile_.get());
+}
+
+BluetoothAdapterProfileChromeOS::~BluetoothAdapterProfileChromeOS() {
+ profile_.reset();
+}
+
+bool BluetoothAdapterProfileChromeOS::SetDelegate(
+ const dbus::ObjectPath& device_path,
+ BluetoothProfileServiceProvider::Delegate* delegate) {
+ DCHECK(delegate);
+ VLOG(1) << "SetDelegate: " << object_path_.value() << " dev "
+ << device_path.value();
+
+ if (delegates_.find(device_path.value()) != delegates_.end()) {
+ return false;
+ }
+
+ delegates_[device_path.value()] = delegate;
+ return true;
+}
+
+void BluetoothAdapterProfileChromeOS::RemoveDelegate(
+ const dbus::ObjectPath& device_path,
+ const base::Closure& unregistered_callback) {
+ VLOG(1) << object_path_.value() << " dev " << device_path.value()
+ << ": RemoveDelegate";
+
+ if (delegates_.find(device_path.value()) == delegates_.end())
+ return;
+
+ delegates_.erase(device_path.value());
+
+ if (delegates_.size() != 0)
+ return;
+
+ VLOG(1) << device_path.value() << " No delegates left, unregistering.";
+
+ // No users left, release the profile.
+ DBusThreadManager::Get()
+ ->GetBluetoothProfileManagerClient()
+ ->UnregisterProfile(
+ object_path_, unregistered_callback,
+ base::Bind(&BluetoothAdapterProfileChromeOS::OnUnregisterProfileError,
+ weak_ptr_factory_.GetWeakPtr(), unregistered_callback));
+}
+
+void BluetoothAdapterProfileChromeOS::OnUnregisterProfileError(
+ const base::Closure& unregistered_callback,
+ const std::string& error_name,
+ const std::string& error_message) {
+ LOG(WARNING) << this->object_path().value()
+ << ": Failed to unregister profile: " << error_name << ": "
+ << error_message;
+
+ unregistered_callback.Run();
+}
+
+// BluetoothProfileServiceProvider::Delegate:
+void BluetoothAdapterProfileChromeOS::Released() {
+ VLOG(1) << object_path_.value() << ": Release";
+}
+
+void BluetoothAdapterProfileChromeOS::NewConnection(
+ const dbus::ObjectPath& device_path,
+ scoped_ptr<dbus::FileDescriptor> fd,
+ const BluetoothProfileServiceProvider::Delegate::Options& options,
+ const ConfirmationCallback& callback) {
+ dbus::ObjectPath delegate_path = device_path;
+
+ if (delegates_.find(device_path.value()) == delegates_.end())
+ delegate_path = dbus::ObjectPath("");
+
+ if (delegates_.find(delegate_path.value()) == delegates_.end()) {
+ VLOG(1) << object_path_.value() << ": New connection for device "
+ << device_path.value() << " which has no delegates!";
+ callback.Run(REJECTED);
+ return;
+ }
+
+ delegates_[delegate_path.value()]->NewConnection(device_path, fd.Pass(),
+ options, callback);
+}
+
+void BluetoothAdapterProfileChromeOS::RequestDisconnection(
+ const dbus::ObjectPath& device_path,
+ const ConfirmationCallback& callback) {
+ dbus::ObjectPath delegate_path = device_path;
+
+ if (delegates_.find(device_path.value()) == delegates_.end())
+ delegate_path = dbus::ObjectPath("");
+
+ if (delegates_.find(delegate_path.value()) == delegates_.end()) {
+ VLOG(1) << object_path_.value() << ": RequestDisconnection for device "
+ << device_path.value() << " which has no delegates!";
+ return;
+ }
+
+ delegates_[delegate_path.value()]->RequestDisconnection(device_path,
+ callback);
+}
+
+void BluetoothAdapterProfileChromeOS::Cancel() {
+ // Cancel() should only go to a delegate accepting connections.
+ if (delegates_.find("") == delegates_.end()) {
+ VLOG(1) << object_path_.value() << ": Cancel with no delegate!";
+ return;
+ }
+
+ delegates_[""]->Cancel();
+}
+
+} // namespace chromeos