summaryrefslogtreecommitdiffstats
path: root/chrome/browser/chromeos/bluetooth/bluetooth_adapter_chromeos.cc
diff options
context:
space:
mode:
authoryoungki@chromium.org <youngki@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-02 01:56:45 +0000
committeryoungki@chromium.org <youngki@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-02 01:56:45 +0000
commitcc1bc719c2fd37e710a5cdf55f4559801b98d9ba (patch)
tree49fd64a8674e54904d886546acfce2f7b636d980 /chrome/browser/chromeos/bluetooth/bluetooth_adapter_chromeos.cc
parentac22933cf0a514c841856e6274df8f2000ae8203 (diff)
downloadchromium_src-cc1bc719c2fd37e710a5cdf55f4559801b98d9ba.zip
chromium_src-cc1bc719c2fd37e710a5cdf55f4559801b98d9ba.tar.gz
chromium_src-cc1bc719c2fd37e710a5cdf55f4559801b98d9ba.tar.bz2
Renames the classes in chrome/browser/chromeos/bluetooth/ ChromeOs-specific (i.e. BluetoothAdapter => BluetoothAdapterChromeOs) and creating interfaces: BluetoothAdapter and BluetoothDevice.
This CL does the Step 1 & 2 of: 1) Renames the classes in chrome/browser/chromeos/bluetooth/ chromeos-specific (i.e. BluetoothAdapter => BluetoothAdapterChromeOs) 2) Create interfaces of the classes in chrome/browser/chromeos/bluetooth/. These interfaces will be used in the platform-independent logics. 3) Move everything out of chrome/browser/chromeos/bluetooth/ into devices/bluetooth/ since the code is no longer specific to linux/chromeos. 4) Add Windows implementations. (i.e. Create BluetoothAdapterWindows) BUG=135470 Review URL: https://chromiumcodereview.appspot.com/10899037 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@159615 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/chromeos/bluetooth/bluetooth_adapter_chromeos.cc')
-rw-r--r--chrome/browser/chromeos/bluetooth/bluetooth_adapter_chromeos.cc553
1 files changed, 553 insertions, 0 deletions
diff --git a/chrome/browser/chromeos/bluetooth/bluetooth_adapter_chromeos.cc b/chrome/browser/chromeos/bluetooth/bluetooth_adapter_chromeos.cc
new file mode 100644
index 0000000..8a4b4c5
--- /dev/null
+++ b/chrome/browser/chromeos/bluetooth/bluetooth_adapter_chromeos.cc
@@ -0,0 +1,553 @@
+// Copyright (c) 2012 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 "chrome/browser/chromeos/bluetooth/bluetooth_adapter_chromeos.h"
+
+#include <string>
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/stl_util.h"
+#include "base/values.h"
+#include "chrome/browser/chromeos/bluetooth/bluetooth_device_chromeos.h"
+#include "chromeos/dbus/bluetooth_adapter_client.h"
+#include "chromeos/dbus/bluetooth_device_client.h"
+#include "chromeos/dbus/bluetooth_manager_client.h"
+#include "chromeos/dbus/bluetooth_out_of_band_client.h"
+#include "chromeos/dbus/bluetooth_out_of_band_pairing_data.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "dbus/object_path.h"
+
+namespace chromeos {
+
+BluetoothAdapterChromeOs::BluetoothAdapterChromeOs() : track_default_(false),
+ powered_(false),
+ discovering_(false),
+ weak_ptr_factory_(this) {
+ DBusThreadManager::Get()->GetBluetoothManagerClient()->
+ AddObserver(this);
+ DBusThreadManager::Get()->GetBluetoothAdapterClient()->
+ AddObserver(this);
+ DBusThreadManager::Get()->GetBluetoothDeviceClient()->
+ AddObserver(this);
+}
+
+BluetoothAdapterChromeOs::~BluetoothAdapterChromeOs() {
+ DBusThreadManager::Get()->GetBluetoothDeviceClient()->
+ RemoveObserver(this);
+ DBusThreadManager::Get()->GetBluetoothAdapterClient()->
+ RemoveObserver(this);
+ DBusThreadManager::Get()->GetBluetoothManagerClient()->
+ RemoveObserver(this);
+
+ STLDeleteValues(&devices_);
+}
+
+void BluetoothAdapterChromeOs::AddObserver(
+ BluetoothAdapter::Observer* observer) {
+ DCHECK(observer);
+ observers_.AddObserver(observer);
+}
+
+void BluetoothAdapterChromeOs::RemoveObserver(
+ BluetoothAdapter::Observer* observer) {
+ DCHECK(observer);
+ observers_.RemoveObserver(observer);
+}
+
+bool BluetoothAdapterChromeOs::IsPresent() const {
+ return !object_path_.value().empty() && !address_.empty();
+}
+
+bool BluetoothAdapterChromeOs::IsPowered() const {
+ return powered_;
+}
+
+void BluetoothAdapterChromeOs::SetPowered(bool powered,
+ const base::Closure& callback,
+ const ErrorCallback& error_callback) {
+ DBusThreadManager::Get()->GetBluetoothAdapterClient()->
+ GetProperties(object_path_)->powered.Set(
+ powered,
+ base::Bind(&BluetoothAdapterChromeOs::OnSetPowered,
+ weak_ptr_factory_.GetWeakPtr(),
+ callback,
+ error_callback));
+}
+
+bool BluetoothAdapterChromeOs::IsDiscovering() const {
+ return discovering_;
+}
+
+void BluetoothAdapterChromeOs::SetDiscovering(
+ bool discovering,
+ const base::Closure& callback,
+ const ErrorCallback& error_callback) {
+ if (discovering) {
+ DBusThreadManager::Get()->GetBluetoothAdapterClient()->
+ StartDiscovery(object_path_,
+ base::Bind(&BluetoothAdapterChromeOs::OnStartDiscovery,
+ weak_ptr_factory_.GetWeakPtr(),
+ callback,
+ error_callback));
+ } else {
+ DBusThreadManager::Get()->GetBluetoothAdapterClient()->
+ StopDiscovery(object_path_,
+ base::Bind(&BluetoothAdapterChromeOs::OnStopDiscovery,
+ weak_ptr_factory_.GetWeakPtr(),
+ callback,
+ error_callback));
+ }
+}
+
+BluetoothAdapter::ConstDeviceList BluetoothAdapterChromeOs::GetDevices() const {
+ ConstDeviceList devices;
+ for (DevicesMap::const_iterator iter = devices_.begin();
+ iter != devices_.end();
+ ++iter)
+ devices.push_back(iter->second);
+
+ return devices;
+}
+
+BluetoothDevice* BluetoothAdapterChromeOs::GetDevice(
+ const std::string& address) {
+ return const_cast<BluetoothDevice *>(
+ const_cast<const BluetoothAdapterChromeOs *>(this)->GetDevice(address));
+}
+
+const BluetoothDevice* BluetoothAdapterChromeOs::GetDevice(
+ const std::string& address) const {
+ DevicesMap::const_iterator iter = devices_.find(address);
+ if (iter != devices_.end())
+ return iter->second;
+
+ return NULL;
+}
+
+void BluetoothAdapterChromeOs::ReadLocalOutOfBandPairingData(
+ const BluetoothOutOfBandPairingDataCallback& callback,
+ const ErrorCallback& error_callback) {
+ DBusThreadManager::Get()->GetBluetoothOutOfBandClient()->
+ ReadLocalData(object_path_,
+ base::Bind(&BluetoothAdapterChromeOs::OnReadLocalData,
+ weak_ptr_factory_.GetWeakPtr(),
+ callback,
+ error_callback));
+}
+
+void BluetoothAdapterChromeOs::TrackDefaultAdapter() {
+ DVLOG(1) << "Tracking default adapter";
+ track_default_ = true;
+ DBusThreadManager::Get()->GetBluetoothManagerClient()->
+ DefaultAdapter(base::Bind(&BluetoothAdapterChromeOs::AdapterCallback,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void BluetoothAdapterChromeOs::FindAdapter(const std::string& address) {
+ DVLOG(1) << "Using adapter " << address;
+ track_default_ = false;
+ DBusThreadManager::Get()->GetBluetoothManagerClient()->
+ FindAdapter(address,
+ base::Bind(&BluetoothAdapterChromeOs::AdapterCallback,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void BluetoothAdapterChromeOs::AdapterCallback(
+ const dbus::ObjectPath& adapter_path,
+ bool success) {
+ if (success) {
+ ChangeAdapter(adapter_path);
+ } else if (!object_path_.value().empty()) {
+ RemoveAdapter();
+ }
+}
+
+void BluetoothAdapterChromeOs::DefaultAdapterChanged(
+ const dbus::ObjectPath& adapter_path) {
+ if (track_default_)
+ ChangeAdapter(adapter_path);
+}
+
+void BluetoothAdapterChromeOs::AdapterRemoved(
+ const dbus::ObjectPath& adapter_path) {
+ if (adapter_path == object_path_)
+ RemoveAdapter();
+}
+
+void BluetoothAdapterChromeOs::ChangeAdapter(
+ const dbus::ObjectPath& adapter_path) {
+ if (object_path_.value().empty()) {
+ DVLOG(1) << "Adapter path initialized to " << adapter_path.value();
+ } else if (object_path_.value() != adapter_path.value()) {
+ DVLOG(1) << "Adapter path changed from " << object_path_.value()
+ << " to " << adapter_path.value();
+
+ RemoveAdapter();
+ } else {
+ DVLOG(1) << "Adapter address updated";
+ }
+
+ object_path_ = adapter_path;
+
+ // Update properties to their new values.
+ BluetoothAdapterClient::Properties* properties =
+ DBusThreadManager::Get()->GetBluetoothAdapterClient()->
+ GetProperties(object_path_);
+
+ address_ = properties->address.value();
+ name_ = properties->name.value();
+
+ // Delay announcing a new adapter until we have an address.
+ if (address_.empty()) {
+ DVLOG(1) << "Adapter address not yet known";
+ return;
+ }
+
+ PoweredChanged(properties->powered.value());
+ DiscoveringChanged(properties->discovering.value());
+ DevicesChanged(properties->devices.value());
+
+ FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
+ AdapterPresentChanged(this, true));
+}
+
+void BluetoothAdapterChromeOs::RemoveAdapter() {
+ const bool adapter_was_present = IsPresent();
+
+ DVLOG(1) << "Adapter lost.";
+ PoweredChanged(false);
+ DiscoveringChanged(false);
+ ClearDevices();
+
+ object_path_ = dbus::ObjectPath("");
+ address_.clear();
+ name_.clear();
+
+ if (adapter_was_present)
+ FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
+ AdapterPresentChanged(this, false));
+}
+
+void BluetoothAdapterChromeOs::OnSetPowered(const base::Closure& callback,
+ const ErrorCallback& error_callback,
+ bool success) {
+ if (success)
+ callback.Run();
+ else
+ error_callback.Run();
+}
+
+void BluetoothAdapterChromeOs::PoweredChanged(bool powered) {
+ if (powered == powered_)
+ return;
+
+ powered_ = powered;
+
+ FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
+ AdapterPoweredChanged(this, powered_));
+}
+
+void BluetoothAdapterChromeOs::OnStartDiscovery(
+ const base::Closure& callback,
+ const ErrorCallback& error_callback,
+ const dbus::ObjectPath& adapter_path,
+ bool success) {
+ if (success) {
+ DVLOG(1) << object_path_.value() << ": started discovery.";
+
+ // Clear devices found in previous discovery attempts
+ ClearDiscoveredDevices();
+ callback.Run();
+ } else {
+ // TODO(keybuk): in future, don't run the callback if the error was just
+ // that we were already discovering.
+ error_callback.Run();
+ }
+}
+
+void BluetoothAdapterChromeOs::OnStopDiscovery(
+ const base::Closure& callback,
+ const ErrorCallback& error_callback,
+ const dbus::ObjectPath& adapter_path,
+ bool success) {
+ if (success) {
+ DVLOG(1) << object_path_.value() << ": stopped discovery.";
+ callback.Run();
+ // Leave found devices available for perusing.
+ } else {
+ // TODO(keybuk): in future, don't run the callback if the error was just
+ // that we weren't discovering.
+ error_callback.Run();
+ }
+}
+
+void BluetoothAdapterChromeOs::DiscoveringChanged(bool discovering) {
+ if (discovering == discovering_)
+ return;
+
+ discovering_ = discovering;
+
+ FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
+ AdapterDiscoveringChanged(this, discovering_));
+}
+
+void BluetoothAdapterChromeOs::OnReadLocalData(
+ const BluetoothOutOfBandPairingDataCallback& callback,
+ const ErrorCallback& error_callback,
+ const BluetoothOutOfBandPairingData& data,
+ bool success) {
+ if (success)
+ callback.Run(data);
+ else
+ error_callback.Run();
+}
+
+void BluetoothAdapterChromeOs::AdapterPropertyChanged(
+ const dbus::ObjectPath& adapter_path,
+ const std::string& property_name) {
+ if (adapter_path != object_path_)
+ return;
+
+ BluetoothAdapterClient::Properties* properties =
+ DBusThreadManager::Get()->GetBluetoothAdapterClient()->
+ GetProperties(object_path_);
+
+ if (property_name == properties->address.name()) {
+ ChangeAdapter(object_path_);
+
+ } else if (!address_.empty()) {
+ if (property_name == properties->powered.name()) {
+ PoweredChanged(properties->powered.value());
+
+ } else if (property_name == properties->discovering.name()) {
+ DiscoveringChanged(properties->discovering.value());
+
+ } else if (property_name == properties->devices.name()) {
+ DevicesChanged(properties->devices.value());
+
+ } else if (property_name == properties->name.name()) {
+ name_ = properties->name.value();
+
+ }
+ }
+}
+
+void BluetoothAdapterChromeOs::DevicePropertyChanged(
+ const dbus::ObjectPath& device_path,
+ const std::string& property_name) {
+ UpdateDevice(device_path);
+}
+
+void BluetoothAdapterChromeOs::UpdateDevice(
+ const dbus::ObjectPath& device_path) {
+ BluetoothDeviceClient::Properties* properties =
+ DBusThreadManager::Get()->GetBluetoothDeviceClient()->
+ GetProperties(device_path);
+
+ // When we first see a device, we may not know the address yet and need to
+ // wait for the DevicePropertyChanged signal before adding the device.
+ const std::string address = properties->address.value();
+ if (address.empty())
+ return;
+
+ // The device may be already known to us, either because this is an update
+ // to properties, or the device going from discovered to connected and
+ // pairing gaining an object path in the process. In any case, we want
+ // to update the existing object, not create a new one.
+ DevicesMap::iterator iter = devices_.find(address);
+ BluetoothDeviceChromeOs* device;
+ const bool update_device = (iter != devices_.end());
+ if (update_device) {
+ device = iter->second;
+ } else {
+ device = BluetoothDeviceChromeOs::Create(this);
+ devices_[address] = device;
+ }
+
+ const bool was_paired = device->IsPaired();
+ if (!was_paired) {
+ DVLOG(1) << "Assigned object path " << device_path.value() << " to device "
+ << address;
+ device->SetObjectPath(device_path);
+ }
+ device->Update(properties, true);
+
+ // Don't send a duplicate added event for supported devices that were
+ // previously visible or for already paired devices, send a changed
+ // event instead. We always send one event or the other since we always
+ // inform observers about paired devices whether or not they're supported.
+ if (update_device && (device->IsSupported() || was_paired)) {
+ FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
+ DeviceChanged(this, device));
+ } else {
+ FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
+ DeviceAdded(this, device));
+ }
+}
+
+void BluetoothAdapterChromeOs::ClearDevices() {
+ DevicesMap replace;
+ devices_.swap(replace);
+ for (DevicesMap::iterator iter = replace.begin();
+ iter != replace.end(); ++iter) {
+ BluetoothDeviceChromeOs* device = iter->second;
+ if (device->IsSupported() || device->IsPaired())
+ FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
+ DeviceRemoved(this, device));
+
+ delete device;
+ }
+}
+
+void BluetoothAdapterChromeOs::DeviceCreated(
+ const dbus::ObjectPath& adapter_path,
+ const dbus::ObjectPath& device_path) {
+ if (adapter_path != object_path_)
+ return;
+
+ UpdateDevice(device_path);
+}
+
+void BluetoothAdapterChromeOs::DeviceRemoved(
+ const dbus::ObjectPath& adapter_path,
+ const dbus::ObjectPath& device_path) {
+ if (adapter_path != object_path_)
+ return;
+
+ DevicesMap::iterator iter = devices_.begin();
+ while (iter != devices_.end()) {
+ BluetoothDeviceChromeOs* device = iter->second;
+ DevicesMap::iterator temp = iter;
+ ++iter;
+
+ if (device->object_path_ != device_path)
+ continue;
+
+ // DeviceRemoved can also be called to indicate a device that is visible
+ // during discovery has disconnected, but it is still visible to the
+ // adapter, so don't remove in that case and only clear the object path.
+ if (!device->IsVisible()) {
+ FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
+ DeviceRemoved(this, device));
+
+ DVLOG(1) << "Removed device " << device->address();
+
+ delete device;
+ devices_.erase(temp);
+ } else {
+ DVLOG(1) << "Removed object path from device " << device->address();
+ device->RemoveObjectPath();
+
+ // If the device is not supported then we want to act as if it was
+ // removed, even though it is still visible to the adapter.
+ if (!device->IsSupported()) {
+ FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
+ DeviceRemoved(this, device));
+ } else {
+ FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
+ DeviceChanged(this, device));
+ }
+ }
+ }
+}
+
+void BluetoothAdapterChromeOs::DevicesChanged(
+ const std::vector<dbus::ObjectPath>& devices) {
+ for (std::vector<dbus::ObjectPath>::const_iterator iter =
+ devices.begin(); iter != devices.end(); ++iter)
+ UpdateDevice(*iter);
+}
+
+void BluetoothAdapterChromeOs::ClearDiscoveredDevices() {
+ DevicesMap::iterator iter = devices_.begin();
+ while (iter != devices_.end()) {
+ BluetoothDeviceChromeOs* device = iter->second;
+ DevicesMap::iterator temp = iter;
+ ++iter;
+
+ if (!device->IsPaired()) {
+ if (device->IsSupported())
+ FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
+ DeviceRemoved(this, device));
+
+ delete device;
+ devices_.erase(temp);
+ }
+ }
+}
+
+void BluetoothAdapterChromeOs::DeviceFound(
+ const dbus::ObjectPath& adapter_path,
+ const std::string& address,
+ const BluetoothDeviceClient::Properties& properties) {
+ if (adapter_path != object_path_)
+ return;
+
+ // DeviceFound can also be called to indicate that a device we've
+ // paired with is now visible to the adapter during discovery, in which
+ // case we want to update the existing object, not create a new one.
+ BluetoothDeviceChromeOs* device;
+ DevicesMap::iterator iter = devices_.find(address);
+ const bool update_device = (iter != devices_.end());
+ if (update_device) {
+ device = iter->second;
+ } else {
+ device = BluetoothDeviceChromeOs::Create(this);
+ devices_[address] = device;
+ }
+
+ DVLOG(1) << "Device " << address << " is visible to the adapter";
+ device->SetVisible(true);
+ device->Update(&properties, false);
+
+ // Don't send a duplicated added event for duplicate signals for supported
+ // devices that were previously visible (should never happen) or for already
+ // paired devices, send a changed event instead. We do not inform observers
+ // if we find or update an unconnected and unsupported device.
+ if (update_device && (device->IsSupported() || device->IsPaired())) {
+ FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
+ DeviceChanged(this, device));
+ } else if (device->IsSupported()) {
+ FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
+ DeviceAdded(this, device));
+ }
+}
+
+void BluetoothAdapterChromeOs::DeviceDisappeared(
+ const dbus::ObjectPath& adapter_path,
+ const std::string& address) {
+ if (adapter_path != object_path_)
+ return;
+
+ DevicesMap::iterator iter = devices_.find(address);
+ if (iter == devices_.end())
+ return;
+
+ BluetoothDeviceChromeOs* device = iter->second;
+
+ // DeviceDisappeared can also be called to indicate that a device we've
+ // paired with is no longer visible to the adapter, so don't remove
+ // in that case and only clear the visible flag.
+ if (!device->IsPaired()) {
+ if (device->IsSupported())
+ FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
+ DeviceRemoved(this, device));
+
+ DVLOG(1) << "Discovered device " << device->address()
+ << " is no longer visible to the adapter";
+
+ delete device;
+ devices_.erase(iter);
+ } else {
+ DVLOG(1) << "Paired device " << device->address()
+ << " is no longer visible to the adapter";
+ device->SetVisible(false);
+
+ FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
+ DeviceChanged(this, device));
+ }
+}
+
+} // namespace chromeos