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

Unified Diff: device/bluetooth/bluetooth_adapter_experimental_chromeos.cc

Issue 13927010: Bluetooth: implement BlueZ 5 backend for Chrome OS (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 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 side-by-side diff with in-line comments
Download patch
Index: device/bluetooth/bluetooth_adapter_experimental_chromeos.cc
diff --git a/device/bluetooth/bluetooth_adapter_experimental_chromeos.cc b/device/bluetooth/bluetooth_adapter_experimental_chromeos.cc
index 8cdfb9618629b15a7c977c7fe4f889893e837602..eb8c1da7f084fe55c249d9853e68c1f1263a1486 100644
--- a/device/bluetooth/bluetooth_adapter_experimental_chromeos.cc
+++ b/device/bluetooth/bluetooth_adapter_experimental_chromeos.cc
@@ -6,32 +6,77 @@
#include <string>
+#include "base/bind.h"
+#include "base/logging.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/dbus/experimental_bluetooth_adapter_client.h"
+#include "chromeos/dbus/experimental_bluetooth_device_client.h"
+#include "device/bluetooth/bluetooth_device.h"
+#include "device/bluetooth/bluetooth_device_experimental_chromeos.h"
+
using device::BluetoothAdapter;
+using device::BluetoothDevice;
namespace chromeos {
BluetoothAdapterExperimentalChromeOS::BluetoothAdapterExperimentalChromeOS()
- : BluetoothAdapter(),
- weak_ptr_factory_(this) {
+ : weak_ptr_factory_(this) {
+ DBusThreadManager::Get()->GetExperimentalBluetoothAdapterClient()->
+ AddObserver(this);
+ DBusThreadManager::Get()->GetExperimentalBluetoothDeviceClient()->
+ AddObserver(this);
+
+ std::vector<dbus::ObjectPath> object_paths =
+ DBusThreadManager::Get()->GetExperimentalBluetoothAdapterClient()->
+ GetAdapters();
+
+ if (!object_paths.empty()) {
+ VLOG(1) << object_paths.size() << " Bluetooth adapter(s) available.";
+ SetAdapter(object_paths[0]);
+ }
}
BluetoothAdapterExperimentalChromeOS::~BluetoothAdapterExperimentalChromeOS() {
+ DBusThreadManager::Get()->GetExperimentalBluetoothAdapterClient()->
+ RemoveObserver(this);
+ DBusThreadManager::Get()->GetExperimentalBluetoothDeviceClient()->
+ RemoveObserver(this);
}
void BluetoothAdapterExperimentalChromeOS::AddObserver(
BluetoothAdapter::Observer* observer) {
+ DCHECK(observer);
+ observers_.AddObserver(observer);
}
void BluetoothAdapterExperimentalChromeOS::RemoveObserver(
BluetoothAdapter::Observer* observer) {
+ DCHECK(observer);
+ observers_.RemoveObserver(observer);
}
std::string BluetoothAdapterExperimentalChromeOS::GetAddress() const {
- return std::string();
+ if (object_path_.value().empty())
+ return std::string();
+
+ ExperimentalBluetoothAdapterClient::Properties* properties =
+ DBusThreadManager::Get()->GetExperimentalBluetoothAdapterClient()->
+ GetProperties(object_path_);
+ DCHECK(properties);
+
+ return properties->address.value();
}
std::string BluetoothAdapterExperimentalChromeOS::GetName() const {
- return std::string();
+ if (object_path_.value().empty())
+ return std::string();
+
+ ExperimentalBluetoothAdapterClient::Properties* properties =
+ DBusThreadManager::Get()->GetExperimentalBluetoothAdapterClient()->
+ GetProperties(object_path_);
+ DCHECK(properties);
+
+ return properties->alias.value();
}
bool BluetoothAdapterExperimentalChromeOS::IsInitialized() const {
@@ -39,33 +84,77 @@ bool BluetoothAdapterExperimentalChromeOS::IsInitialized() const {
}
bool BluetoothAdapterExperimentalChromeOS::IsPresent() const {
- return false;
+ return !object_path_.value().empty();
}
bool BluetoothAdapterExperimentalChromeOS::IsPowered() const {
- return false;
+ if (object_path_.value().empty())
youngki 2013/04/16 15:26:56 Would it be more elegant if we reuse IsPresent() h
keybuk 2013/04/16 23:19:13 Done.
+ return false;
+
+ ExperimentalBluetoothAdapterClient::Properties* properties =
+ DBusThreadManager::Get()->GetExperimentalBluetoothAdapterClient()->
+ GetProperties(object_path_);
+
+ return properties->powered.value();
}
-void BluetoothAdapterExperimentalChromeOS::SetPowered(bool powered,
- const base::Closure& callback,
- const ErrorCallback& error_callback) {
- error_callback.Run();
+void BluetoothAdapterExperimentalChromeOS::SetPowered(
+ bool powered,
+ const base::Closure& callback,
+ const ErrorCallback& error_callback) {
+ DBusThreadManager::Get()->GetExperimentalBluetoothAdapterClient()->
+ GetProperties(object_path_)->powered.Set(
+ powered,
+ base::Bind(&BluetoothAdapterExperimentalChromeOS::OnSetPowered,
+ weak_ptr_factory_.GetWeakPtr(),
+ callback, error_callback));
youngki 2013/04/16 15:26:56 style nits: one argument per line.
keybuk 2013/04/16 23:19:13 Done.
}
bool BluetoothAdapterExperimentalChromeOS::IsDiscovering() const {
- return false;
+ if (object_path_.value().empty())
youngki 2013/04/16 15:26:56 Can we reuse IsPresent()? if (!IsPresent()) ret
keybuk 2013/04/16 23:19:13 Done.
+ return false;
+
+ ExperimentalBluetoothAdapterClient::Properties* properties =
+ DBusThreadManager::Get()->GetExperimentalBluetoothAdapterClient()->
+ GetProperties(object_path_);
+
+ return properties->discovering.value();
}
void BluetoothAdapterExperimentalChromeOS::StartDiscovering(
const base::Closure& callback,
const ErrorCallback& error_callback) {
- error_callback.Run();
+ // BlueZ counts discovery sessions, and permits multiple sessions for a
+ // single connection, so issue a StartDiscovery() call for every use
+ // within Chromium for the right behavior.
+ DBusThreadManager::Get()->GetExperimentalBluetoothAdapterClient()->
+ StartDiscovery(
+ object_path_,
+ base::Bind(
+ &BluetoothAdapterExperimentalChromeOS::OnStartDiscovery,
+ weak_ptr_factory_.GetWeakPtr(),
+ callback),
+ base::Bind(
+ &BluetoothAdapterExperimentalChromeOS::OnStartDiscoveryError,
+ weak_ptr_factory_.GetWeakPtr(),
+ error_callback));
}
void BluetoothAdapterExperimentalChromeOS::StopDiscovering(
const base::Closure& callback,
const ErrorCallback& error_callback) {
- error_callback.Run();
+ // Inform BlueZ to stop one of our open discovery sessions.
+ DBusThreadManager::Get()->GetExperimentalBluetoothAdapterClient()->
+ StopDiscovery(
+ object_path_,
+ base::Bind(
+ &BluetoothAdapterExperimentalChromeOS::OnStopDiscovery,
+ weak_ptr_factory_.GetWeakPtr(),
+ callback),
+ base::Bind(
+ &BluetoothAdapterExperimentalChromeOS::OnStopDiscoveryError,
+ weak_ptr_factory_.GetWeakPtr(),
+ error_callback));
}
void BluetoothAdapterExperimentalChromeOS::ReadLocalOutOfBandPairingData(
@@ -74,4 +163,228 @@ void BluetoothAdapterExperimentalChromeOS::ReadLocalOutOfBandPairingData(
error_callback.Run();
}
+void BluetoothAdapterExperimentalChromeOS::AdapterAdded(
+ const dbus::ObjectPath& object_path) {
+ if (object_path_.value().empty())
satorux1 2013/04/16 06:30:45 Did you mean: if (!object_path_.value().empty())
keybuk 2013/04/16 23:19:13 No, this only sets the adapter if it *isn't* alrea
+ SetAdapter(object_path);
+}
+
+void BluetoothAdapterExperimentalChromeOS::AdapterRemoved(
+ const dbus::ObjectPath& object_path) {
+ if (object_path == object_path_)
+ RemoveAdapter();
+}
+
+void BluetoothAdapterExperimentalChromeOS::AdapterPropertyChanged(
+ const dbus::ObjectPath& object_path,
+ const std::string& property_name) {
+ if (object_path != object_path_)
+ return;
+
+ ExperimentalBluetoothAdapterClient::Properties* properties =
+ DBusThreadManager::Get()->GetExperimentalBluetoothAdapterClient()->
+ GetProperties(object_path_);
+
+ if (property_name == properties->powered.name())
+ PoweredChanged(properties->powered.value());
+ else if (property_name == properties->discovering.name())
+ DiscoveringChanged(properties->discovering.value());
+}
+
+void BluetoothAdapterExperimentalChromeOS::DeviceAdded(
+ const dbus::ObjectPath& object_path) {
+ ExperimentalBluetoothDeviceClient::Properties* properties =
+ DBusThreadManager::Get()->GetExperimentalBluetoothDeviceClient()->
+ GetProperties(object_path);
+ if (properties->adapter.value() != object_path_)
+ return;
+
+ BluetoothDeviceExperimentalChromeOS* device_chromeos =
+ new BluetoothDeviceExperimentalChromeOS(this, object_path);
+
youngki 2013/04/16 15:26:56 Can we put DCHECK here that devices_[device_chrome
keybuk 2013/04/16 23:19:13 Done.
+ devices_[device_chromeos->GetAddress()] = device_chromeos;
+
+ FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
+ DeviceAdded(this, device_chromeos));
+}
+
+void BluetoothAdapterExperimentalChromeOS::DeviceRemoved(
+ const dbus::ObjectPath& object_path) {
+ for (DevicesMap::iterator iter = devices_.begin();
+ iter != devices_.end(); ++iter) {
+ BluetoothDeviceExperimentalChromeOS* device_chromeos =
+ static_cast<BluetoothDeviceExperimentalChromeOS*>(iter->second);
+ if (device_chromeos->object_path() == object_path) {
+ devices_.erase(iter);
+
+ FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
+ DeviceRemoved(this, device_chromeos));
+ delete device_chromeos;
+ return;
+ }
+ }
+}
+
+void BluetoothAdapterExperimentalChromeOS::DevicePropertyChanged(
+ const dbus::ObjectPath& object_path,
+ const std::string& property_name) {
+ BluetoothDeviceExperimentalChromeOS* device_chromeos =
+ GetDeviceWithPath(object_path);
+ if (!device_chromeos)
+ return;
+
+ ExperimentalBluetoothDeviceClient::Properties* properties =
+ DBusThreadManager::Get()->GetExperimentalBluetoothDeviceClient()->
+ GetProperties(object_path);
+
+ if (property_name == properties->bluetooth_class.name() ||
+ property_name == properties->alias.name() ||
+ property_name == properties->paired.name() ||
+ property_name == properties->connected.name() ||
+ property_name == properties->uuids.name()) {
+ FOR_EACH_OBSERVER(
+ BluetoothAdapter::Observer, observers_,
+ DeviceChanged(this, static_cast<BluetoothDevice*>(device_chromeos)));
youngki 2013/04/16 15:26:56 I don't think this cast is necessary since Bluetoo
keybuk 2013/04/16 23:19:13 Done.
+ }
+}
+
+BluetoothDeviceExperimentalChromeOS*
+BluetoothAdapterExperimentalChromeOS::GetDeviceWithPath(
+ const dbus::ObjectPath& object_path) {
+ for (DevicesMap::iterator iter = devices_.begin();
+ iter != devices_.end(); ++iter) {
+ BluetoothDeviceExperimentalChromeOS* device_chromeos =
+ static_cast<BluetoothDeviceExperimentalChromeOS*>(iter->second);
+ if (device_chromeos->object_path() == object_path)
+ return device_chromeos;
+ }
+
+ return NULL;
+}
+
+void BluetoothAdapterExperimentalChromeOS::SetAdapter(
+ const dbus::ObjectPath& object_path)
+{
+ DCHECK(object_path_.value().empty());
+ object_path_ = object_path;
+
+ VLOG(1) << object_path_.value() << ": using adapter.";
+
+ ExperimentalBluetoothAdapterClient::Properties* properties =
+ DBusThreadManager::Get()->GetExperimentalBluetoothAdapterClient()->
+ GetProperties(object_path_);
+
+ PresentChanged(true);
+
+ if (properties->powered.value() != false)
youngki 2013/04/16 15:26:56 change it to if (properties->powered.value())
keybuk 2013/04/16 23:19:13 Done.
+ PoweredChanged(properties->powered.value());
youngki 2013/04/16 15:26:56 Also I think we should just make it PoweredChanged
keybuk 2013/04/16 23:19:13 Done.
+ if (properties->discovering.value() != false)
youngki 2013/04/16 15:26:56 change it to if (properties->discovering.value())
keybuk 2013/04/16 23:19:13 Done.
+ DiscoveringChanged(properties->discovering.value());
youngki 2013/04/16 15:26:56 Change it to DiscoveringChanged(true) also.
keybuk 2013/04/16 23:19:13 Done.
+
+ std::vector<dbus::ObjectPath> device_paths =
+ DBusThreadManager::Get()->GetExperimentalBluetoothDeviceClient()->
+ GetDevicesForAdapter(object_path_);
+
+ for (std::vector<dbus::ObjectPath>::iterator iter = device_paths.begin();
+ iter != device_paths.end(); ++iter) {
+ BluetoothDeviceExperimentalChromeOS* device_chromeos =
+ new BluetoothDeviceExperimentalChromeOS(this, *iter);
+
+ devices_[device_chromeos->GetAddress()] = device_chromeos;
+
+ FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
+ DeviceAdded(this, device_chromeos));
+ }
+}
+
+void BluetoothAdapterExperimentalChromeOS::RemoveAdapter()
+{
+ DCHECK(!object_path_.value().empty());
youngki 2013/04/16 15:26:56 DCHECK(IsPresent());
keybuk 2013/04/16 23:19:13 Done.
+ VLOG(1) << object_path_.value() << ": adapter removed.";
+
+ ExperimentalBluetoothAdapterClient::Properties* properties =
+ DBusThreadManager::Get()->GetExperimentalBluetoothAdapterClient()->
+ GetProperties(object_path_);
+
+ object_path_ = dbus::ObjectPath("");
+
+ if (properties->powered.value() != false)
youngki 2013/04/16 15:26:56 change it to if (properties->powered.value())
keybuk 2013/04/16 23:19:13 Done.
+ PoweredChanged(false);
youngki 2013/04/16 15:26:56 Are you sure this logic is right? This looks to me
keybuk 2013/04/16 23:19:13 "if powered was on, the adapter is going buh-bye,
+ if (properties->discovering.value() != false)
youngki 2013/04/16 15:26:56 change it to if (properties->discovering.value())
keybuk 2013/04/16 23:19:13 Done.
+ DiscoveringChanged(false);
+
+ // Copy the devices list here and clear the original so that when we
+ // send DeviceRemoved(), GetDevices() returns no devices.
+ DevicesMap devices = devices_;
+ devices_.clear();
+
+ for (DevicesMap::iterator iter = devices.begin();
+ iter != devices.end(); ++iter) {
+ FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
+ DeviceRemoved(this, iter->second));
+ delete iter->second;
+ }
+
+ PresentChanged(false);
+}
+
+void BluetoothAdapterExperimentalChromeOS::PoweredChanged(bool powered)
+{
+ FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
+ AdapterPoweredChanged(this, powered));
+}
+
+void BluetoothAdapterExperimentalChromeOS::DiscoveringChanged(bool discovering)
+{
+ FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
+ AdapterDiscoveringChanged(this, discovering));
+}
+
+void BluetoothAdapterExperimentalChromeOS::PresentChanged(bool present)
+{
+ FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
+ AdapterPresentChanged(this, present));
+}
+
+void BluetoothAdapterExperimentalChromeOS::OnSetPowered(
+ const base::Closure& callback,
+ const ErrorCallback& error_callback,
+ bool success)
+{
satorux1 2013/04/16 06:30:45 nit: move { to the previous line
keybuk 2013/04/16 23:19:13 Done.
+ if (success)
+ callback.Run();
+ else
+ error_callback.Run();
+}
+
+void BluetoothAdapterExperimentalChromeOS::OnStartDiscovery(
+ const base::Closure& callback) {
+ callback.Run();
+}
+
+void BluetoothAdapterExperimentalChromeOS::OnStartDiscoveryError(
+ const ErrorCallback& error_callback,
+ const std::string& error_name,
+ const std::string& error_message)
+{
satorux1 2013/04/16 06:30:45 ditto
keybuk 2013/04/16 23:19:13 Done.
+ LOG(WARNING) << object_path_.value() << ": Failed to start discovery: "
+ << error_name << ": " << error_message;
+ error_callback.Run();
+}
+
+void BluetoothAdapterExperimentalChromeOS::OnStopDiscovery(
+ const base::Closure& callback) {
+ callback.Run();
+}
+
+void BluetoothAdapterExperimentalChromeOS::OnStopDiscoveryError(
+ const ErrorCallback& error_callback,
+ const std::string& error_name,
+ const std::string& error_message)
+{
satorux1 2013/04/16 06:30:45 ditto
keybuk 2013/04/16 23:19:13 Done.
+ LOG(WARNING) << object_path_.value() << ": Failed to stop discovery: "
+ << error_name << ": " << error_message;
+ error_callback.Run();
+}
+
} // namespace chromeos

Powered by Google App Engine
This is Rietveld 408576698