diff options
author | youngki@chromium.org <youngki@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-02 01:56:45 +0000 |
---|---|---|
committer | youngki@chromium.org <youngki@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-02 01:56:45 +0000 |
commit | cc1bc719c2fd37e710a5cdf55f4559801b98d9ba (patch) | |
tree | 49fd64a8674e54904d886546acfce2f7b636d980 /chrome/browser/chromeos/bluetooth/bluetooth_adapter_chromeos.cc | |
parent | ac22933cf0a514c841856e6274df8f2000ae8203 (diff) | |
download | chromium_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.cc | 553 |
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 |