diff options
Diffstat (limited to 'chrome/browser')
25 files changed, 2434 insertions, 1970 deletions
diff --git a/chrome/browser/chromeos/bluetooth/bluetooth_adapter.cc b/chrome/browser/chromeos/bluetooth/bluetooth_adapter.cc index cad3de4..7108b41 100644 --- a/chrome/browser/chromeos/bluetooth/bluetooth_adapter.cc +++ b/chrome/browser/chromeos/bluetooth/bluetooth_adapter.cc @@ -4,575 +4,31 @@ #include "chrome/browser/chromeos/bluetooth/bluetooth_adapter.h" -#include "base/bind.h" -#include "base/lazy_instance.h" -#include "base/logging.h" -#include "base/stl_util.h" -#include "base/values.h" #include "chrome/browser/chromeos/bluetooth/bluetooth_device.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/dbus_thread_manager.h" -#include "dbus/object_path.h" - -namespace { - -// Shared default adapter instance, we don't want to keep this class around -// if nobody is using it so use a WeakPtr and create the object when needed; -// since Google C++ Style (and clang's static analyzer) forbids us having -// exit-time destructors we use a leaky lazy instance for it. -base::LazyInstance<base::WeakPtr<chromeos::BluetoothAdapter> >::Leaky - default_adapter = LAZY_INSTANCE_INITIALIZER; - -} // namespace namespace chromeos { -BluetoothAdapter::BluetoothAdapter() : 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); -} - BluetoothAdapter::~BluetoothAdapter() { - DBusThreadManager::Get()->GetBluetoothDeviceClient()-> - RemoveObserver(this); - DBusThreadManager::Get()->GetBluetoothAdapterClient()-> - RemoveObserver(this); - DBusThreadManager::Get()->GetBluetoothManagerClient()-> - RemoveObserver(this); - - STLDeleteValues(&devices_); -} - -void BluetoothAdapter::AddObserver(Observer* observer) { - DCHECK(observer); - observers_.AddObserver(observer); -} - -void BluetoothAdapter::RemoveObserver(Observer* observer) { - DCHECK(observer); - observers_.RemoveObserver(observer); -} - -bool BluetoothAdapter::IsPresent() const { - return !object_path_.value().empty() && !address_.empty(); -} - -bool BluetoothAdapter::IsPowered() const { - return powered_; -} - -void BluetoothAdapter::SetPowered(bool powered, - const base::Closure& callback, - const ErrorCallback& error_callback) { - DBusThreadManager::Get()->GetBluetoothAdapterClient()-> - GetProperties(object_path_)->powered.Set( - powered, - base::Bind(&BluetoothAdapter::OnSetPowered, - weak_ptr_factory_.GetWeakPtr(), - callback, - error_callback)); } -bool BluetoothAdapter::IsDiscovering() const { - return discovering_; +const std::string& BluetoothAdapter::address() const { + return address_; } -void BluetoothAdapter::SetDiscovering(bool discovering, - const base::Closure& callback, - const ErrorCallback& error_callback) { - if (discovering) { - DBusThreadManager::Get()->GetBluetoothAdapterClient()-> - StartDiscovery(object_path_, - base::Bind(&BluetoothAdapter::OnStartDiscovery, - weak_ptr_factory_.GetWeakPtr(), - callback, - error_callback)); - } else { - DBusThreadManager::Get()->GetBluetoothAdapterClient()-> - StopDiscovery(object_path_, - base::Bind(&BluetoothAdapter::OnStopDiscovery, - weak_ptr_factory_.GetWeakPtr(), - callback, - error_callback)); - } +const std::string& BluetoothAdapter::name() const { + return name_; } BluetoothAdapter::DeviceList BluetoothAdapter::GetDevices() { ConstDeviceList const_devices = - const_cast<const BluetoothAdapter *>(this)->GetDevices(); + const_cast<const BluetoothAdapter *>(this)->GetDevices(); DeviceList devices; for (ConstDeviceList::const_iterator i = const_devices.begin(); - i != const_devices.end(); ++i) + i != const_devices.end(); ++i) devices.push_back(const_cast<BluetoothDevice *>(*i)); return devices; } -BluetoothAdapter::ConstDeviceList BluetoothAdapter::GetDevices() const { - ConstDeviceList devices; - for (DevicesMap::const_iterator iter = devices_.begin(); - iter != devices_.end(); ++iter) - devices.push_back(iter->second); - - return devices; -} - -BluetoothDevice* BluetoothAdapter::GetDevice(const std::string& address) { - return const_cast<BluetoothDevice *>( - const_cast<const BluetoothAdapter *>(this)->GetDevice(address)); -} - -const BluetoothDevice* BluetoothAdapter::GetDevice( - const std::string& address) const { - DevicesMap::const_iterator iter = devices_.find(address); - if (iter != devices_.end()) - return iter->second; - - return NULL; -} - -void BluetoothAdapter::ReadLocalOutOfBandPairingData( - const BluetoothOutOfBandPairingDataCallback& callback, - const ErrorCallback& error_callback) { - DBusThreadManager::Get()->GetBluetoothOutOfBandClient()-> - ReadLocalData(object_path_, - base::Bind(&BluetoothAdapter::OnReadLocalData, - weak_ptr_factory_.GetWeakPtr(), - callback, - error_callback)); -} - -void BluetoothAdapter::TrackDefaultAdapter() { - DVLOG(1) << "Tracking default adapter"; - track_default_ = true; - DBusThreadManager::Get()->GetBluetoothManagerClient()-> - DefaultAdapter(base::Bind(&BluetoothAdapter::AdapterCallback, - weak_ptr_factory_.GetWeakPtr())); -} - -void BluetoothAdapter::FindAdapter(const std::string& address) { - DVLOG(1) << "Using adapter " << address; - track_default_ = false; - DBusThreadManager::Get()->GetBluetoothManagerClient()-> - FindAdapter(address, - base::Bind(&BluetoothAdapter::AdapterCallback, - weak_ptr_factory_.GetWeakPtr())); -} - -void BluetoothAdapter::AdapterCallback(const dbus::ObjectPath& adapter_path, - bool success) { - if (success) { - ChangeAdapter(adapter_path); - } else if (!object_path_.value().empty()) { - RemoveAdapter(); - } -} - -void BluetoothAdapter::DefaultAdapterChanged( - const dbus::ObjectPath& adapter_path) { - if (track_default_) - ChangeAdapter(adapter_path); -} - -void BluetoothAdapter::AdapterRemoved(const dbus::ObjectPath& adapter_path) { - if (adapter_path == object_path_) - RemoveAdapter(); -} - -void BluetoothAdapter::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 BluetoothAdapter::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 BluetoothAdapter::OnSetPowered(const base::Closure& callback, - const ErrorCallback& error_callback, - bool success) { - if (success) - callback.Run(); - else - error_callback.Run(); -} - -void BluetoothAdapter::PoweredChanged(bool powered) { - if (powered == powered_) - return; - - powered_ = powered; - - FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, - AdapterPoweredChanged(this, powered_)); -} - -void BluetoothAdapter::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 BluetoothAdapter::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 BluetoothAdapter::DiscoveringChanged(bool discovering) { - if (discovering == discovering_) - return; - - discovering_ = discovering; - - FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, - AdapterDiscoveringChanged(this, discovering_)); -} - -void BluetoothAdapter::OnReadLocalData( - const BluetoothOutOfBandPairingDataCallback& callback, - const ErrorCallback& error_callback, - const BluetoothOutOfBandPairingData& data, - bool success) { - if (success) - callback.Run(data); - else - error_callback.Run(); -} - -void BluetoothAdapter::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 BluetoothAdapter::DevicePropertyChanged( - const dbus::ObjectPath& device_path, - const std::string& property_name) { - UpdateDevice(device_path); -} - -void BluetoothAdapter::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); - BluetoothDevice* device; - const bool update_device = (iter != devices_.end()); - if (update_device) { - device = iter->second; - } else { - device = BluetoothDevice::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 BluetoothAdapter::ClearDevices() { - DevicesMap replace; - devices_.swap(replace); - for (DevicesMap::iterator iter = replace.begin(); - iter != replace.end(); ++iter) { - BluetoothDevice* device = iter->second; - if (device->IsSupported() || device->IsPaired()) - FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, - DeviceRemoved(this, device)); - - delete device; - } -} - -void BluetoothAdapter::DeviceCreated(const dbus::ObjectPath& adapter_path, - const dbus::ObjectPath& device_path) { - if (adapter_path != object_path_) - return; - - UpdateDevice(device_path); -} - -void BluetoothAdapter::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()) { - BluetoothDevice* 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 BluetoothAdapter::DevicesChanged( - const std::vector<dbus::ObjectPath>& devices) { - for (std::vector<dbus::ObjectPath>::const_iterator iter = - devices.begin(); iter != devices.end(); ++iter) - UpdateDevice(*iter); -} - -void BluetoothAdapter::ClearDiscoveredDevices() { - DevicesMap::iterator iter = devices_.begin(); - while (iter != devices_.end()) { - BluetoothDevice* 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 BluetoothAdapter::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. - BluetoothDevice* device; - DevicesMap::iterator iter = devices_.find(address); - const bool update_device = (iter != devices_.end()); - if (update_device) { - device = iter->second; - } else { - device = BluetoothDevice::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 BluetoothAdapter::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; - - BluetoothDevice* 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)); - } -} - - -// static -scoped_refptr<BluetoothAdapter> BluetoothAdapter::DefaultAdapter() { - if (!default_adapter.Get().get()) { - BluetoothAdapter* new_adapter = new BluetoothAdapter; - default_adapter.Get() = new_adapter->weak_ptr_factory_.GetWeakPtr(); - default_adapter.Get()->TrackDefaultAdapter(); - } - - return scoped_refptr<BluetoothAdapter>(default_adapter.Get()); -} - -// static -BluetoothAdapter* BluetoothAdapter::Create(const std::string& address) { - BluetoothAdapter* adapter = new BluetoothAdapter; - adapter->FindAdapter(address); - return adapter; -} - } // namespace chromeos diff --git a/chrome/browser/chromeos/bluetooth/bluetooth_adapter.h b/chrome/browser/chromeos/bluetooth/bluetooth_adapter.h index 673aac5..14a94a1 100644 --- a/chrome/browser/chromeos/bluetooth/bluetooth_adapter.h +++ b/chrome/browser/chromeos/bluetooth/bluetooth_adapter.h @@ -5,37 +5,25 @@ #ifndef CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_ADAPTER_H_ #define CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_ADAPTER_H_ -#include <map> #include <string> #include <vector> -#include "base/basictypes.h" #include "base/callback.h" #include "base/memory/ref_counted.h" -#include "base/observer_list.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 "dbus/object_path.h" namespace chromeos { class BluetoothDevice; -// The BluetoothAdapter class represents a local Bluetooth adapter which -// may be used to interact with remote Bluetooth devices. As well as -// providing support for determining whether an adapter is present, and -// whether the radio is powered, this class also provides support for -// obtaining the list of remote devices known to the adapter, discovering -// new devices, and providing notification of updates to device information. -// -// The class may be instantiated for either a specific adapter, or for the -// generic "default adapter" which may change depending on availability. -class BluetoothAdapter : public base::RefCounted<BluetoothAdapter>, - public BluetoothManagerClient::Observer, - public BluetoothAdapterClient::Observer, - public BluetoothDeviceClient::Observer { +struct BluetoothOutOfBandPairingData; + +// BluetoothAdapter represents a local Bluetooth adapter which may be used to +// interact with remote Bluetooth devices. As well as providing support for +// determining whether an adapter is present, and whether the radio is powered, +// this class also provides support for obtaining the list of remote devices +// known to the adapter, discovering new devices, and providing notification of +// updates to device information. +class BluetoothAdapter : public base::RefCounted<BluetoothAdapter> { public: // Interface for observing changes from bluetooth adapters. class Observer { @@ -81,12 +69,6 @@ class BluetoothAdapter : public base::RefCounted<BluetoothAdapter>, BluetoothDevice* device) {} }; - // Adds and removes observers for events on this bluetooth adapter, - // if monitoring multiple adapters check the |adapter| parameter of - // observer methods to determine which adapter is issuing the event. - void AddObserver(Observer* observer); - void RemoveObserver(Observer* observer); - // The ErrorCallback is used for methods that can fail in which case it // is called, in the success case the callback is simply not called. typedef base::Callback<void()> ErrorCallback; @@ -96,40 +78,47 @@ class BluetoothAdapter : public base::RefCounted<BluetoothAdapter>, typedef base::Callback<void(const BluetoothOutOfBandPairingData& data)> BluetoothOutOfBandPairingDataCallback; + // Adds and removes observers for events on this bluetooth adapter, + // if monitoring multiple adapters check the |adapter| parameter of + // observer methods to determine which adapter is issuing the event. + virtual void AddObserver(BluetoothAdapter::Observer* observer) = 0; + virtual void RemoveObserver( + BluetoothAdapter::Observer* observer) = 0; + // The address of this adapter. The address format is "XX:XX:XX:XX:XX:XX", // where each XX is a hexadecimal number. - const std::string& address() const { return address_; } + virtual const std::string& address() const; // The name of the adapter. - const std::string& name() const { return name_; } + virtual const std::string& name() const; // Indicates whether the adapter is actually present on the system, for // the default adapter this indicates whether any adapter is present. An // adapter is only considered present if the address has been obtained. - virtual bool IsPresent() const; + virtual bool IsPresent() const = 0; // Indicates whether the adapter radio is powered. - virtual bool IsPowered() const; + virtual bool IsPowered() const = 0; // Requests a change to the adapter radio power, setting |powered| to true // will turn on the radio and false will turn it off. On success, callback // will be called. On failure, |error_callback| will be called. - void SetPowered(bool powered, - const base::Closure& callback, - const ErrorCallback& error_callback); + virtual void SetPowered(bool powered, + const base::Closure& callback, + const ErrorCallback& error_callback) = 0; // Indicates whether the adapter is currently discovering new devices, // note that a typical discovery process has phases of this being true // followed by phases of being false when the adapter interrogates the // devices found. - virtual bool IsDiscovering() const; + virtual bool IsDiscovering() const = 0; // Requests that the adapter either begin discovering new devices when // |discovering| is true, or cease any discovery when false. On success, // callback will be called. On failure, |error_callback| will be called. virtual void SetDiscovering(bool discovering, const base::Closure& callback, - const ErrorCallback& error_callback); + const ErrorCallback& error_callback) = 0; // Requests the list of devices from the adapter, all are returned // including those currently connected and those paired. Use the @@ -137,205 +126,28 @@ class BluetoothAdapter : public base::RefCounted<BluetoothAdapter>, typedef std::vector<BluetoothDevice*> DeviceList; virtual DeviceList GetDevices(); typedef std::vector<const BluetoothDevice*> ConstDeviceList; - virtual ConstDeviceList GetDevices() const; + virtual ConstDeviceList GetDevices() const = 0; // Returns a pointer to the device with the given address |address| or // NULL if no such device is known. - virtual BluetoothDevice* GetDevice(const std::string& address); - virtual const BluetoothDevice* GetDevice(const std::string& address) const; + virtual BluetoothDevice* GetDevice(const std::string& address) = 0; + virtual const BluetoothDevice* GetDevice( + const std::string& address) const = 0; // Requests the local Out Of Band pairing data. virtual void ReadLocalOutOfBandPairingData( const BluetoothOutOfBandPairingDataCallback& callback, - const ErrorCallback& error_callback); - - // Returns the shared instance for the default adapter, whichever that may - // be at the time. Use IsPresent() and the AdapterPresentChanged() observer - // method to determine whether an adapter is actually available or not. - static scoped_refptr<BluetoothAdapter> DefaultAdapter(); + const ErrorCallback& error_callback) = 0; - // Creates an instance for a specific adapter named by |address|, which - // may be the bluetooth address of the adapter or a device name such as - // "hci0". - static BluetoothAdapter* Create(const std::string& address); - - private: + protected: friend class base::RefCounted<BluetoothAdapter>; - friend class BluetoothDevice; - friend class MockBluetoothAdapter; - - BluetoothAdapter(); virtual ~BluetoothAdapter(); - // Obtains the default adapter object path from the Bluetooth Daemon - // and tracks future changes to it. - void TrackDefaultAdapter(); - - // Obtains the object paht for the adapter named by |address| from the - // Bluetooth Daemon. - void FindAdapter(const std::string& address); - - // Called by dbus:: in response to the method call sent by both - // DefaultAdapter() and FindAdapter(), |object_path| will contain the - // dbus object path of the requested adapter when |success| is true. - void AdapterCallback(const dbus::ObjectPath& adapter_path, bool success); - - // BluetoothManagerClient::Observer override. - // - // Called when the default local bluetooth adapter changes. - // |object_path| is the dbus object path of the new default adapter. - // Not called if all adapters are removed. - virtual void DefaultAdapterChanged(const dbus::ObjectPath& adapter_path) - OVERRIDE; - - // BluetoothManagerClient::Observer override. - // - // Called when a local bluetooth adapter is removed. - // |object_path| is the dbus object path of the adapter. - virtual void AdapterRemoved(const dbus::ObjectPath& adapter_path) OVERRIDE; - - // Changes the tracked adapter to the dbus object path |adapter_path|, - // clearing information from the previously tracked adapter and updating - // to the new adapter. - void ChangeAdapter(const dbus::ObjectPath& adapter_path); - - // Clears the tracked adapter information. - void RemoveAdapter(); - - // Called by dbus:: in response to the method call send by SetPowered(). - // |callback| and |error_callback| are the callbacks passed to SetPowered(). - void OnSetPowered(const base::Closure& callback, - const ErrorCallback& error_callback, - bool success); - - // Updates the tracked state of the adapter's radio power to |powered| - // and notifies observers. Called on receipt of a property changed signal, - // and directly using values obtained from properties. - void PoweredChanged(bool powered); - - // Called by dbus:: in response to the method calls send by SetDiscovering(). - // |callback| and |error_callback| are the callbacks passed to - // SetDiscovering(). - void OnStartDiscovery(const base::Closure& callback, - const ErrorCallback& error_callback, - const dbus::ObjectPath& adapter_path, - bool success); - void OnStopDiscovery(const base::Closure& callback, - const ErrorCallback& error_callback, - const dbus::ObjectPath& adapter_path, - bool success); - - // Updates the tracked state of the adapter's discovering state to - // |discovering| and notifies observers. Called on receipt of a property - // changed signal, and directly using values obtained from properties. - void DiscoveringChanged(bool discovering); - - // Called by dbus:: in response to the ReadLocalData method call. - void OnReadLocalData(const BluetoothOutOfBandPairingDataCallback& callback, - const ErrorCallback& error_callback, - const BluetoothOutOfBandPairingData& data, - bool success); - - // BluetoothAdapterClient::Observer override. - // - // Called when the adapter with object path |adapter_path| has a - // change in value of the property named |property_name|. - virtual void AdapterPropertyChanged(const dbus::ObjectPath& adapter_path, - const std::string& property_name) - OVERRIDE; - - // BluetoothDeviceClient::Observer override. - // - // Called when the device with object path |device_path| has a - // change in value of the property named |property_name|. - virtual void DevicePropertyChanged(const dbus::ObjectPath& device_path, - const std::string& property_name) - OVERRIDE; - - // Updates information on the device with object path |device_path|, - // adding it to the |devices_| map if not already present. - void UpdateDevice(const dbus::ObjectPath& device_path); - - // Clears the |devices_| list, notifying obsevers of the device removal. - void ClearDevices(); - - // BluetoothAdapterClient::Observer override. - // - // Called when the adapter with object path |object_path| has a - // new known device with object path |object_path|. - virtual void DeviceCreated(const dbus::ObjectPath& adapter_path, - const dbus::ObjectPath& device_path) OVERRIDE; - - // BluetoothAdapterClient::Observer override. - // - // Called when the adapter with object path |object_path| removes - // the known device with object path |object_path|. - virtual void DeviceRemoved(const dbus::ObjectPath& adapter_path, - const dbus::ObjectPath& device_path) OVERRIDE; - - // Updates the adapter |devices_| list, adding or updating devices using - // the object paths in the|devices| list. This doesn't remove devices, - // relying instead on the DeviceRemoved() signal for that. Called on - // receipt of a property changed signal, and directly using values obtained - // from properties. - void DevicesChanged(const std::vector<dbus::ObjectPath>& devices); - - // Clears discovered devices from the |devices_| list, notifying - // observers, and leaving only those devices with a dbus object path. - void ClearDiscoveredDevices(); - - // BluetoothAdapterClient::Observer override. - // - // Called when the adapter with object path |object_path| discovers - // a new remote device with address |address| and properties - // |properties|, there is no device object path until connected. - // - // |properties| supports only value() calls, not Get() or Set(), and - // should be copied if needed. - virtual void DeviceFound( - const dbus::ObjectPath& adapter_path, const std::string& address, - const BluetoothDeviceClient::Properties& properties) OVERRIDE; - - // BluetoothAdapterClient::Observer override. - // - // Called when the adapter with object path |object_path| can no - // longer communicate with the discovered removed device with - // address |address|. - virtual void DeviceDisappeared(const dbus::ObjectPath& object_path, - const std::string& address) OVERRIDE; - - // List of observers interested in event notifications from us. - ObserverList<BluetoothAdapter::Observer> observers_; - - // Object path of adapter for this instance, this is fixed at creation time - // unless |track_default_| is true in which case we update it to always - // point at the default adapter. - bool track_default_; - dbus::ObjectPath object_path_; - // Address of the adapter. std::string address_; // Name of the adapter. std::string name_; - - // Tracked adapter state, cached locally so we only send change notifications - // to observers on a genuine change. - bool powered_; - bool discovering_; - - // Devices paired with, connected to, discovered by, or visible to the - // adapter. The key is the Bluetooth address of the device and the value - // is the BluetoothDevice object whose lifetime is managed by the adapter - // instance. - typedef std::map<const std::string, BluetoothDevice*> DevicesMap; - DevicesMap devices_; - - // Note: This should remain the last member so it'll be destroyed and - // invalidate its weak pointers before any other members are destroyed. - base::WeakPtrFactory<BluetoothAdapter> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(BluetoothAdapter); }; } // namespace chromeos 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 diff --git a/chrome/browser/chromeos/bluetooth/bluetooth_adapter_chromeos.h b/chrome/browser/chromeos/bluetooth/bluetooth_adapter_chromeos.h new file mode 100644 index 0000000..2a0db65 --- /dev/null +++ b/chrome/browser/chromeos/bluetooth/bluetooth_adapter_chromeos.h @@ -0,0 +1,232 @@ +// 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. + +#ifndef CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_ADAPTER_CHROMEOS_H_ +#define CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_ADAPTER_CHROMEOS_H_ + +#include <map> +#include <string> +#include <vector> + +#include "base/basictypes.h" +#include "base/callback.h" +#include "base/observer_list.h" +#include "chrome/browser/chromeos/bluetooth/bluetooth_adapter.h" +#include "chromeos/dbus/bluetooth_adapter_client.h" +#include "chromeos/dbus/bluetooth_device_client.h" +#include "chromeos/dbus/bluetooth_manager_client.h" +#include "dbus/object_path.h" + +namespace chromeos { + +class BluetoothDeviceChromeOs; + +struct BluetoothOutOfBandPairingData; + +// The BluetoothAdapterChromeOs class is an implementation of BluetoothAdapter +// for Chrome OS platform. +class BluetoothAdapterChromeOs : public BluetoothAdapter, + public BluetoothManagerClient::Observer, + public BluetoothAdapterClient::Observer, + public BluetoothDeviceClient::Observer { + public: + // BluetoothAdapter override + virtual void AddObserver(BluetoothAdapter::Observer* observer) OVERRIDE; + virtual void RemoveObserver(BluetoothAdapter::Observer* observer) OVERRIDE; + virtual bool IsPresent() const OVERRIDE; + virtual bool IsPowered() const OVERRIDE; + virtual void SetPowered( + bool powered, + const base::Closure& callback, + const ErrorCallback& error_callback) OVERRIDE; + virtual bool IsDiscovering() const OVERRIDE; + virtual void SetDiscovering( + bool discovering, + const base::Closure& callback, + const ErrorCallback& error_callback) OVERRIDE; + virtual ConstDeviceList GetDevices() const OVERRIDE; + virtual BluetoothDevice* GetDevice(const std::string& address) OVERRIDE; + virtual const BluetoothDevice* GetDevice( + const std::string& address) const OVERRIDE; + virtual void ReadLocalOutOfBandPairingData( + const BluetoothOutOfBandPairingDataCallback& callback, + const ErrorCallback& error_callback) OVERRIDE; + + private: + friend class BluetoothAdapterFactory; + friend class BluetoothDeviceChromeOs; + friend class MockBluetoothAdapter; + + BluetoothAdapterChromeOs(); + virtual ~BluetoothAdapterChromeOs(); + + // Obtains the default adapter object path from the Bluetooth Daemon + // and tracks future changes to it. + void TrackDefaultAdapter(); + + // Obtains the object paht for the adapter named by |address| from the + // Bluetooth Daemon. + void FindAdapter(const std::string& address); + + // Called by dbus:: in response to the method call sent by both + // DefaultAdapter() and FindAdapter(), |object_path| will contain the + // dbus object path of the requested adapter when |success| is true. + void AdapterCallback(const dbus::ObjectPath& adapter_path, bool success); + + // BluetoothManagerClient::Observer override. + // + // Called when the default local bluetooth adapter changes. + // |object_path| is the dbus object path of the new default adapter. + // Not called if all adapters are removed. + virtual void DefaultAdapterChanged(const dbus::ObjectPath& adapter_path) + OVERRIDE; + + // BluetoothManagerClient::Observer override. + // + // Called when a local bluetooth adapter is removed. + // |object_path| is the dbus object path of the adapter. + virtual void AdapterRemoved(const dbus::ObjectPath& adapter_path) OVERRIDE; + + // Changes the tracked adapter to the dbus object path |adapter_path|, + // clearing information from the previously tracked adapter and updating + // to the new adapter. + void ChangeAdapter(const dbus::ObjectPath& adapter_path); + + // Clears the tracked adapter information. + void RemoveAdapter(); + + // Called by dbus:: in response to the method call send by SetPowered(). + // |callback| and |error_callback| are the callbacks passed to SetPowered(). + void OnSetPowered(const base::Closure& callback, + const ErrorCallback& error_callback, + bool success); + + // Updates the tracked state of the adapter's radio power to |powered| + // and notifies observers. Called on receipt of a property changed signal, + // and directly using values obtained from properties. + void PoweredChanged(bool powered); + + // Called by dbus:: in response to the method calls send by SetDiscovering(). + // |callback| and |error_callback| are the callbacks passed to + // SetDiscovering(). + void OnStartDiscovery(const base::Closure& callback, + const ErrorCallback& error_callback, + const dbus::ObjectPath& adapter_path, + bool success); + void OnStopDiscovery(const base::Closure& callback, + const ErrorCallback& error_callback, + const dbus::ObjectPath& adapter_path, + bool success); + + // Updates the tracked state of the adapter's discovering state to + // |discovering| and notifies observers. Called on receipt of a property + // changed signal, and directly using values obtained from properties. + void DiscoveringChanged(bool discovering); + + // Called by dbus:: in response to the ReadLocalData method call. + void OnReadLocalData(const BluetoothOutOfBandPairingDataCallback& callback, + const ErrorCallback& error_callback, + const BluetoothOutOfBandPairingData& data, + bool success); + + // BluetoothAdapterClient::Observer override. + // + // Called when the adapter with object path |adapter_path| has a + // change in value of the property named |property_name|. + virtual void AdapterPropertyChanged(const dbus::ObjectPath& adapter_path, + const std::string& property_name) + OVERRIDE; + + // BluetoothDeviceClient::Observer override. + // + // Called when the device with object path |device_path| has a + // change in value of the property named |property_name|. + virtual void DevicePropertyChanged(const dbus::ObjectPath& device_path, + const std::string& property_name) + OVERRIDE; + + // Updates information on the device with object path |device_path|, + // adding it to the |devices_| map if not already present. + void UpdateDevice(const dbus::ObjectPath& device_path); + + // Clears the |devices_| list, notifying obsevers of the device removal. + void ClearDevices(); + + // BluetoothAdapterClient::Observer override. + // + // Called when the adapter with object path |object_path| has a + // new known device with object path |object_path|. + virtual void DeviceCreated(const dbus::ObjectPath& adapter_path, + const dbus::ObjectPath& device_path) OVERRIDE; + + // BluetoothAdapterClient::Observer override. + // + // Called when the adapter with object path |object_path| removes + // the known device with object path |object_path|. + virtual void DeviceRemoved(const dbus::ObjectPath& adapter_path, + const dbus::ObjectPath& device_path) OVERRIDE; + + // Updates the adapter |devices_| list, adding or updating devices using + // the object paths in the|devices| list. This doesn't remove devices, + // relying instead on the DeviceRemoved() signal for that. Called on + // receipt of a property changed signal, and directly using values obtained + // from properties. + void DevicesChanged(const std::vector<dbus::ObjectPath>& devices); + + // Clears discovered devices from the |devices_| list, notifying + // observers, and leaving only those devices with a dbus object path. + void ClearDiscoveredDevices(); + + // BluetoothAdapterClient::Observer override. + // + // Called when the adapter with object path |object_path| discovers + // a new remote device with address |address| and properties + // |properties|, there is no device object path until connected. + // + // |properties| supports only value() calls, not Get() or Set(), and + // should be copied if needed. + virtual void DeviceFound( + const dbus::ObjectPath& adapter_path, + const std::string& address, + const BluetoothDeviceClient::Properties& properties) OVERRIDE; + + // BluetoothAdapterClient::Observer override. + // + // Called when the adapter with object path |object_path| can no + // longer communicate with the discovered removed device with + // address |address|. + virtual void DeviceDisappeared(const dbus::ObjectPath& object_path, + const std::string& address) OVERRIDE; + + // List of observers interested in event notifications from us. + ObserverList<BluetoothAdapter::Observer> observers_; + + // Object path of adapter for this instance, this is fixed at creation time + // unless |track_default_| is true in which case we update it to always + // point at the default adapter. + bool track_default_; + dbus::ObjectPath object_path_; + + // Tracked adapter state, cached locally so we only send change notifications + // to observers on a genuine change. + bool powered_; + bool discovering_; + + // Devices paired with, connected to, discovered by, or visible to the + // adapter. The key is the Bluetooth address of the device and the value + // is the BluetoothDeviceChromeOs object whose lifetime is managed by the + // adapter instance. + typedef std::map<const std::string, BluetoothDeviceChromeOs*> DevicesMap; + DevicesMap devices_; + + // Note: This should remain the last member so it'll be destroyed and + // invalidate its weak pointers before any other members are destroyed. + base::WeakPtrFactory<BluetoothAdapterChromeOs> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(BluetoothAdapterChromeOs); +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_ADAPTER_CHROMEOS_H_ diff --git a/chrome/browser/chromeos/bluetooth/bluetooth_adapter_unittest.cc b/chrome/browser/chromeos/bluetooth/bluetooth_adapter_chromeos_unittest.cc index 8c168af..d909559 100644 --- a/chrome/browser/chromeos/bluetooth/bluetooth_adapter_unittest.cc +++ b/chrome/browser/chromeos/bluetooth/bluetooth_adapter_chromeos_unittest.cc @@ -3,6 +3,8 @@ // found in the LICENSE file. #include "chrome/browser/chromeos/bluetooth/bluetooth_adapter.h" +#include "chrome/browser/chromeos/bluetooth/bluetooth_adapter_chromeos.h" +#include "chrome/browser/chromeos/bluetooth/bluetooth_adapter_factory.h" #include "chrome/browser/chromeos/bluetooth/test/mock_bluetooth_adapter.h" #include "chromeos/dbus/mock_bluetooth_adapter_client.h" #include "chromeos/dbus/mock_bluetooth_manager_client.h" @@ -17,7 +19,7 @@ using ::testing::SaveArg; namespace chromeos { -class BluetoothAdapterTest : public testing::Test { +class BluetoothAdapterChromeOsTest : public testing::Test { public: virtual void SetUp() { MockDBusThreadManager* mock_dbus_thread_manager = new MockDBusThreadManager; @@ -55,7 +57,7 @@ class BluetoothAdapterTest : public testing::Test { bool error_callback_called_; }; -TEST_F(BluetoothAdapterTest, DefaultAdapterNotPresent) { +TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterNotPresent) { // Create the default adapter instance; // BluetoothManagerClient::DefaultAdapter will be called once, passing // a callback to obtain the adapter path. @@ -63,7 +65,8 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterNotPresent) { EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) .WillOnce(SaveArg<0>(&adapter_callback)); - scoped_refptr<BluetoothAdapter> adapter = BluetoothAdapter::DefaultAdapter(); + scoped_refptr<BluetoothAdapter> adapter = + BluetoothAdapterFactory::DefaultAdapter(); // Call the adapter callback; make out it failed. // BluetoothAdapter::Observer::AdapterPresentChanged must not be called. @@ -79,7 +82,7 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterNotPresent) { EXPECT_FALSE(adapter->IsPresent()); } -TEST_F(BluetoothAdapterTest, DefaultAdapterWithAddress) { +TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterWithAddress) { const dbus::ObjectPath adapter_path("/fake/hci0"); const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; @@ -90,7 +93,8 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterWithAddress) { EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) .WillOnce(SaveArg<0>(&adapter_callback)); - scoped_refptr<BluetoothAdapter> adapter = BluetoothAdapter::DefaultAdapter(); + scoped_refptr<BluetoothAdapter> adapter = + BluetoothAdapterFactory::DefaultAdapter(); // Call the adapter callback; // BluetoothAdapterClient::GetProperties will be called once to obtain @@ -116,7 +120,7 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterWithAddress) { EXPECT_EQ(adapter_address, adapter->address()); } -TEST_F(BluetoothAdapterTest, DefaultAdapterWithoutAddress) { +TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterWithoutAddress) { const dbus::ObjectPath adapter_path("/fake/hci0"); const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; @@ -127,7 +131,8 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterWithoutAddress) { EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) .WillOnce(SaveArg<0>(&adapter_callback)); - scoped_refptr<BluetoothAdapter> adapter = BluetoothAdapter::DefaultAdapter(); + scoped_refptr<BluetoothAdapter> adapter = + BluetoothAdapterFactory::DefaultAdapter(); // Call the adapter callback; // BluetoothAdapterClient::GetProperties will be called once to obtain @@ -157,7 +162,10 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterWithoutAddress) { EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), true)) .Times(1); - static_cast<BluetoothAdapterClient::Observer*>(adapter.get()) + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast<BluetoothAdapterChromeOs*>(adapter.get()); + + static_cast<BluetoothAdapterClient::Observer*>(adapter_chromeos) ->AdapterPropertyChanged(adapter_path, adapter_properties.address.name()); @@ -166,7 +174,7 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterWithoutAddress) { EXPECT_EQ(adapter_address, adapter->address()); } -TEST_F(BluetoothAdapterTest, DefaultAdapterBecomesPresentWithAddress) { +TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterBecomesPresentWithAddress) { const dbus::ObjectPath adapter_path("/fake/hci0"); const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; @@ -177,7 +185,8 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterBecomesPresentWithAddress) { EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) .WillOnce(SaveArg<0>(&adapter_callback)); - scoped_refptr<BluetoothAdapter> adapter = BluetoothAdapter::DefaultAdapter(); + scoped_refptr<BluetoothAdapter> adapter = + BluetoothAdapterFactory::DefaultAdapter(); // Call the adapter callback; make out it failed. adapter_callback.Run(dbus::ObjectPath(""), false); @@ -198,7 +207,10 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterBecomesPresentWithAddress) { EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), true)) .Times(1); - static_cast<BluetoothManagerClient::Observer*>(adapter.get()) + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast<BluetoothAdapterChromeOs*>(adapter.get()); + + static_cast<BluetoothManagerClient::Observer*>(adapter_chromeos) ->DefaultAdapterChanged(adapter_path); // Adapter should be present with the new address. @@ -206,7 +218,7 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterBecomesPresentWithAddress) { EXPECT_EQ(adapter_address, adapter->address()); } -TEST_F(BluetoothAdapterTest, DefaultAdapterReplacedWithAddress) { +TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterReplacedWithAddress) { const dbus::ObjectPath initial_adapter_path("/fake/hci0"); const dbus::ObjectPath new_adapter_path("/fake/hci1"); const std::string initial_adapter_address = "CA:FE:4A:C0:FE:FE"; @@ -219,7 +231,8 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterReplacedWithAddress) { EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) .WillOnce(SaveArg<0>(&adapter_callback)); - scoped_refptr<BluetoothAdapter> adapter = BluetoothAdapter::DefaultAdapter(); + scoped_refptr<BluetoothAdapter> adapter = + BluetoothAdapterFactory::DefaultAdapter(); // Call the adapter callback; // BluetoothAdapterClient::GetProperties will be called once to obtain @@ -252,7 +265,10 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterReplacedWithAddress) { EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), true)) .Times(1); - static_cast<BluetoothManagerClient::Observer*>(adapter.get()) + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast<BluetoothAdapterChromeOs*>(adapter.get()); + + static_cast<BluetoothManagerClient::Observer*>(adapter_chromeos) ->DefaultAdapterChanged(new_adapter_path); // Adapter should be present with the new address. @@ -260,7 +276,8 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterReplacedWithAddress) { EXPECT_EQ(new_adapter_address, adapter->address()); } -TEST_F(BluetoothAdapterTest, DefaultAdapterBecomesPresentWithoutAddress) { +TEST_F(BluetoothAdapterChromeOsTest, + DefaultAdapterBecomesPresentWithoutAddress) { const dbus::ObjectPath adapter_path("/fake/hci0"); const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; @@ -271,7 +288,8 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterBecomesPresentWithoutAddress) { EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) .WillOnce(SaveArg<0>(&adapter_callback)); - scoped_refptr<BluetoothAdapter> adapter = BluetoothAdapter::DefaultAdapter(); + scoped_refptr<BluetoothAdapter> adapter = + BluetoothAdapterFactory::DefaultAdapter(); // Call the adapter callback; make out it failed. adapter_callback.Run(dbus::ObjectPath(""), false); @@ -291,7 +309,10 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterBecomesPresentWithoutAddress) { EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), _)) .Times(0); - static_cast<BluetoothManagerClient::Observer*>(adapter.get()) + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast<BluetoothAdapterChromeOs*>(adapter.get()); + + static_cast<BluetoothManagerClient::Observer*>(adapter_chromeos) ->DefaultAdapterChanged(adapter_path); // Adapter should not be present yet. @@ -304,7 +325,7 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterBecomesPresentWithoutAddress) { EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), true)) .Times(1); - static_cast<BluetoothAdapterClient::Observer*>(adapter.get()) + static_cast<BluetoothAdapterClient::Observer*>(adapter_chromeos) ->AdapterPropertyChanged(adapter_path, adapter_properties.address.name()); @@ -313,7 +334,7 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterBecomesPresentWithoutAddress) { EXPECT_EQ(adapter_address, adapter->address()); } -TEST_F(BluetoothAdapterTest, DefaultAdapterReplacedWithoutAddress) { +TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterReplacedWithoutAddress) { const dbus::ObjectPath initial_adapter_path("/fake/hci0"); const dbus::ObjectPath new_adapter_path("/fake/hci1"); const std::string initial_adapter_address = "CA:FE:4A:C0:FE:FE"; @@ -326,7 +347,8 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterReplacedWithoutAddress) { EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) .WillOnce(SaveArg<0>(&adapter_callback)); - scoped_refptr<BluetoothAdapter> adapter = BluetoothAdapter::DefaultAdapter(); + scoped_refptr<BluetoothAdapter> adapter = + BluetoothAdapterFactory::DefaultAdapter(); // Call the adapter callback; // BluetoothAdapterClient::GetProperties will be called once to obtain @@ -355,7 +377,10 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterReplacedWithoutAddress) { EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), false)) .Times(1); - static_cast<BluetoothManagerClient::Observer*>(adapter.get()) + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast<BluetoothAdapterChromeOs*>(adapter.get()); + + static_cast<BluetoothManagerClient::Observer*>(adapter_chromeos) ->DefaultAdapterChanged(new_adapter_path); // Adapter should be now marked not present. @@ -368,7 +393,7 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterReplacedWithoutAddress) { EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), true)) .Times(1); - static_cast<BluetoothAdapterClient::Observer*>(adapter.get()) + static_cast<BluetoothAdapterClient::Observer*>(adapter_chromeos) ->AdapterPropertyChanged(new_adapter_path, new_adapter_properties.address.name()); @@ -377,7 +402,7 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterReplacedWithoutAddress) { EXPECT_EQ(new_adapter_address, adapter->address()); } -TEST_F(BluetoothAdapterTest, DefaultAdapterRemoved) { +TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterRemoved) { const dbus::ObjectPath adapter_path("/fake/hci0"); const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; @@ -388,7 +413,8 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterRemoved) { EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) .WillOnce(SaveArg<0>(&adapter_callback)); - scoped_refptr<BluetoothAdapter> adapter = BluetoothAdapter::DefaultAdapter(); + scoped_refptr<BluetoothAdapter> adapter = + BluetoothAdapterFactory::DefaultAdapter(); // Call the adapter callback; // BluetoothAdapterClient::GetProperties will be called once to obtain @@ -410,14 +436,17 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterRemoved) { EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), false)) .Times(1); - static_cast<BluetoothManagerClient::Observer*>(adapter.get()) + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast<BluetoothAdapterChromeOs*>(adapter.get()); + + static_cast<BluetoothManagerClient::Observer*>(adapter_chromeos) ->AdapterRemoved(adapter_path); // Adapter should be no longer present. EXPECT_FALSE(adapter->IsPresent()); } -TEST_F(BluetoothAdapterTest, DefaultAdapterWithoutAddressRemoved) { +TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterWithoutAddressRemoved) { const dbus::ObjectPath adapter_path("/fake/hci0"); // Create the default adapter instance; @@ -427,7 +456,8 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterWithoutAddressRemoved) { EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) .WillOnce(SaveArg<0>(&adapter_callback)); - scoped_refptr<BluetoothAdapter> adapter = BluetoothAdapter::DefaultAdapter(); + scoped_refptr<BluetoothAdapter> adapter = + BluetoothAdapterFactory::DefaultAdapter(); // Call the adapter callback; // BluetoothAdapterClient::GetProperties will be called once to obtain @@ -448,14 +478,18 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterWithoutAddressRemoved) { EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), _)) .Times(0); - static_cast<BluetoothManagerClient::Observer*>(adapter.get()) + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast<BluetoothAdapterChromeOs*>(adapter.get()); + + static_cast<BluetoothManagerClient::Observer*>(adapter_chromeos) ->AdapterRemoved(adapter_path); // Adapter should be still no longer present. EXPECT_FALSE(adapter->IsPresent()); } -TEST_F(BluetoothAdapterTest, DefaultAdapterPoweredPropertyInitiallyFalse) { +TEST_F(BluetoothAdapterChromeOsTest, + DefaultAdapterPoweredPropertyInitiallyFalse) { const dbus::ObjectPath adapter_path("/fake/hci0"); const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; @@ -466,7 +500,8 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterPoweredPropertyInitiallyFalse) { EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) .WillOnce(SaveArg<0>(&adapter_callback)); - scoped_refptr<BluetoothAdapter> adapter = BluetoothAdapter::DefaultAdapter(); + scoped_refptr<BluetoothAdapter> adapter = + BluetoothAdapterFactory::DefaultAdapter(); // Call the adapter callback; // BluetoothAdapterClient::GetProperties will be called once to obtain @@ -484,7 +519,8 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterPoweredPropertyInitiallyFalse) { EXPECT_FALSE(adapter->IsPowered()); } -TEST_F(BluetoothAdapterTest, DefaultAdapterPoweredPropertyInitiallyTrue) { +TEST_F(BluetoothAdapterChromeOsTest, + DefaultAdapterPoweredPropertyInitiallyTrue) { const dbus::ObjectPath adapter_path("/fake/hci0"); const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; @@ -495,7 +531,8 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterPoweredPropertyInitiallyTrue) { EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) .WillOnce(SaveArg<0>(&adapter_callback)); - scoped_refptr<BluetoothAdapter> adapter = BluetoothAdapter::DefaultAdapter(); + scoped_refptr<BluetoothAdapter> adapter = + BluetoothAdapterFactory::DefaultAdapter(); // Call the adapter callback; // BluetoothAdapterClient::GetProperties will be called once to obtain @@ -523,7 +560,7 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterPoweredPropertyInitiallyTrue) { EXPECT_TRUE(adapter->IsPowered()); } -TEST_F(BluetoothAdapterTest, +TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterPoweredPropertyInitiallyTrueWithoutAddress) { const dbus::ObjectPath adapter_path("/fake/hci0"); const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; @@ -535,7 +572,8 @@ TEST_F(BluetoothAdapterTest, EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) .WillOnce(SaveArg<0>(&adapter_callback)); - scoped_refptr<BluetoothAdapter> adapter = BluetoothAdapter::DefaultAdapter(); + scoped_refptr<BluetoothAdapter> adapter = + BluetoothAdapterFactory::DefaultAdapter(); // Call the adapter callback; // BluetoothAdapterClient::GetProperties will be called once to obtain @@ -569,7 +607,10 @@ TEST_F(BluetoothAdapterTest, EXPECT_CALL(adapter_observer, AdapterPoweredChanged(adapter.get(), true)) .Times(1); - static_cast<BluetoothAdapterClient::Observer*>(adapter.get()) + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast<BluetoothAdapterChromeOs*>(adapter.get()); + + static_cast<BluetoothAdapterClient::Observer*>(adapter_chromeos) ->AdapterPropertyChanged(adapter_path, adapter_properties.address.name()); @@ -577,7 +618,7 @@ TEST_F(BluetoothAdapterTest, EXPECT_TRUE(adapter->IsPowered()); } -TEST_F(BluetoothAdapterTest, DefaultAdapterPoweredPropertyChanged) { +TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterPoweredPropertyChanged) { const dbus::ObjectPath adapter_path("/fake/hci0"); const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; @@ -588,7 +629,8 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterPoweredPropertyChanged) { EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) .WillOnce(SaveArg<0>(&adapter_callback)); - scoped_refptr<BluetoothAdapter> adapter = BluetoothAdapter::DefaultAdapter(); + scoped_refptr<BluetoothAdapter> adapter = + BluetoothAdapterFactory::DefaultAdapter(); // Call the adapter callback; // BluetoothAdapterClient::GetProperties will be called once to obtain @@ -614,7 +656,11 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterPoweredPropertyChanged) { .Times(1); adapter_properties.powered.ReplaceValue(true); - static_cast<BluetoothAdapterClient::Observer*>(adapter.get()) + + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast<BluetoothAdapterChromeOs*>(adapter.get()); + + static_cast<BluetoothAdapterClient::Observer*>(adapter_chromeos) ->AdapterPropertyChanged(adapter_path, adapter_properties.powered.name()); @@ -622,7 +668,7 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterPoweredPropertyChanged) { EXPECT_TRUE(adapter->IsPowered()); } -TEST_F(BluetoothAdapterTest, DefaultAdapterPoweredPropertyUnchanged) { +TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterPoweredPropertyUnchanged) { const dbus::ObjectPath adapter_path("/fake/hci0"); const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; @@ -633,7 +679,8 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterPoweredPropertyUnchanged) { EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) .WillOnce(SaveArg<0>(&adapter_callback)); - scoped_refptr<BluetoothAdapter> adapter = BluetoothAdapter::DefaultAdapter(); + scoped_refptr<BluetoothAdapter> adapter = + BluetoothAdapterFactory::DefaultAdapter(); // Call the adapter callback; // BluetoothAdapterClient::GetProperties will be called once to obtain @@ -658,7 +705,10 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterPoweredPropertyUnchanged) { EXPECT_CALL(adapter_observer, AdapterPoweredChanged(adapter.get(), _)) .Times(0); - static_cast<BluetoothAdapterClient::Observer*>(adapter.get()) + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast<BluetoothAdapterChromeOs*>(adapter.get()); + + static_cast<BluetoothAdapterClient::Observer*>(adapter_chromeos) ->AdapterPropertyChanged(adapter_path, adapter_properties.powered.name()); @@ -666,7 +716,7 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterPoweredPropertyUnchanged) { EXPECT_TRUE(adapter->IsPowered()); } -TEST_F(BluetoothAdapterTest, +TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterPoweredPropertyChangedWithoutAddress) { const dbus::ObjectPath adapter_path("/fake/hci0"); const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; @@ -678,7 +728,8 @@ TEST_F(BluetoothAdapterTest, EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) .WillOnce(SaveArg<0>(&adapter_callback)); - scoped_refptr<BluetoothAdapter> adapter = BluetoothAdapter::DefaultAdapter(); + scoped_refptr<BluetoothAdapter> adapter = + BluetoothAdapterFactory::DefaultAdapter(); // Call the adapter callback; // BluetoothAdapterClient::GetProperties will be called once to obtain @@ -705,7 +756,10 @@ TEST_F(BluetoothAdapterTest, EXPECT_CALL(adapter_observer, AdapterPoweredChanged(adapter.get(), _)) .Times(0); - static_cast<BluetoothAdapterClient::Observer*>(adapter.get()) + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast<BluetoothAdapterChromeOs*>(adapter.get()); + + static_cast<BluetoothAdapterClient::Observer*>(adapter_chromeos) ->AdapterPropertyChanged(adapter_path, adapter_properties.powered.name()); @@ -723,7 +777,7 @@ TEST_F(BluetoothAdapterTest, EXPECT_CALL(adapter_observer, AdapterPoweredChanged(adapter.get(), true)) .Times(1); - static_cast<BluetoothAdapterClient::Observer*>(adapter.get()) + static_cast<BluetoothAdapterClient::Observer*>(adapter_chromeos) ->AdapterPropertyChanged(adapter_path, adapter_properties.address.name()); @@ -731,7 +785,8 @@ TEST_F(BluetoothAdapterTest, EXPECT_TRUE(adapter->IsPowered()); } -TEST_F(BluetoothAdapterTest, DefaultAdapterPoweredPropertyResetOnReplace) { +TEST_F(BluetoothAdapterChromeOsTest, + DefaultAdapterPoweredPropertyResetOnReplace) { const dbus::ObjectPath initial_adapter_path("/fake/hci0"); const dbus::ObjectPath new_adapter_path("/fake/hci1"); const std::string initial_adapter_address = "CA:FE:4A:C0:FE:FE"; @@ -744,7 +799,8 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterPoweredPropertyResetOnReplace) { EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) .WillOnce(SaveArg<0>(&adapter_callback)); - scoped_refptr<BluetoothAdapter> adapter = BluetoothAdapter::DefaultAdapter(); + scoped_refptr<BluetoothAdapter> adapter = + BluetoothAdapterFactory::DefaultAdapter(); // Call the adapter callback; // BluetoothAdapterClient::GetProperties will be called once to obtain @@ -783,14 +839,17 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterPoweredPropertyResetOnReplace) { EXPECT_CALL(adapter_observer, AdapterPoweredChanged(adapter.get(), false)) .Times(1); - static_cast<BluetoothManagerClient::Observer*>(adapter.get()) + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast<BluetoothAdapterChromeOs*>(adapter.get()); + + static_cast<BluetoothManagerClient::Observer*>(adapter_chromeos) ->DefaultAdapterChanged(new_adapter_path); // Adapter should have the new property value. EXPECT_FALSE(adapter->IsPowered()); } -TEST_F(BluetoothAdapterTest, +TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterPoweredPropertyResetOnReplaceWhenTrue) { const dbus::ObjectPath initial_adapter_path("/fake/hci0"); const dbus::ObjectPath new_adapter_path("/fake/hci1"); @@ -804,7 +863,8 @@ TEST_F(BluetoothAdapterTest, EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) .WillOnce(SaveArg<0>(&adapter_callback)); - scoped_refptr<BluetoothAdapter> adapter = BluetoothAdapter::DefaultAdapter(); + scoped_refptr<BluetoothAdapter> adapter = + BluetoothAdapterFactory::DefaultAdapter(); // Call the adapter callback; // BluetoothAdapterClient::GetProperties will be called once to obtain @@ -852,14 +912,18 @@ TEST_F(BluetoothAdapterTest, .Times(1); } - static_cast<BluetoothManagerClient::Observer*>(adapter.get()) + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast<BluetoothAdapterChromeOs*>(adapter.get()); + + static_cast<BluetoothManagerClient::Observer*>(adapter_chromeos) ->DefaultAdapterChanged(new_adapter_path); // Adapter should have the new property value. EXPECT_TRUE(adapter->IsPowered()); } -TEST_F(BluetoothAdapterTest, DefaultAdapterPoweredPropertyResetOnRemove) { +TEST_F(BluetoothAdapterChromeOsTest, + DefaultAdapterPoweredPropertyResetOnRemove) { const dbus::ObjectPath adapter_path("/fake/hci0"); const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; @@ -870,7 +934,8 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterPoweredPropertyResetOnRemove) { EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) .WillOnce(SaveArg<0>(&adapter_callback)); - scoped_refptr<BluetoothAdapter> adapter = BluetoothAdapter::DefaultAdapter(); + scoped_refptr<BluetoothAdapter> adapter = + BluetoothAdapterFactory::DefaultAdapter(); // Call the adapter callback; // BluetoothAdapterClient::GetProperties will be called once to obtain @@ -894,14 +959,17 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterPoweredPropertyResetOnRemove) { EXPECT_CALL(adapter_observer, AdapterPoweredChanged(adapter.get(), false)) .Times(1); - static_cast<BluetoothManagerClient::Observer*>(adapter.get()) + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast<BluetoothAdapterChromeOs*>(adapter.get()); + + static_cast<BluetoothManagerClient::Observer*>(adapter_chromeos) ->AdapterRemoved(adapter_path); // Adapter should have the new property value. EXPECT_FALSE(adapter->IsPowered()); } -TEST_F(BluetoothAdapterTest, DefaultAdapterSetPowered) { +TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterSetPowered) { const dbus::ObjectPath adapter_path("/fake/hci0"); const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; @@ -912,7 +980,8 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterSetPowered) { EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) .WillOnce(SaveArg<0>(&adapter_callback)); - scoped_refptr<BluetoothAdapter> adapter = BluetoothAdapter::DefaultAdapter(); + scoped_refptr<BluetoothAdapter> adapter = + BluetoothAdapterFactory::DefaultAdapter(); // Call the adapter callback; // BluetoothAdapterClient::GetProperties will be called once to obtain @@ -932,9 +1001,9 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterSetPowered) { .WillOnce(SaveArg<1>(&set_callback)); adapter->SetPowered(true, - base::Bind(&BluetoothAdapterTest::SetCallback, + base::Bind(&BluetoothAdapterChromeOsTest::SetCallback, base::Unretained(this)), - base::Bind(&BluetoothAdapterTest::ErrorCallback, + base::Bind(&BluetoothAdapterChromeOsTest::ErrorCallback, base::Unretained(this))); // Reply to the callback to indicate success, the set callback we provided @@ -948,7 +1017,7 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterSetPowered) { EXPECT_FALSE(error_callback_called_); } -TEST_F(BluetoothAdapterTest, DefaultAdapterSetPoweredError) { +TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterSetPoweredError) { const dbus::ObjectPath adapter_path("/fake/hci0"); const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; @@ -959,7 +1028,8 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterSetPoweredError) { EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) .WillOnce(SaveArg<0>(&adapter_callback)); - scoped_refptr<BluetoothAdapter> adapter = BluetoothAdapter::DefaultAdapter(); + scoped_refptr<BluetoothAdapter> adapter = + BluetoothAdapterFactory::DefaultAdapter(); // Call the adapter callback; // BluetoothAdapterClient::GetProperties will be called once to obtain @@ -979,9 +1049,9 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterSetPoweredError) { .WillOnce(SaveArg<1>(&set_callback)); adapter->SetPowered(true, - base::Bind(&BluetoothAdapterTest::SetCallback, + base::Bind(&BluetoothAdapterChromeOsTest::SetCallback, base::Unretained(this)), - base::Bind(&BluetoothAdapterTest::ErrorCallback, + base::Bind(&BluetoothAdapterChromeOsTest::ErrorCallback, base::Unretained(this))); // Reply to the callback to indicate failure, the error callback we provided @@ -995,7 +1065,8 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterSetPoweredError) { EXPECT_TRUE(error_callback_called_); } -TEST_F(BluetoothAdapterTest, DefaultAdapterDiscoveringPropertyInitiallyFalse) { +TEST_F(BluetoothAdapterChromeOsTest, + DefaultAdapterDiscoveringPropertyInitiallyFalse) { const dbus::ObjectPath adapter_path("/fake/hci0"); const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; @@ -1006,7 +1077,8 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterDiscoveringPropertyInitiallyFalse) { EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) .WillOnce(SaveArg<0>(&adapter_callback)); - scoped_refptr<BluetoothAdapter> adapter = BluetoothAdapter::DefaultAdapter(); + scoped_refptr<BluetoothAdapter> adapter = + BluetoothAdapterFactory::DefaultAdapter(); // Call the adapter callback; // BluetoothAdapterClient::GetProperties will be called once to obtain @@ -1024,7 +1096,8 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterDiscoveringPropertyInitiallyFalse) { EXPECT_FALSE(adapter->IsDiscovering()); } -TEST_F(BluetoothAdapterTest, DefaultAdapterDiscoveringPropertyInitiallyTrue) { +TEST_F(BluetoothAdapterChromeOsTest, + DefaultAdapterDiscoveringPropertyInitiallyTrue) { const dbus::ObjectPath adapter_path("/fake/hci0"); const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; @@ -1035,7 +1108,8 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterDiscoveringPropertyInitiallyTrue) { EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) .WillOnce(SaveArg<0>(&adapter_callback)); - scoped_refptr<BluetoothAdapter> adapter = BluetoothAdapter::DefaultAdapter(); + scoped_refptr<BluetoothAdapter> adapter = + BluetoothAdapterFactory::DefaultAdapter(); // Call the adapter callback; // BluetoothAdapterClient::GetProperties will be called once to obtain @@ -1063,7 +1137,7 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterDiscoveringPropertyInitiallyTrue) { EXPECT_TRUE(adapter->IsDiscovering()); } -TEST_F(BluetoothAdapterTest, +TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterDiscoveringPropertyInitiallyTrueWithoutAddress) { const dbus::ObjectPath adapter_path("/fake/hci0"); const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; @@ -1075,7 +1149,8 @@ TEST_F(BluetoothAdapterTest, EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) .WillOnce(SaveArg<0>(&adapter_callback)); - scoped_refptr<BluetoothAdapter> adapter = BluetoothAdapter::DefaultAdapter(); + scoped_refptr<BluetoothAdapter> adapter = + BluetoothAdapterFactory::DefaultAdapter(); // Call the adapter callback; // BluetoothAdapterClient::GetProperties will be called once to obtain @@ -1109,7 +1184,10 @@ TEST_F(BluetoothAdapterTest, EXPECT_CALL(adapter_observer, AdapterDiscoveringChanged(adapter.get(), true)) .Times(1); - static_cast<BluetoothAdapterClient::Observer*>(adapter.get()) + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast<BluetoothAdapterChromeOs*>(adapter.get()); + + static_cast<BluetoothAdapterClient::Observer*>(adapter_chromeos) ->AdapterPropertyChanged(adapter_path, adapter_properties.address.name()); @@ -1117,7 +1195,7 @@ TEST_F(BluetoothAdapterTest, EXPECT_TRUE(adapter->IsDiscovering()); } -TEST_F(BluetoothAdapterTest, DefaultAdapterDiscoveringPropertyChanged) { +TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterDiscoveringPropertyChanged) { const dbus::ObjectPath adapter_path("/fake/hci0"); const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; @@ -1128,7 +1206,8 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterDiscoveringPropertyChanged) { EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) .WillOnce(SaveArg<0>(&adapter_callback)); - scoped_refptr<BluetoothAdapter> adapter = BluetoothAdapter::DefaultAdapter(); + scoped_refptr<BluetoothAdapter> adapter = + BluetoothAdapterFactory::DefaultAdapter(); // Call the adapter callback; // BluetoothAdapterClient::GetProperties will be called once to obtain @@ -1154,7 +1233,11 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterDiscoveringPropertyChanged) { .Times(1); adapter_properties.discovering.ReplaceValue(true); - static_cast<BluetoothAdapterClient::Observer*>(adapter.get()) + + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast<BluetoothAdapterChromeOs*>(adapter.get()); + + static_cast<BluetoothAdapterClient::Observer*>(adapter_chromeos) ->AdapterPropertyChanged(adapter_path, adapter_properties.discovering.name()); @@ -1162,7 +1245,8 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterDiscoveringPropertyChanged) { EXPECT_TRUE(adapter->IsDiscovering()); } -TEST_F(BluetoothAdapterTest, DefaultAdapterDiscoveringPropertyUnchanged) { +TEST_F(BluetoothAdapterChromeOsTest, + DefaultAdapterDiscoveringPropertyUnchanged) { const dbus::ObjectPath adapter_path("/fake/hci0"); const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; @@ -1173,7 +1257,8 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterDiscoveringPropertyUnchanged) { EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) .WillOnce(SaveArg<0>(&adapter_callback)); - scoped_refptr<BluetoothAdapter> adapter = BluetoothAdapter::DefaultAdapter(); + scoped_refptr<BluetoothAdapter> adapter = + BluetoothAdapterFactory::DefaultAdapter(); // Call the adapter callback; // BluetoothAdapterClient::GetProperties will be called once to obtain @@ -1199,7 +1284,10 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterDiscoveringPropertyUnchanged) { EXPECT_CALL(adapter_observer, AdapterDiscoveringChanged(adapter.get(), _)) .Times(0); - static_cast<BluetoothAdapterClient::Observer*>(adapter.get()) + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast<BluetoothAdapterChromeOs*>(adapter.get()); + + static_cast<BluetoothAdapterClient::Observer*>(adapter_chromeos) ->AdapterPropertyChanged(adapter_path, adapter_properties.discovering.name()); @@ -1207,7 +1295,7 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterDiscoveringPropertyUnchanged) { EXPECT_TRUE(adapter->IsDiscovering()); } -TEST_F(BluetoothAdapterTest, +TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterDiscoveringPropertyChangedWithoutAddress) { const dbus::ObjectPath adapter_path("/fake/hci0"); const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; @@ -1219,7 +1307,8 @@ TEST_F(BluetoothAdapterTest, EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) .WillOnce(SaveArg<0>(&adapter_callback)); - scoped_refptr<BluetoothAdapter> adapter = BluetoothAdapter::DefaultAdapter(); + scoped_refptr<BluetoothAdapter> adapter = + BluetoothAdapterFactory::DefaultAdapter(); // Call the adapter callback; // BluetoothAdapterClient::GetProperties will be called once to obtain @@ -1246,7 +1335,10 @@ TEST_F(BluetoothAdapterTest, EXPECT_CALL(adapter_observer, AdapterDiscoveringChanged(adapter.get(), _)) .Times(0); - static_cast<BluetoothAdapterClient::Observer*>(adapter.get()) + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast<BluetoothAdapterChromeOs*>(adapter.get()); + + static_cast<BluetoothAdapterClient::Observer*>(adapter_chromeos) ->AdapterPropertyChanged(adapter_path, adapter_properties.discovering.name()); @@ -1264,7 +1356,7 @@ TEST_F(BluetoothAdapterTest, EXPECT_CALL(adapter_observer, AdapterDiscoveringChanged(adapter.get(), true)) .Times(1); - static_cast<BluetoothAdapterClient::Observer*>(adapter.get()) + static_cast<BluetoothAdapterClient::Observer*>(adapter_chromeos) ->AdapterPropertyChanged(adapter_path, adapter_properties.address.name()); @@ -1272,7 +1364,8 @@ TEST_F(BluetoothAdapterTest, EXPECT_TRUE(adapter->IsDiscovering()); } -TEST_F(BluetoothAdapterTest, DefaultAdapterDiscoveringPropertyResetOnReplace) { +TEST_F(BluetoothAdapterChromeOsTest, + DefaultAdapterDiscoveringPropertyResetOnReplace) { const dbus::ObjectPath initial_adapter_path("/fake/hci0"); const dbus::ObjectPath new_adapter_path("/fake/hci1"); const std::string initial_adapter_address = "CA:FE:4A:C0:FE:FE"; @@ -1285,7 +1378,8 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterDiscoveringPropertyResetOnReplace) { EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) .WillOnce(SaveArg<0>(&adapter_callback)); - scoped_refptr<BluetoothAdapter> adapter = BluetoothAdapter::DefaultAdapter(); + scoped_refptr<BluetoothAdapter> adapter = + BluetoothAdapterFactory::DefaultAdapter(); // Call the adapter callback; // BluetoothAdapterClient::GetProperties will be called once to obtain @@ -1324,14 +1418,17 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterDiscoveringPropertyResetOnReplace) { EXPECT_CALL(adapter_observer, AdapterDiscoveringChanged(adapter.get(), false)) .Times(1); - static_cast<BluetoothManagerClient::Observer*>(adapter.get()) + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast<BluetoothAdapterChromeOs*>(adapter.get()); + + static_cast<BluetoothManagerClient::Observer*>(adapter_chromeos) ->DefaultAdapterChanged(new_adapter_path); // Adapter should have the new property value. EXPECT_FALSE(adapter->IsDiscovering()); } -TEST_F(BluetoothAdapterTest, +TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterDiscoveringPropertyResetOnReplaceWhenTrue) { const dbus::ObjectPath initial_adapter_path("/fake/hci0"); const dbus::ObjectPath new_adapter_path("/fake/hci1"); @@ -1345,7 +1442,8 @@ TEST_F(BluetoothAdapterTest, EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) .WillOnce(SaveArg<0>(&adapter_callback)); - scoped_refptr<BluetoothAdapter> adapter = BluetoothAdapter::DefaultAdapter(); + scoped_refptr<BluetoothAdapter> adapter = + BluetoothAdapterFactory::DefaultAdapter(); // Call the adapter callback; // BluetoothAdapterClient::GetProperties will be called once to obtain @@ -1395,14 +1493,18 @@ TEST_F(BluetoothAdapterTest, .Times(1); } - static_cast<BluetoothManagerClient::Observer*>(adapter.get()) + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast<BluetoothAdapterChromeOs*>(adapter.get()); + + static_cast<BluetoothManagerClient::Observer*>(adapter_chromeos) ->DefaultAdapterChanged(new_adapter_path); // Adapter should have the new property value. EXPECT_TRUE(adapter->IsDiscovering()); } -TEST_F(BluetoothAdapterTest, DefaultAdapterDiscoveringPropertyResetOnRemove) { +TEST_F(BluetoothAdapterChromeOsTest, + DefaultAdapterDiscoveringPropertyResetOnRemove) { const dbus::ObjectPath adapter_path("/fake/hci0"); const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; @@ -1413,7 +1515,8 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterDiscoveringPropertyResetOnRemove) { EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) .WillOnce(SaveArg<0>(&adapter_callback)); - scoped_refptr<BluetoothAdapter> adapter = BluetoothAdapter::DefaultAdapter(); + scoped_refptr<BluetoothAdapter> adapter = + BluetoothAdapterFactory::DefaultAdapter(); // Call the adapter callback; // BluetoothAdapterClient::GetProperties will be called once to obtain @@ -1437,7 +1540,10 @@ TEST_F(BluetoothAdapterTest, DefaultAdapterDiscoveringPropertyResetOnRemove) { EXPECT_CALL(adapter_observer, AdapterDiscoveringChanged(adapter.get(), false)) .Times(1); - static_cast<BluetoothManagerClient::Observer*>(adapter.get()) + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast<BluetoothAdapterChromeOs*>(adapter.get()); + + static_cast<BluetoothManagerClient::Observer*>(adapter_chromeos) ->AdapterRemoved(adapter_path); // Adapter should have the new property value. diff --git a/chrome/browser/chromeos/bluetooth/bluetooth_adapter_devices_unittest.cc b/chrome/browser/chromeos/bluetooth/bluetooth_adapter_devices_chromeos_unittest.cc index 19bcfb8..6455841 100644 --- a/chrome/browser/chromeos/bluetooth/bluetooth_adapter_devices_unittest.cc +++ b/chrome/browser/chromeos/bluetooth/bluetooth_adapter_devices_chromeos_unittest.cc @@ -3,6 +3,8 @@ // found in the LICENSE file. #include "chrome/browser/chromeos/bluetooth/bluetooth_adapter.h" +#include "chrome/browser/chromeos/bluetooth/bluetooth_adapter_chromeos.h" +#include "chrome/browser/chromeos/bluetooth/bluetooth_adapter_factory.h" #include "chrome/browser/chromeos/bluetooth/test/mock_bluetooth_adapter.h" #include "chromeos/dbus/mock_bluetooth_adapter_client.h" #include "chromeos/dbus/mock_bluetooth_device_client.h" @@ -18,7 +20,7 @@ using ::testing::SaveArg; namespace chromeos { -class BluetoothAdapterDevicesTest : public testing::Test { +class BluetoothAdapterDevicesChromeOsTest : public testing::Test { public: virtual void SetUp() { MockDBusThreadManager* mock_dbus_thread_manager = new MockDBusThreadManager; @@ -46,7 +48,7 @@ class BluetoothAdapterDevicesTest : public testing::Test { EXPECT_CALL(*mock_adapter_client_, AddObserver(_)) .Times(1); - adapter_ = BluetoothAdapter::DefaultAdapter(); + adapter_ = BluetoothAdapterFactory::DefaultAdapter(); // Call the adapter callback; // BluetoothAdapterClient::GetProperties will be called once to obtain @@ -76,11 +78,13 @@ class BluetoothAdapterDevicesTest : public testing::Test { } virtual void TearDown() { - EXPECT_CALL(*mock_device_client_, RemoveObserver(adapter_.get())) + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast<BluetoothAdapterChromeOs*>(adapter_.get()); + EXPECT_CALL(*mock_device_client_, RemoveObserver(adapter_chromeos)) .Times(1); - EXPECT_CALL(*mock_adapter_client_, RemoveObserver(adapter_.get())) + EXPECT_CALL(*mock_adapter_client_, RemoveObserver(adapter_chromeos)) .Times(1); - EXPECT_CALL(*mock_manager_client_, RemoveObserver(adapter_.get())) + EXPECT_CALL(*mock_manager_client_, RemoveObserver(adapter_chromeos)) .Times(1); adapter_ = NULL; @@ -99,12 +103,12 @@ class BluetoothAdapterDevicesTest : public testing::Test { MockBluetoothAdapter::Observer adapter_observer_; }; -const dbus::ObjectPath BluetoothAdapterDevicesTest::adapter_path_( +const dbus::ObjectPath BluetoothAdapterDevicesChromeOsTest::adapter_path_( "/fake/hci0"); -const std::string BluetoothAdapterDevicesTest::adapter_address_ = +const std::string BluetoothAdapterDevicesChromeOsTest::adapter_address_ = "CA:FE:4A:C0:FE:FE"; -TEST_F(BluetoothAdapterDevicesTest, DeviceRemovedAfterFound) { +TEST_F(BluetoothAdapterDevicesChromeOsTest, DeviceRemovedAfterFound) { const dbus::ObjectPath device_path("/fake/hci0/dev_ba_c0_11_00_00_01"); const std::string device_address = "BA:C0:11:00:00:01"; @@ -128,7 +132,9 @@ TEST_F(BluetoothAdapterDevicesTest, DeviceRemovedAfterFound) { .Times(1) .WillOnce(SaveArg<1>(&device)); - static_cast<BluetoothAdapterClient::Observer*>(adapter_.get()) + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast<BluetoothAdapterChromeOs*>(adapter_.get()); + static_cast<BluetoothAdapterClient::Observer*>(adapter_chromeos) ->DeviceFound(adapter_path_, device_address, device_properties); // Now inform the adapter that the device has been added and assigned an @@ -139,10 +145,10 @@ TEST_F(BluetoothAdapterDevicesTest, DeviceRemovedAfterFound) { EXPECT_CALL(*mock_device_client_, GetProperties(device_path)) .WillRepeatedly(Return(&device_properties)); - EXPECT_CALL(adapter_observer_, DeviceChanged(adapter_.get(), device)) + EXPECT_CALL(adapter_observer_, DeviceChanged(adapter_chromeos, device)) .Times(1); - static_cast<BluetoothAdapterClient::Observer*>(adapter_.get()) + static_cast<BluetoothAdapterClient::Observer*>(adapter_chromeos) ->DeviceCreated(adapter_path_, device_path); // Finally remove the adapter again; since this is a supported device @@ -153,7 +159,7 @@ TEST_F(BluetoothAdapterDevicesTest, DeviceRemovedAfterFound) { EXPECT_CALL(adapter_observer_, DeviceChanged(adapter_.get(), device)) .Times(1); - static_cast<BluetoothAdapterClient::Observer*>(adapter_.get()) + static_cast<BluetoothAdapterClient::Observer*>(adapter_chromeos) ->DeviceRemoved(adapter_path_, device_path); // Verify that the device is still visible, just no longer paired. @@ -161,7 +167,8 @@ TEST_F(BluetoothAdapterDevicesTest, DeviceRemovedAfterFound) { EXPECT_FALSE(device->IsPaired()); } -TEST_F(BluetoothAdapterDevicesTest, UnsupportedDeviceRemovedAfterFound) { +TEST_F(BluetoothAdapterDevicesChromeOsTest, + UnsupportedDeviceRemovedAfterFound) { const dbus::ObjectPath device_path("/fake/hci0/dev_ba_c0_11_00_00_02"); const std::string device_address = "BA:C0:11:00:00:02"; @@ -176,7 +183,9 @@ TEST_F(BluetoothAdapterDevicesTest, UnsupportedDeviceRemovedAfterFound) { EXPECT_CALL(adapter_observer_, DeviceAdded(adapter_.get(), _)) .Times(0); - static_cast<BluetoothAdapterClient::Observer*>(adapter_.get()) + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast<BluetoothAdapterChromeOs*>(adapter_.get()); + static_cast<BluetoothAdapterClient::Observer*>(adapter_chromeos) ->DeviceFound(adapter_path_, device_address, device_properties); // Now inform the adapter the device has been added and assigned an @@ -192,7 +201,7 @@ TEST_F(BluetoothAdapterDevicesTest, UnsupportedDeviceRemovedAfterFound) { .Times(1) .WillOnce(SaveArg<1>(&device)); - static_cast<BluetoothAdapterClient::Observer*>(adapter_.get()) + static_cast<BluetoothAdapterClient::Observer*>(adapter_chromeos) ->DeviceCreated(adapter_path_, device_path); // Finally remove the device again; @@ -201,7 +210,7 @@ TEST_F(BluetoothAdapterDevicesTest, UnsupportedDeviceRemovedAfterFound) { EXPECT_CALL(adapter_observer_, DeviceRemoved(adapter_.get(), device)) .Times(1); - static_cast<BluetoothAdapterClient::Observer*>(adapter_.get()) + static_cast<BluetoothAdapterClient::Observer*>(adapter_chromeos) ->DeviceRemoved(adapter_path_, device_path); } diff --git a/chrome/browser/chromeos/bluetooth/bluetooth_adapter_factory.cc b/chrome/browser/chromeos/bluetooth/bluetooth_adapter_factory.cc new file mode 100644 index 0000000..eb62622 --- /dev/null +++ b/chrome/browser/chromeos/bluetooth/bluetooth_adapter_factory.cc @@ -0,0 +1,44 @@ +// 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. +// +// TODO(youngki): Guard the ChromeOS specific part with "#ifdef CHROME_OS" block +// once we move this code into common directory. + +#include "base/lazy_instance.h" +#include "base/memory/ref_counted.h" +#include "chrome/browser/chromeos/bluetooth/bluetooth_adapter_chromeos.h" +#include "chrome/browser/chromeos/bluetooth/bluetooth_adapter_factory.h" + +namespace { + +// Shared default adapter instance, we don't want to keep this class around +// if nobody is using it so use a WeakPtr and create the object when needed; +// since Google C++ Style (and clang's static analyzer) forbids us having +// exit-time destructors we use a leaky lazy instance for it. +base::LazyInstance<base::WeakPtr<chromeos::BluetoothAdapter> >::Leaky + default_adapter = LAZY_INSTANCE_INITIALIZER; + +} // namespace + +namespace chromeos { + +// static +scoped_refptr<BluetoothAdapter> BluetoothAdapterFactory::DefaultAdapter() { + if (!default_adapter.Get().get()) { + BluetoothAdapterChromeOs* new_adapter = new BluetoothAdapterChromeOs; + new_adapter->TrackDefaultAdapter(); + default_adapter.Get() = new_adapter->weak_ptr_factory_.GetWeakPtr(); + } + + return scoped_refptr<BluetoothAdapter>(default_adapter.Get()); +} + +// static +BluetoothAdapter* BluetoothAdapterFactory::Create(const std::string& address) { + BluetoothAdapterChromeOs* adapter = new BluetoothAdapterChromeOs; + adapter->FindAdapter(address); + return adapter; +} + +} // namespace chromeos diff --git a/chrome/browser/chromeos/bluetooth/bluetooth_adapter_factory.h b/chrome/browser/chromeos/bluetooth/bluetooth_adapter_factory.h new file mode 100644 index 0000000..0cd4b24 --- /dev/null +++ b/chrome/browser/chromeos/bluetooth/bluetooth_adapter_factory.h @@ -0,0 +1,32 @@ +// 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. + +#ifndef CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_ADAPTER_FACTORY_H_ +#define CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_ADAPTER_FACTORY_H_ + +#include <string> + +#include "base/memory/ref_counted.h" + +namespace chromeos { + +class BluetoothAdapter; + +// BluetoothAdapterFactory is a class that contains static methods, which +// instantiate either a specific bluetooth adapter, or the generic "default +// adapter" which may change depending on availability. +class BluetoothAdapterFactory { + public: + // Returns the shared instance for the default adapter, whichever that may + // be at the time. Use IsPresent() and the AdapterPresentChanged() observer + // method to determine whether an adapter is actually available or not. + static scoped_refptr<BluetoothAdapter> DefaultAdapter(); + + // Creates an instance for a specific adapter at address |address|. + static BluetoothAdapter* Create(const std::string& address); +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_ADAPTER_FACTORY_H_ diff --git a/chrome/browser/chromeos/bluetooth/bluetooth_device.cc b/chrome/browser/chromeos/bluetooth/bluetooth_device.cc index ba19dc5..657f1f4 100644 --- a/chrome/browser/chromeos/bluetooth/bluetooth_device.cc +++ b/chrome/browser/chromeos/bluetooth/bluetooth_device.cc @@ -4,54 +4,25 @@ #include "chrome/browser/chromeos/bluetooth/bluetooth_device.h" -#include <map> -#include <string> -#include <vector> - -#include "base/bind.h" -#include "base/command_line.h" -#include "base/logging.h" -#include "base/memory/scoped_vector.h" -#include "base/memory/weak_ptr.h" -#include "base/string16.h" -#include "base/string_util.h" #include "base/utf_string_conversions.h" -#include "base/values.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_adapter.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_service_record.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_socket.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_utils.h" -#include "chrome/common/chrome_switches.h" -#include "chromeos/dbus/bluetooth_adapter_client.h" -#include "chromeos/dbus/bluetooth_agent_service_provider.h" -#include "chromeos/dbus/bluetooth_device_client.h" -#include "chromeos/dbus/bluetooth_input_client.h" -#include "chromeos/dbus/bluetooth_out_of_band_client.h" -#include "chromeos/dbus/dbus_thread_manager.h" -#include "chromeos/dbus/introspectable_client.h" -#include "dbus/bus.h" -#include "dbus/object_path.h" #include "grit/generated_resources.h" -#include "third_party/cros_system_api/dbus/service_constants.h" #include "ui/base/l10n/l10n_util.h" namespace chromeos { -BluetoothDevice::BluetoothDevice(BluetoothAdapter* adapter) - : adapter_(adapter), - bluetooth_class_(0), - visible_(false), - bonded_(false), - connected_(false), - pairing_delegate_(NULL), - connecting_applications_counter_(0), - weak_ptr_factory_(this) { +BluetoothDevice::BluetoothDevice() + : bluetooth_class_(0), + visible_(false), + bonded_(false), + connected_(false) { } BluetoothDevice::~BluetoothDevice() { } -const std::string& BluetoothDevice::address() const { return address_; } +const std::string& BluetoothDevice::address() const { + return address_; +} string16 BluetoothDevice::GetName() const { if (!name_.empty()) { @@ -61,6 +32,42 @@ string16 BluetoothDevice::GetName() const { } } +string16 BluetoothDevice::GetAddressWithLocalizedDeviceTypeName() const { + string16 address = UTF8ToUTF16(address_); + BluetoothDevice::DeviceType device_type = GetDeviceType(); + switch (device_type) { + case DEVICE_COMPUTER: + return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_COMPUTER, + address); + case DEVICE_PHONE: + return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_PHONE, + address); + case DEVICE_MODEM: + return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_MODEM, + address); + case DEVICE_JOYSTICK: + return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_JOYSTICK, + address); + case DEVICE_GAMEPAD: + return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_GAMEPAD, + address); + case DEVICE_KEYBOARD: + return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_KEYBOARD, + address); + case DEVICE_MOUSE: + return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_MOUSE, + address); + case DEVICE_TABLET: + return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_TABLET, + address); + case DEVICE_KEYBOARD_MOUSE_COMBO: + return l10n_util::GetStringFUTF16( + IDS_BLUETOOTH_DEVICE_KEYBOARD_MOUSE_COMBO, address); + default: + return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_UNKNOWN, address); + } +} + BluetoothDevice::DeviceType BluetoothDevice::GetDeviceType() const { // https://www.bluetooth.org/Technical/AssignedNumbers/baseband.htm switch ((bluetooth_class_ & 0x1f00) >> 8) { @@ -121,657 +128,16 @@ BluetoothDevice::DeviceType BluetoothDevice::GetDeviceType() const { return DEVICE_UNKNOWN; } -string16 BluetoothDevice::GetAddressWithLocalizedDeviceTypeName() const { - string16 address = UTF8ToUTF16(address_); - DeviceType device_type = GetDeviceType(); - switch (device_type) { - case DEVICE_COMPUTER: - return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_COMPUTER, - address); - case DEVICE_PHONE: - return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_PHONE, - address); - case DEVICE_MODEM: - return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_MODEM, - address); - case DEVICE_JOYSTICK: - return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_JOYSTICK, - address); - case DEVICE_GAMEPAD: - return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_GAMEPAD, - address); - case DEVICE_KEYBOARD: - return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_KEYBOARD, - address); - case DEVICE_MOUSE: - return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_MOUSE, - address); - case DEVICE_TABLET: - return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_TABLET, - address); - case DEVICE_KEYBOARD_MOUSE_COMBO: - return l10n_util::GetStringFUTF16( - IDS_BLUETOOTH_DEVICE_KEYBOARD_MOUSE_COMBO, address); - default: - return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_UNKNOWN, address); - } +bool BluetoothDevice::IsVisible() const { + return visible_; } -bool BluetoothDevice::IsSupported() const { - if (CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableUnsupportedBluetoothDevices)) - return true; - - DeviceType device_type = GetDeviceType(); - return (device_type == DEVICE_JOYSTICK || - device_type == DEVICE_GAMEPAD || - device_type == DEVICE_KEYBOARD || - device_type == DEVICE_MOUSE || - device_type == DEVICE_TABLET || - device_type == DEVICE_KEYBOARD_MOUSE_COMBO); +bool BluetoothDevice::IsBonded() const { + return bonded_; } -bool BluetoothDevice::IsPaired() const { return !object_path_.value().empty(); } - -bool BluetoothDevice::IsBonded() const { return bonded_; } - bool BluetoothDevice::IsConnected() const { - // TODO(keybuk): examine protocol-specific connected state, such as Input return connected_; } -void BluetoothDevice::GetServiceRecords(const ServiceRecordsCallback& callback, - const ErrorCallback& error_callback) { - DBusThreadManager::Get()->GetBluetoothDeviceClient()-> - DiscoverServices( - object_path_, - "", // empty pattern to browse all services - base::Bind(&BluetoothDevice::CollectServiceRecordsCallback, - weak_ptr_factory_.GetWeakPtr(), - callback, - error_callback)); -} - -bool BluetoothDevice::ProvidesServiceWithUUID(const std::string& uuid) const { - const BluetoothDevice::ServiceList& services = GetServices(); - for (BluetoothDevice::ServiceList::const_iterator iter = services.begin(); - iter != services.end(); ++iter) { - if (bluetooth_utils::CanonicalUuid(*iter) == uuid) - return true; - } - return false; -} - -void BluetoothDevice::ProvidesServiceWithName(const std::string& name, - const ProvidesServiceCallback& callback) { - GetServiceRecords( - base::Bind(&BluetoothDevice::SearchServicesForNameCallback, - weak_ptr_factory_.GetWeakPtr(), - name, - callback), - base::Bind(&BluetoothDevice::SearchServicesForNameErrorCallback, - weak_ptr_factory_.GetWeakPtr(), - callback)); -} - -void BluetoothDevice::Connect(PairingDelegate* pairing_delegate, - const base::Closure& callback, - const ErrorCallback& error_callback) { - if (IsPaired() || IsBonded() || IsConnected()) { - // Connection to already paired or connected device. - ConnectApplications(callback, error_callback); - - } else if (!pairing_delegate) { - // No pairing delegate supplied, initiate low-security connection only. - DBusThreadManager::Get()->GetBluetoothAdapterClient()-> - CreateDevice(adapter_->object_path_, - address_, - base::Bind(&BluetoothDevice::ConnectCallback, - weak_ptr_factory_.GetWeakPtr(), - callback, - error_callback), - base::Bind(&BluetoothDevice::ConnectErrorCallback, - weak_ptr_factory_.GetWeakPtr(), - error_callback)); - } else { - // Initiate high-security connection with pairing. - DCHECK(!pairing_delegate_); - pairing_delegate_ = pairing_delegate; - - // The agent path is relatively meaningless, we use the device address - // to generate it as we only support one pairing attempt at a time for - // a given bluetooth device. - DCHECK(agent_.get() == NULL); - - std::string agent_path_basename; - ReplaceChars(address_, ":", "_", &agent_path_basename); - dbus::ObjectPath agent_path("/org/chromium/bluetooth_agent/" + - agent_path_basename); - - dbus::Bus* system_bus = DBusThreadManager::Get()->GetSystemBus(); - if (system_bus) { - agent_.reset(BluetoothAgentServiceProvider::Create(system_bus, - agent_path, - this)); - } else { - agent_.reset(NULL); - } - - DVLOG(1) << "Pairing: " << address_; - DBusThreadManager::Get()->GetBluetoothAdapterClient()-> - CreatePairedDevice(adapter_->object_path_, - address_, - agent_path, - bluetooth_agent::kDisplayYesNoCapability, - base::Bind(&BluetoothDevice::ConnectCallback, - weak_ptr_factory_.GetWeakPtr(), - callback, - error_callback), - base::Bind(&BluetoothDevice::ConnectErrorCallback, - weak_ptr_factory_.GetWeakPtr(), - error_callback)); - } -} - -void BluetoothDevice::SetPinCode(const std::string& pincode) { - if (!agent_.get() || pincode_callback_.is_null()) - return; - - pincode_callback_.Run(SUCCESS, pincode); - pincode_callback_.Reset(); -} - -void BluetoothDevice::SetPasskey(uint32 passkey) { - if (!agent_.get() || passkey_callback_.is_null()) - return; - - passkey_callback_.Run(SUCCESS, passkey); - passkey_callback_.Reset(); -} - -void BluetoothDevice::ConfirmPairing() { - if (!agent_.get() || confirmation_callback_.is_null()) - return; - - confirmation_callback_.Run(SUCCESS); - confirmation_callback_.Reset(); -} - -void BluetoothDevice::RejectPairing() { - if (!agent_.get()) - return; - - if (!pincode_callback_.is_null()) { - pincode_callback_.Run(REJECTED, ""); - pincode_callback_.Reset(); - } - if (!passkey_callback_.is_null()) { - passkey_callback_.Run(REJECTED, 0); - passkey_callback_.Reset(); - } - if (!confirmation_callback_.is_null()) { - confirmation_callback_.Run(REJECTED); - confirmation_callback_.Reset(); - } -} - -void BluetoothDevice::CancelPairing() { - if (!agent_.get()) - return; - - if (!pincode_callback_.is_null()) { - pincode_callback_.Run(CANCELLED, ""); - pincode_callback_.Reset(); - } - if (!passkey_callback_.is_null()) { - passkey_callback_.Run(CANCELLED, 0); - passkey_callback_.Reset(); - } - if (!confirmation_callback_.is_null()) { - confirmation_callback_.Run(CANCELLED); - confirmation_callback_.Reset(); - } -} - -void BluetoothDevice::Disconnect(const base::Closure& callback, - const ErrorCallback& error_callback) { - DBusThreadManager::Get()->GetBluetoothDeviceClient()-> - Disconnect(object_path_, - base::Bind(&BluetoothDevice::DisconnectCallback, - weak_ptr_factory_.GetWeakPtr(), - callback, - error_callback)); - -} - -void BluetoothDevice::Forget(const ErrorCallback& error_callback) { - DBusThreadManager::Get()->GetBluetoothAdapterClient()-> - RemoveDevice(adapter_->object_path_, - object_path_, - base::Bind(&BluetoothDevice::ForgetCallback, - weak_ptr_factory_.GetWeakPtr(), - error_callback)); -} - -void BluetoothDevice::ConnectToService(const std::string& service_uuid, - const SocketCallback& callback) { - GetServiceRecords( - base::Bind(&BluetoothDevice::GetServiceRecordsForConnectCallback, - weak_ptr_factory_.GetWeakPtr(), - service_uuid, - callback), - base::Bind(&BluetoothDevice::GetServiceRecordsForConnectErrorCallback, - weak_ptr_factory_.GetWeakPtr(), - callback)); -} - -void BluetoothDevice::SetOutOfBandPairingData( - const chromeos::BluetoothOutOfBandPairingData& data, - const base::Closure& callback, - const ErrorCallback& error_callback) { - DBusThreadManager::Get()->GetBluetoothOutOfBandClient()-> - AddRemoteData( - object_path_, - address(), - data, - base::Bind(&BluetoothDevice::OnRemoteDataCallback, - weak_ptr_factory_.GetWeakPtr(), - callback, - error_callback)); -} - -void BluetoothDevice::ClearOutOfBandPairingData( - const base::Closure& callback, - const ErrorCallback& error_callback) { - DBusThreadManager::Get()->GetBluetoothOutOfBandClient()-> - RemoveRemoteData( - object_path_, - address(), - base::Bind(&BluetoothDevice::OnRemoteDataCallback, - weak_ptr_factory_.GetWeakPtr(), - callback, - error_callback)); -} - -void BluetoothDevice::SetObjectPath(const dbus::ObjectPath& object_path) { - DCHECK(object_path_ == dbus::ObjectPath("")); - object_path_ = object_path; -} - -void BluetoothDevice::RemoveObjectPath() { - DCHECK(object_path_ != dbus::ObjectPath("")); - object_path_ = dbus::ObjectPath(""); -} - -void BluetoothDevice::Update( - const BluetoothDeviceClient::Properties* properties, - bool update_state) { - std::string address = properties->address.value(); - std::string name = properties->name.value(); - uint32 bluetooth_class = properties->bluetooth_class.value(); - const std::vector<std::string>& uuids = properties->uuids.value(); - - if (!address.empty()) - address_ = address; - if (!name.empty()) - name_ = name; - if (bluetooth_class) - bluetooth_class_ = bluetooth_class; - if (!uuids.empty()) { - service_uuids_.clear(); - service_uuids_.assign(uuids.begin(), uuids.end()); - } - - if (update_state) { - // BlueZ uses paired to mean link keys exchanged, whereas the Bluetooth - // spec refers to this as bonded. Use the spec name for our interface. - bonded_ = properties->paired.value(); - connected_ = properties->connected.value(); - } -} - -void BluetoothDevice::ConnectCallback(const base::Closure& callback, - const ErrorCallback& error_callback, - const dbus::ObjectPath& device_path) { - DVLOG(1) << "Connection successful: " << device_path.value(); - if (object_path_.value().empty()) { - object_path_ = device_path; - } else { - LOG_IF(WARNING, object_path_ != device_path) - << "Conflicting device paths for objects, result gave: " - << device_path.value() << " but signal gave: " - << object_path_.value(); - } - - // Mark the device trusted so it can connect to us automatically, and - // we can connect after rebooting. This information is part of the - // pairing information of the device, and is unique to the combination - // of our bluetooth address and the device's bluetooth address. A - // different host needs a new pairing, so it's not useful to sync. - DBusThreadManager::Get()->GetBluetoothDeviceClient()-> - GetProperties(object_path_)->trusted.Set( - true, - base::Bind(&BluetoothDevice::OnSetTrusted, - weak_ptr_factory_.GetWeakPtr(), - callback, - error_callback)); - - // Connect application-layer protocols. - ConnectApplications(callback, error_callback); -} - -void BluetoothDevice::ConnectErrorCallback(const ErrorCallback& error_callback, - const std::string& error_name, - const std::string& error_message) { - LOG(WARNING) << "Connection failed: " << address_ - << ": " << error_name << ": " << error_message; - error_callback.Run(); -} - -void BluetoothDevice::CollectServiceRecordsCallback( - const ServiceRecordsCallback& callback, - const ErrorCallback& error_callback, - const dbus::ObjectPath& device_path, - const BluetoothDeviceClient::ServiceMap& service_map, - bool success) { - if (!success) { - error_callback.Run(); - return; - } - - ScopedVector<BluetoothServiceRecord> records; - for (BluetoothDeviceClient::ServiceMap::const_iterator i = - service_map.begin(); i != service_map.end(); ++i) { - records.push_back( - new BluetoothServiceRecord(address(), i->second)); - } - callback.Run(records); -} - -void BluetoothDevice::OnSetTrusted(const base::Closure& callback, - const ErrorCallback& error_callback, - bool success) { - if (success) { - callback.Run(); - } else { - LOG(WARNING) << "Failed to set device as trusted: " << address_; - error_callback.Run(); - } -} - -void BluetoothDevice::ConnectApplications(const base::Closure& callback, - const ErrorCallback& error_callback) { - // Introspect the device object to determine supported applications. - DBusThreadManager::Get()->GetIntrospectableClient()-> - Introspect(bluetooth_device::kBluetoothDeviceServiceName, - object_path_, - base::Bind(&BluetoothDevice::OnIntrospect, - weak_ptr_factory_.GetWeakPtr(), - callback, - error_callback)); -} - -void BluetoothDevice::OnIntrospect(const base::Closure& callback, - const ErrorCallback& error_callback, - const std::string& service_name, - const dbus::ObjectPath& device_path, - const std::string& xml_data, - bool success) { - if (!success) { - LOG(WARNING) << "Failed to determine supported applications: " << address_; - error_callback.Run(); - return; - } - - // The introspection data for the device object may list one or more - // additional D-Bus interfaces that BlueZ supports for this particular - // device. Send appropraite Connect calls for each of those interfaces - // to connect all of the application protocols for this device. - std::vector<std::string> interfaces = - IntrospectableClient::GetInterfacesFromIntrospectResult(xml_data); - - DCHECK_EQ(0, connecting_applications_counter_); - connecting_applications_counter_ = 0; - for (std::vector<std::string>::iterator iter = interfaces.begin(); - iter != interfaces.end(); ++iter) { - if (*iter == bluetooth_input::kBluetoothInputInterface) { - connecting_applications_counter_++; - // Supports Input interface. - DBusThreadManager::Get()->GetBluetoothInputClient()-> - Connect(object_path_, - base::Bind(&BluetoothDevice::OnConnect, - weak_ptr_factory_.GetWeakPtr(), - callback, - *iter), - base::Bind(&BluetoothDevice::OnConnectError, - weak_ptr_factory_.GetWeakPtr(), - error_callback, *iter)); - } - } - - // If OnConnect has been called for every call to Connect above, then this - // will decrement the counter to -1. In that case, call the callback - // directly as it has not been called by any of the OnConnect callbacks. - // This is safe because OnIntrospect and OnConnect run on the same thread. - connecting_applications_counter_--; - if (connecting_applications_counter_ == -1) - callback.Run(); -} - -void BluetoothDevice::OnConnect(const base::Closure& callback, - const std::string& interface_name, - const dbus::ObjectPath& device_path) { - DVLOG(1) << "Application connection successful: " << device_path.value() - << ": " << interface_name; - - connecting_applications_counter_--; - // |callback| should only be called once, meaning it cannot be called before - // all requests have been started. The extra decrement after all requests - // have been started, and the check for -1 instead of 0 below, insure only a - // single call to |callback| will occur (provided OnConnect and OnIntrospect - // run on the same thread, which is true). - if (connecting_applications_counter_ == -1) { - connecting_applications_counter_ = 0; - callback.Run(); - } -} - -void BluetoothDevice::OnConnectError(const ErrorCallback& error_callback, - const std::string& interface_name, - const dbus::ObjectPath& device_path, - const std::string& error_name, - const std::string& error_message) { - LOG(WARNING) << "Connection failed: " << address_ << ": " << interface_name - << ": " << error_name << ": " << error_message; - error_callback.Run(); -} - -void BluetoothDevice::DisconnectCallback(const base::Closure& callback, - const ErrorCallback& error_callback, - const dbus::ObjectPath& device_path, - bool success) { - DCHECK(device_path == object_path_); - if (success) { - DVLOG(1) << "Disconnection successful: " << address_; - callback.Run(); - } else { - LOG(WARNING) << "Disconnection failed: " << address_; - error_callback.Run(); - } -} - -void BluetoothDevice::ForgetCallback(const ErrorCallback& error_callback, - const dbus::ObjectPath& adapter_path, - bool success) { - // It's quite normal that this path never gets called on success; we use a - // weak pointer, and bluetoothd might send the DeviceRemoved signal before - // the method reply, in which case this object is deleted and the - // callback never takes place. Therefore don't do anything here for the - // success case. - if (!success) { - LOG(WARNING) << "Forget failed: " << address_; - error_callback.Run(); - } -} - -void BluetoothDevice::SearchServicesForNameErrorCallback( - const ProvidesServiceCallback& callback) { - callback.Run(false); -} - -void BluetoothDevice::SearchServicesForNameCallback( - const std::string& name, - const ProvidesServiceCallback& callback, - const ServiceRecordList& list) { - for (ServiceRecordList::const_iterator i = list.begin(); - i != list.end(); ++i) { - if ((*i)->name() == name) { - callback.Run(true); - return; - } - } - callback.Run(false); -} - -void BluetoothDevice::GetServiceRecordsForConnectErrorCallback( - const SocketCallback& callback) { - callback.Run(NULL); -} - -void BluetoothDevice::GetServiceRecordsForConnectCallback( - const std::string& service_uuid, - const SocketCallback& callback, - const ServiceRecordList& list) { - for (ServiceRecordList::const_iterator i = list.begin(); - i != list.end(); ++i) { - if ((*i)->uuid() == service_uuid) { - // If multiple service records are found, use the first one that works. - scoped_refptr<BluetoothSocket> socket( - BluetoothSocket::CreateBluetoothSocket(**i)); - if (socket.get() != NULL) { - callback.Run(socket); - return; - } - } - } - callback.Run(NULL); -} - -void BluetoothDevice::OnRemoteDataCallback(const base::Closure& callback, - const ErrorCallback& error_callback, - bool success) { - if (success) - callback.Run(); - else - error_callback.Run(); -} - -void BluetoothDevice::DisconnectRequested(const dbus::ObjectPath& object_path) { - DCHECK(object_path == object_path_); -} - -void BluetoothDevice::Release() { - DCHECK(agent_.get()); - DVLOG(1) << "Release: " << address_; - - DCHECK(pairing_delegate_); - pairing_delegate_->DismissDisplayOrConfirm(); - pairing_delegate_ = NULL; - - pincode_callback_.Reset(); - passkey_callback_.Reset(); - confirmation_callback_.Reset(); - - agent_.reset(); -} - -void BluetoothDevice::RequestPinCode(const dbus::ObjectPath& device_path, - const PinCodeCallback& callback) { - DCHECK(agent_.get()); - DVLOG(1) << "RequestPinCode: " << device_path.value(); - - DCHECK(pairing_delegate_); - DCHECK(pincode_callback_.is_null()); - pincode_callback_ = callback; - pairing_delegate_->RequestPinCode(this); -} - -void BluetoothDevice::RequestPasskey(const dbus::ObjectPath& device_path, - const PasskeyCallback& callback) { - DCHECK(agent_.get()); - DCHECK(device_path == object_path_); - DVLOG(1) << "RequestPasskey: " << device_path.value(); - - DCHECK(pairing_delegate_); - DCHECK(passkey_callback_.is_null()); - passkey_callback_ = callback; - pairing_delegate_->RequestPasskey(this); -} - -void BluetoothDevice::DisplayPinCode(const dbus::ObjectPath& device_path, - const std::string& pincode) { - DCHECK(agent_.get()); - DCHECK(device_path == object_path_); - DVLOG(1) << "DisplayPinCode: " << device_path.value() << " " << pincode; - - DCHECK(pairing_delegate_); - pairing_delegate_->DisplayPinCode(this, pincode); -} - -void BluetoothDevice::DisplayPasskey(const dbus::ObjectPath& device_path, - uint32 passkey) { - DCHECK(agent_.get()); - DCHECK(device_path == object_path_); - DVLOG(1) << "DisplayPasskey: " << device_path.value() << " " << passkey; - - DCHECK(pairing_delegate_); - pairing_delegate_->DisplayPasskey(this, passkey); -} - -void BluetoothDevice::RequestConfirmation( - const dbus::ObjectPath& device_path, - uint32 passkey, - const ConfirmationCallback& callback) { - DCHECK(agent_.get()); - DCHECK(device_path == object_path_); - DVLOG(1) << "RequestConfirmation: " << device_path.value() << " " << passkey; - - DCHECK(pairing_delegate_); - DCHECK(confirmation_callback_.is_null()); - confirmation_callback_ = callback; - pairing_delegate_->ConfirmPasskey(this, passkey); -} - -void BluetoothDevice::Authorize(const dbus::ObjectPath& device_path, - const std::string& uuid, - const ConfirmationCallback& callback) { - DCHECK(agent_.get()); - DCHECK(device_path == object_path_); - LOG(WARNING) << "Rejected authorization for service: " << uuid - << " requested from device: " << device_path.value(); - callback.Run(REJECTED); -} - -void BluetoothDevice::ConfirmModeChange(Mode mode, - const ConfirmationCallback& callback) { - DCHECK(agent_.get()); - LOG(WARNING) << "Rejected adapter-level mode change: " << mode - << " made on agent for device: " << address_; - callback.Run(REJECTED); -} - -void BluetoothDevice::Cancel() { - DCHECK(agent_.get()); - DVLOG(1) << "Cancel: " << address_; - - DCHECK(pairing_delegate_); - pairing_delegate_->DismissDisplayOrConfirm(); -} - - -// static -BluetoothDevice* BluetoothDevice::Create(BluetoothAdapter* adapter) { - return new BluetoothDevice(adapter); -} - } // namespace chromeos diff --git a/chrome/browser/chromeos/bluetooth/bluetooth_device.h b/chrome/browser/chromeos/bluetooth/bluetooth_device.h index 031dfd8..fe55ab4 100644 --- a/chrome/browser/chromeos/bluetooth/bluetooth_device.h +++ b/chrome/browser/chromeos/bluetooth/bluetooth_device.h @@ -8,27 +8,20 @@ #include <string> #include <vector> -#include "base/basictypes.h" #include "base/callback.h" -#include "base/memory/scoped_ptr.h" -#include "base/memory/scoped_vector.h" -#include "base/memory/weak_ptr.h" #include "base/string16.h" -#include "chromeos/dbus/bluetooth_agent_service_provider.h" -#include "chromeos/dbus/bluetooth_device_client.h" -#include "chromeos/dbus/bluetooth_out_of_band_client.h" -#include "dbus/object_path.h" +#include "base/memory/ref_counted.h" namespace chromeos { -class BluetoothAdapter; class BluetoothServiceRecord; class BluetoothSocket; -// The BluetoothDevice class represents a remote Bluetooth device, both -// its properties and capabilities as discovered by a local adapter and -// actions that may be performed on the remove device such as pairing, -// connection and disconnection. +struct BluetoothOutOfBandPairingData; + +// BluetoothDevice represents a remote Bluetooth device, both its properties and +// capabilities as discovered by a local adapter and actions that may be +// performed on the remove device such as pairing, connection and disconnection. // // The class is instantiated and managed by the BluetoothAdapter class // and pointers should only be obtained from that class and not cached, @@ -37,8 +30,7 @@ class BluetoothSocket; // Since the lifecycle of BluetoothDevice instances is managed by // BluetoothAdapter, that class rather than this provides observer methods // for devices coming and going, as well as properties being updated. -class BluetoothDevice : public BluetoothDeviceClient::Observer, - public BluetoothAgentServiceProvider::Delegate { +class BluetoothDevice { public: // Possible values that may be returned by GetDeviceType(), representing // different types of bluetooth device that we support or are aware of @@ -153,20 +145,13 @@ class BluetoothDevice : public BluetoothDeviceClient::Observer, // DEVICE_PERIPHERAL. DeviceType GetDeviceType() const; - // Returns a localized string containing the device's bluetooth address and - // a device type for display when |name_| is empty. - string16 GetAddressWithLocalizedDeviceTypeName() const; - - // Indicates whether the class of this device is supported by Chrome OS. - bool IsSupported() const; - // Indicates whether the device is paired to the adapter, whether or not // that pairing is permanent or temporary. - virtual bool IsPaired() const; + virtual bool IsPaired() const = 0; // Indicates whether the device is visible to the adapter, this is not // mutually exclusive to being paired. - bool IsVisible() const { return visible_; } + virtual bool IsVisible() const; // Indicates whether the device is bonded to the adapter, bonding is // formed by pairing and exchanging high-security link keys so that @@ -179,7 +164,7 @@ class BluetoothDevice : public BluetoothDeviceClient::Observer, // Returns the services (as UUID strings) that this device provides. typedef std::vector<std::string> ServiceList; - const ServiceList& GetServices() const { return service_uuids_; } + virtual const ServiceList& GetServices() const = 0; // The ErrorCallback is used for methods that can fail in which case it // is called, in the success case the callback is simply not called. @@ -189,34 +174,39 @@ class BluetoothDevice : public BluetoothDeviceClient::Observer, // provides. typedef ScopedVector<BluetoothServiceRecord> ServiceRecordList; typedef base::Callback<void(const ServiceRecordList&)> ServiceRecordsCallback; - void GetServiceRecords(const ServiceRecordsCallback& callback, - const ErrorCallback& error_callback); + virtual void GetServiceRecords(const ServiceRecordsCallback& callback, + const ErrorCallback& error_callback) = 0; // Indicates whether this device provides the given service. |uuid| should // be in canonical form (see bluetooth_utils::CanonicalUuid). - virtual bool ProvidesServiceWithUUID(const std::string& uuid) const; + virtual bool ProvidesServiceWithUUID(const std::string& uuid) const = 0; // The ProvidesServiceCallback is used by ProvidesServiceWithName to indicate // whether or not a matching service was found. typedef base::Callback<void(bool)> ProvidesServiceCallback; // Indicates whether this device provides the given service. - virtual void ProvidesServiceWithName(const std::string& name, - const ProvidesServiceCallback& callback); + virtual void ProvidesServiceWithName( + const std::string& name, + const ProvidesServiceCallback& callback) = 0; // Indicates whether the device is currently pairing and expecting a // PIN Code to be returned. - bool ExpectingPinCode() const { return !pincode_callback_.is_null(); } + virtual bool ExpectingPinCode() const = 0; // Indicates whether the device is currently pairing and expecting a // Passkey to be returned. - bool ExpectingPasskey() const { return !passkey_callback_.is_null(); } + virtual bool ExpectingPasskey() const = 0; // Indicates whether the device is currently pairing and expecting // confirmation of a displayed passkey. - bool ExpectingConfirmation() const { - return !confirmation_callback_.is_null(); - } + virtual bool ExpectingConfirmation() const = 0; + + // SocketCallback is used by ConnectToService to return a BluetoothSocket to + // the caller, or NULL if there was an error. The socket will remain open + // until the last reference to the returned BluetoothSocket is released. + typedef base::Callback<void(scoped_refptr<BluetoothSocket>)> + SocketCallback; // Initiates a connection to the device, pairing first if necessary. // @@ -229,40 +219,40 @@ class BluetoothDevice : public BluetoothDeviceClient::Observer, // // If the request fails, |error_callback| will be called; otherwise, // |callback| is called when the request is complete. - void Connect(PairingDelegate* pairing_delegate, - const base::Closure& callback, - const ErrorCallback& error_callback); + virtual void Connect(PairingDelegate* pairing_delegate, + const base::Closure& callback, + const ErrorCallback& error_callback) = 0; // Sends the PIN code |pincode| to the remote device during pairing. // // PIN Codes are generally required for Bluetooth 2.0 and earlier devices // for which there is no automatic pairing or special handling. - void SetPinCode(const std::string& pincode); + virtual void SetPinCode(const std::string& pincode) = 0; // Sends the Passkey |passkey| to the remote device during pairing. // // Passkeys are generally required for Bluetooth 2.1 and later devices // which cannot provide input or display on their own, and don't accept // passkey-less pairing, and are a numeric in the range 0-999999. - void SetPasskey(uint32 passkey); + virtual void SetPasskey(uint32 passkey) = 0; // Confirms to the remote device during pairing that a passkey provided by // the ConfirmPasskey() delegate call is displayed on both devices. - void ConfirmPairing(); + virtual void ConfirmPairing() = 0; // Rejects a pairing or connection request from a remote device. - void RejectPairing(); + virtual void RejectPairing() = 0; // Cancels a pairing or connection attempt to a remote device. - void CancelPairing(); + virtual void CancelPairing() = 0; // Disconnects the device, terminating the low-level ACL connection // and any application connections using it. Link keys and other pairing // information are not discarded, and the device object is not deleted. // If the request fails, |error_callback| will be called; otherwise, // |callback| is called when the request is complete. - void Disconnect(const base::Closure& callback, - const ErrorCallback& error_callback); + virtual void Disconnect(const base::Closure& callback, + const ErrorCallback& error_callback) = 0; // Disconnects the device, terminating the low-level ACL connection // and any application connections using it, and then discards link keys @@ -271,12 +261,7 @@ class BluetoothDevice : public BluetoothDeviceClient::Observer, // have been deleted. If the request fails, |error_callback| will be called. // There is no callback for success beause this object is often deleted // before that callback would be called. - void Forget(const ErrorCallback& error_callback); - - // SocketCallback is used by ConnectToService to return a BluetoothSocket - // to the caller, or NULL if there was an error. The socket will remain open - // until the last reference to the returned BluetoothSocket is released. - typedef base::Callback<void(scoped_refptr<BluetoothSocket>)> SocketCallback; + virtual void Forget(const ErrorCallback& error_callback) = 0; // Attempts to open a socket to a service matching |uuid| on this device. If // the connection is successful, |callback| is called with a BluetoothSocket. @@ -284,295 +269,34 @@ class BluetoothDevice : public BluetoothDeviceClient::Observer, // all references to the BluetoothSocket are released. Note that the // BluetoothSocket object can outlive both this BluetoothDevice and the // BluetoothAdapter for this device. - void ConnectToService(const std::string& service_uuid, - const SocketCallback& callback); + virtual void ConnectToService(const std::string& service_uuid, + const SocketCallback& callback) = 0; // Sets the Out Of Band pairing data for this device to |data|. Exactly one // of |callback| or |error_callback| will be run. virtual void SetOutOfBandPairingData( - const chromeos::BluetoothOutOfBandPairingData& data, + const BluetoothOutOfBandPairingData& data, const base::Closure& callback, - const ErrorCallback& error_callback); + const ErrorCallback& error_callback) = 0; // Clears the Out Of Band pairing data for this device. Exactly one of // |callback| or |error_callback| will be run. virtual void ClearOutOfBandPairingData( const base::Closure& callback, - const ErrorCallback& error_callback); - - private: - friend class BluetoothAdapter; - friend class MockBluetoothDevice; - - explicit BluetoothDevice(BluetoothAdapter* adapter); - - // Sets the dbus object path for the device to |object_path|, indicating - // that the device has gone from being discovered to paired or bonded. - void SetObjectPath(const dbus::ObjectPath& object_path); - - // Removes the dbus object path from the device, indicating that the - // device is no longer paired or bonded, but perhaps still visible. - void RemoveObjectPath(); - - // Sets whether the device is visible to the owning adapter to |visible|. - void SetVisible(bool visible) { visible_ = visible; } - - // Updates device information from the properties in |properties|, device - // state properties such as |paired_| and |connected_| are ignored unless - // |update_state| is true. - void Update(const BluetoothDeviceClient::Properties* properties, - bool update_state); - - // Called by BluetoothAdapterClient when a call to CreateDevice() or - // CreatePairedDevice() succeeds, provides the new object path for the remote - // device in |device_path|. |callback| and |error_callback| are the callbacks - // provided to Connect(). - void ConnectCallback(const base::Closure& callback, - const ErrorCallback& error_callback, - const dbus::ObjectPath& device_path); - - // Called by BluetoothAdapterClient when a call to CreateDevice() or - // CreatePairedDevice() fails with the error named |error_name| and - // optional message |error_message|, |error_callback| is the callback - // provided to Connect(). - void ConnectErrorCallback(const ErrorCallback& error_callback, - const std::string& error_name, - const std::string& error_message); - - // Called by BluetoothAdapterClient when a call to DiscoverServices() - // completes. |callback| and |error_callback| are the callbacks provided to - // GetServiceRecords. - void CollectServiceRecordsCallback( - const ServiceRecordsCallback& callback, - const ErrorCallback& error_callback, - const dbus::ObjectPath& device_path, - const BluetoothDeviceClient::ServiceMap& service_map, - bool success); - - // Called by BluetoothProperty when the call to Set() for the Trusted - // property completes. |success| indicates whether or not the request - // succeeded, |callback| and |error_callback| are the callbacks provided to - // Connect(). - void OnSetTrusted(const base::Closure& callback, - const ErrorCallback& error_callback, - bool success); - - // Connect application-level protocols of the device to the system, called - // on a successful connection or to reconnect to a device that is already - // paired or previously connected. |error_callback| is called on failure. - // Otherwise, |callback| is called when the request is complete. - void ConnectApplications(const base::Closure& callback, - const ErrorCallback& error_callback); - - // Called by IntrospectableClient when a call to Introspect() completes. - // |success| indicates whether or not the request succeeded, |callback| and - // |error_callback| are the callbacks provided to ConnectApplications(), - // |service_name| and |device_path| specify the remote object being - // introspected and |xml_data| contains the XML-formatted protocol data. - void OnIntrospect(const base::Closure& callback, - const ErrorCallback& error_callback, - const std::string& service_name, - const dbus::ObjectPath& device_path, - const std::string& xml_data, bool success); - - // Called by BluetoothInputClient when the call to Connect() succeeds. - // |error_callback| is the callback provided to ConnectApplications(), - // |interface_name| specifies the interface being connected and - // |device_path| the remote object path. - void OnConnect(const base::Closure& callback, - const std::string& interface_name, - const dbus::ObjectPath& device_path); - - // Called by BluetoothInputClient when the call to Connect() fails. - // |error_callback| is the callback provided to ConnectApplications(), - // |interface_name| specifies the interface being connected, - // |device_path| the remote object path, - // |error_name| the error name and |error_message| the optional message. - void OnConnectError(const ErrorCallback& error_callback, - const std::string& interface_name, - const dbus::ObjectPath& device_path, - const std::string& error_name, - const std::string& error_message); - - // Called by BluetoothDeviceClient when a call to Disconnect() completes, - // |success| indicates whether or not the request succeeded, |callback| and - // |error_callback| are the callbacks provided to Disconnect() and - // |device_path| is the device disconnected. - void DisconnectCallback(const base::Closure& callback, - const ErrorCallback& error_callback, - const dbus::ObjectPath& device_path, bool success); - - // Called by BluetoothAdapterClient when a call to RemoveDevice() completes, - // |success| indicates whether or not the request succeeded, |error_callback| - // is the callback provided to Forget() and |adapter_path| is the d-bus - // object path of the adapter that performed the removal. - void ForgetCallback(const ErrorCallback& error_callback, - const dbus::ObjectPath& adapter_path, bool success); - - // Called if the call to GetServiceRecords from ProvidesServiceWithName fails. - void SearchServicesForNameErrorCallback( - const ProvidesServiceCallback& callback); - - // Called by GetServiceRecords with the list of BluetoothServiceRecords to - // search for |name|. |callback| is the callback from - // ProvidesServiceWithName. - void SearchServicesForNameCallback( - const std::string& name, - const ProvidesServiceCallback& callback, - const ServiceRecordList& list); - - // Called if the call to GetServiceRecords from Connect fails. - void GetServiceRecordsForConnectErrorCallback( - const SocketCallback& callback); - - // Called by GetServiceRecords with the list of BluetoothServiceRecords. - // Connections are attempted to each service in the list matching - // |service_uuid|, and the socket from the first successful connection is - // passed to |callback|. - void GetServiceRecordsForConnectCallback( - const std::string& service_uuid, - const SocketCallback& callback, - const ServiceRecordList& list); - - // Called by BlueoothDeviceClient in response to the AddRemoteData and - // RemoveRemoteData method calls. - void OnRemoteDataCallback(const base::Closure& callback, - const ErrorCallback& error_callback, - bool success); - - // BluetoothDeviceClient::Observer override. - // - // Called when the device with object path |object_path| is about - // to be disconnected, giving a chance for application layers to - // shut down cleanly. - virtual void DisconnectRequested( - const dbus::ObjectPath& object_path) OVERRIDE; - - // BluetoothAgentServiceProvider::Delegate override. - // - // This method will be called when the agent is unregistered from the - // Bluetooth daemon, generally at the end of a pairing request. It may be - // used to perform cleanup tasks. - virtual void Release() OVERRIDE; - - // BluetoothAgentServiceProvider::Delegate override. - // - // This method will be called when the Bluetooth daemon requires a - // PIN Code for authentication of the device with object path |device_path|, - // the agent should obtain the code from the user and call |callback| - // to provide it, or indicate rejection or cancellation of the request. - // - // PIN Codes are generally required for Bluetooth 2.0 and earlier devices - // for which there is no automatic pairing or special handling. - virtual void RequestPinCode(const dbus::ObjectPath& device_path, - const PinCodeCallback& callback) OVERRIDE; - - // BluetoothAgentServiceProvider::Delegate override. - // - // This method will be called when the Bluetooth daemon requires a - // Passkey for authentication of the device with object path |device_path|, - // the agent should obtain the passkey from the user (a numeric in the - // range 0-999999) and call |callback| to provide it, or indicate - // rejection or cancellation of the request. - // - // Passkeys are generally required for Bluetooth 2.1 and later devices - // which cannot provide input or display on their own, and don't accept - // passkey-less pairing. - virtual void RequestPasskey(const dbus::ObjectPath& device_path, - const PasskeyCallback& callback) OVERRIDE; - - // BluetoothAgentServiceProvider::Delegate override. - // - // This method will be called when the Bluetooth daemon requires that the - // user enter the PIN code |pincode| into the device with object path - // |device_path| so that it may be authenticated. The Cancel() method - // will be called to dismiss the display once pairing is complete or - // cancelled. - // - // This is used for Bluetooth 2.0 and earlier keyboard devices, the - // |pincode| will always be a six-digit numeric in the range 000000-999999 - // for compatibilty with later specifications. - virtual void DisplayPinCode(const dbus::ObjectPath& device_path, - const std::string& pincode) OVERRIDE; + const ErrorCallback& error_callback) = 0; - // BluetoothAgentServiceProvider::Delegate override. - // - // This method will be called when the Bluetooth daemon requires that the - // user enter the Passkey |passkey| into the device with object path - // |device_path| so that it may be authenticated. The Cancel() method - // will be called to dismiss the display once pairing is complete or - // cancelled. - // - // This is used for Bluetooth 2.1 and later devices that support input - // but not display, such as keyboards. The Passkey is a numeric in the - // range 0-999999 and should be always presented zero-padded to six - // digits. - virtual void DisplayPasskey(const dbus::ObjectPath& device_path, - uint32 passkey) OVERRIDE; - - // BluetoothAgentServiceProvider::Delegate override. - // - // This method will be called when the Bluetooth daemon requires that the - // user confirm that the Passkey |passkey| is displayed on the screen - // of the device with object path |object_path| so that it may be - // authentication. The agent should display to the user and ask for - // confirmation, then call |callback| to provide their response (success, - // rejected or cancelled). - // - // This is used for Bluetooth 2.1 and later devices that support display, - // such as other computers or phones. The Passkey is a numeric in the - // range 0-999999 and should be always present zero-padded to six - // digits. - virtual void RequestConfirmation( - const dbus::ObjectPath& device_path, - uint32 passkey, - const ConfirmationCallback& callback) OVERRIDE; - - // BluetoothAgentServiceProvider::Delegate override. - // - // This method will be called when the Bluetooth daemon requires that the - // user confirm that the device with object path |object_path| is - // authorized to connect to the service with UUID |uuid|. The agent should - // confirm with the user and call |callback| to provide their response - // (success, rejected or cancelled). - virtual void Authorize(const dbus::ObjectPath& device_path, - const std::string& uuid, - const ConfirmationCallback& callback) OVERRIDE; - - // BluetoothAgentServiceProvider::Delegate override. - // - // This method will be called when the Bluetooth daemon requires that the - // user confirm that the device adapter may switch to mode |mode|. The - // agent should confirm with the user and call |callback| to provide - // their response (success, rejected or cancelled). - virtual void ConfirmModeChange(Mode mode, - const ConfirmationCallback& callback) OVERRIDE; - - // BluetoothAgentServiceProvider::Delegate override. - // - // This method will be called by the Bluetooth daemon to indicate that - // the request failed before a reply was returned from the device. - virtual void Cancel() OVERRIDE; - - // Creates a new BluetoothDevice object bound to the adapter |adapter|. - static BluetoothDevice* Create(BluetoothAdapter* adapter); + protected: + BluetoothDevice(); - // The adapter that owns this device instance. - BluetoothAdapter* adapter_; - - // The dbus object path of the device, will be empty if the device has only - // been discovered and not yet paired with. - dbus::ObjectPath object_path_; - - // The Bluetooth address of the device. - std::string address_; + // The Bluetooth class of the device, a bitmask that may be decoded using + // https://www.bluetooth.org/Technical/AssignedNumbers/baseband.htm + uint32 bluetooth_class_; // The name of the device, as supplied by the remote device. std::string name_; - // The Bluetooth class of the device, a bitmask that may be decoded using - // https://www.bluetooth.org/Technical/AssignedNumbers/baseband.htm - uint32 bluetooth_class_; + // The Bluetooth address of the device. + std::string address_; // Tracked device state, updated by the adapter managing the lifecyle of // the device. @@ -580,33 +304,10 @@ class BluetoothDevice : public BluetoothDeviceClient::Observer, bool bonded_; bool connected_; - // The services (identified by UUIDs) that this device provides. - std::vector<std::string> service_uuids_; - - // During pairing this is set to an object that we don't own, but on which - // we can make method calls to request, display or confirm PIN Codes and - // Passkeys. Generally it is the object that owns this one. - PairingDelegate* pairing_delegate_; - - // During pairing this is set to an instance of a D-Bus agent object - // intialized with our own class as its delegate. - scoped_ptr<BluetoothAgentServiceProvider> agent_; - - // During pairing these callbacks are set to those provided by method calls - // made on us by |agent_| and are called by our own method calls such as - // SetPinCode() and SetPasskey(). - PinCodeCallback pincode_callback_; - PasskeyCallback passkey_callback_; - ConfirmationCallback confirmation_callback_; - - // Used to keep track of pending application connection requests. - int connecting_applications_counter_; - - // Note: This should remain the last member so it'll be destroyed and - // invalidate its weak pointers before any other members are destroyed. - base::WeakPtrFactory<BluetoothDevice> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(BluetoothDevice); + private: + // Returns a localized string containing the device's bluetooth address and + // a device type for display when |name_| is empty. + string16 GetAddressWithLocalizedDeviceTypeName() const; }; } // namespace chromeos diff --git a/chrome/browser/chromeos/bluetooth/bluetooth_device_chromeos.cc b/chrome/browser/chromeos/bluetooth/bluetooth_device_chromeos.cc new file mode 100644 index 0000000..7b1b076 --- /dev/null +++ b/chrome/browser/chromeos/bluetooth/bluetooth_device_chromeos.cc @@ -0,0 +1,700 @@ +// 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_device_chromeos.h" + +#include <map> +#include <string> +#include <vector> + +#include "base/bind.h" +#include "base/command_line.h" +#include "base/logging.h" +#include "base/memory/scoped_vector.h" +#include "base/memory/weak_ptr.h" +#include "base/string16.h" +#include "base/string_util.h" +#include "base/values.h" +#include "chrome/browser/chromeos/bluetooth/bluetooth_adapter_chromeos.h" +#include "chrome/browser/chromeos/bluetooth/bluetooth_service_record.h" +#include "chrome/browser/chromeos/bluetooth/bluetooth_socket_chromeos.h" +#include "chrome/browser/chromeos/bluetooth/bluetooth_utils.h" +#include "chrome/common/chrome_switches.h" +#include "chromeos/dbus/bluetooth_adapter_client.h" +#include "chromeos/dbus/bluetooth_agent_service_provider.h" +#include "chromeos/dbus/bluetooth_device_client.h" +#include "chromeos/dbus/bluetooth_input_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 "chromeos/dbus/introspectable_client.h" +#include "dbus/bus.h" +#include "dbus/object_path.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace chromeos { + +BluetoothDeviceChromeOs::BluetoothDeviceChromeOs( + BluetoothAdapterChromeOs* adapter) + : BluetoothDevice(), + adapter_(adapter), + pairing_delegate_(NULL), + connecting_applications_counter_(0), + weak_ptr_factory_(this) { +} + +BluetoothDeviceChromeOs::~BluetoothDeviceChromeOs() { +} + +bool BluetoothDeviceChromeOs::IsSupported() const { + if (CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableUnsupportedBluetoothDevices)) + return true; + + BluetoothDevice::DeviceType device_type = GetDeviceType(); + return (device_type == DEVICE_JOYSTICK || + device_type == DEVICE_GAMEPAD || + device_type == DEVICE_KEYBOARD || + device_type == DEVICE_MOUSE || + device_type == DEVICE_TABLET || + device_type == DEVICE_KEYBOARD_MOUSE_COMBO); +} + +bool BluetoothDeviceChromeOs::IsPaired() const { + return !object_path_.value().empty(); +} + +const BluetoothDevice::ServiceList& +BluetoothDeviceChromeOs::GetServices() const { + return service_uuids_; +} + +void BluetoothDeviceChromeOs::GetServiceRecords( + const ServiceRecordsCallback& callback, + const ErrorCallback& error_callback) { + DBusThreadManager::Get()->GetBluetoothDeviceClient()-> + DiscoverServices( + object_path_, + "", // empty pattern to browse all services + base::Bind(&BluetoothDeviceChromeOs::CollectServiceRecordsCallback, + weak_ptr_factory_.GetWeakPtr(), + callback, + error_callback)); +} + +bool BluetoothDeviceChromeOs::ProvidesServiceWithUUID( + const std::string& uuid) const { + const BluetoothDevice::ServiceList& services = GetServices(); + for (BluetoothDevice::ServiceList::const_iterator iter = services.begin(); + iter != services.end(); + ++iter) { + if (bluetooth_utils::CanonicalUuid(*iter) == uuid) + return true; + } + return false; +} + +void BluetoothDeviceChromeOs::ProvidesServiceWithName( + const std::string& name, + const ProvidesServiceCallback& callback) { + GetServiceRecords( + base::Bind(&BluetoothDeviceChromeOs::SearchServicesForNameCallback, + weak_ptr_factory_.GetWeakPtr(), + name, + callback), + base::Bind(&BluetoothDeviceChromeOs::SearchServicesForNameErrorCallback, + weak_ptr_factory_.GetWeakPtr(), + callback)); +} + +bool BluetoothDeviceChromeOs::ExpectingPinCode() const { + return !pincode_callback_.is_null(); +} + +bool BluetoothDeviceChromeOs::ExpectingPasskey() const { + return !passkey_callback_.is_null(); +} + +bool BluetoothDeviceChromeOs::ExpectingConfirmation() const { + return !confirmation_callback_.is_null(); +} + +void BluetoothDeviceChromeOs::Connect(PairingDelegate* pairing_delegate, + const base::Closure& callback, + const ErrorCallback& error_callback) { + if (IsPaired() || IsBonded() || IsConnected()) { + // Connection to already paired or connected device. + ConnectApplications(callback, error_callback); + + } else if (!pairing_delegate) { + // No pairing delegate supplied, initiate low-security connection only. + DBusThreadManager::Get()->GetBluetoothAdapterClient()-> + CreateDevice(adapter_->object_path_, + address_, + base::Bind(&BluetoothDeviceChromeOs::ConnectCallback, + weak_ptr_factory_.GetWeakPtr(), + callback, + error_callback), + base::Bind(&BluetoothDeviceChromeOs::ConnectErrorCallback, + weak_ptr_factory_.GetWeakPtr(), + error_callback)); + } else { + // Initiate high-security connection with pairing. + DCHECK(!pairing_delegate_); + pairing_delegate_ = pairing_delegate; + + // The agent path is relatively meaningless, we use the device address + // to generate it as we only support one pairing attempt at a time for + // a given bluetooth device. + DCHECK(agent_.get() == NULL); + + std::string agent_path_basename; + ReplaceChars(address_, ":", "_", &agent_path_basename); + dbus::ObjectPath agent_path("/org/chromium/bluetooth_agent/" + + agent_path_basename); + + dbus::Bus* system_bus = DBusThreadManager::Get()->GetSystemBus(); + if (system_bus) { + agent_.reset(BluetoothAgentServiceProvider::Create(system_bus, + agent_path, + this)); + } else { + agent_.reset(NULL); + } + + DVLOG(1) << "Pairing: " << address_; + DBusThreadManager::Get()->GetBluetoothAdapterClient()-> + CreatePairedDevice( + adapter_->object_path_, + address_, + agent_path, + bluetooth_agent::kDisplayYesNoCapability, + base::Bind(&BluetoothDeviceChromeOs::ConnectCallback, + weak_ptr_factory_.GetWeakPtr(), + callback, + error_callback), + base::Bind(&BluetoothDeviceChromeOs::ConnectErrorCallback, + weak_ptr_factory_.GetWeakPtr(), + error_callback)); + } +} + +void BluetoothDeviceChromeOs::SetPinCode(const std::string& pincode) { + if (!agent_.get() || pincode_callback_.is_null()) + return; + + pincode_callback_.Run(SUCCESS, pincode); + pincode_callback_.Reset(); +} + +void BluetoothDeviceChromeOs::SetPasskey(uint32 passkey) { + if (!agent_.get() || passkey_callback_.is_null()) + return; + + passkey_callback_.Run(SUCCESS, passkey); + passkey_callback_.Reset(); +} + +void BluetoothDeviceChromeOs::ConfirmPairing() { + if (!agent_.get() || confirmation_callback_.is_null()) + return; + + confirmation_callback_.Run(SUCCESS); + confirmation_callback_.Reset(); +} + +void BluetoothDeviceChromeOs::RejectPairing() { + if (!agent_.get()) + return; + + if (!pincode_callback_.is_null()) { + pincode_callback_.Run(REJECTED, ""); + pincode_callback_.Reset(); + } + if (!passkey_callback_.is_null()) { + passkey_callback_.Run(REJECTED, 0); + passkey_callback_.Reset(); + } + if (!confirmation_callback_.is_null()) { + confirmation_callback_.Run(REJECTED); + confirmation_callback_.Reset(); + } +} + +void BluetoothDeviceChromeOs::CancelPairing() { + if (!agent_.get()) + return; + + if (!pincode_callback_.is_null()) { + pincode_callback_.Run(CANCELLED, ""); + pincode_callback_.Reset(); + } + if (!passkey_callback_.is_null()) { + passkey_callback_.Run(CANCELLED, 0); + passkey_callback_.Reset(); + } + if (!confirmation_callback_.is_null()) { + confirmation_callback_.Run(CANCELLED); + confirmation_callback_.Reset(); + } +} + +void BluetoothDeviceChromeOs::Disconnect(const base::Closure& callback, + const ErrorCallback& error_callback) { + DBusThreadManager::Get()->GetBluetoothDeviceClient()-> + Disconnect(object_path_, + base::Bind(&BluetoothDeviceChromeOs::DisconnectCallback, + weak_ptr_factory_.GetWeakPtr(), + callback, + error_callback)); + +} + +void BluetoothDeviceChromeOs::Forget(const ErrorCallback& error_callback) { + DBusThreadManager::Get()->GetBluetoothAdapterClient()-> + RemoveDevice(adapter_->object_path_, + object_path_, + base::Bind(&BluetoothDeviceChromeOs::ForgetCallback, + weak_ptr_factory_.GetWeakPtr(), + error_callback)); +} + +void BluetoothDeviceChromeOs::ConnectToService(const std::string& service_uuid, + const SocketCallback& callback) { + GetServiceRecords( + base::Bind(&BluetoothDeviceChromeOs::GetServiceRecordsForConnectCallback, + weak_ptr_factory_.GetWeakPtr(), + service_uuid, + callback), + base::Bind( + &BluetoothDeviceChromeOs::GetServiceRecordsForConnectErrorCallback, + weak_ptr_factory_.GetWeakPtr(), + callback)); +} + +void BluetoothDeviceChromeOs::SetOutOfBandPairingData( + const chromeos::BluetoothOutOfBandPairingData& data, + const base::Closure& callback, + const ErrorCallback& error_callback) { + DBusThreadManager::Get()->GetBluetoothOutOfBandClient()-> + AddRemoteData( + object_path_, + address(), + data, + base::Bind(&BluetoothDeviceChromeOs::OnRemoteDataCallback, + weak_ptr_factory_.GetWeakPtr(), + callback, + error_callback)); +} + +void BluetoothDeviceChromeOs::ClearOutOfBandPairingData( + const base::Closure& callback, + const ErrorCallback& error_callback) { + DBusThreadManager::Get()->GetBluetoothOutOfBandClient()-> + RemoveRemoteData( + object_path_, + address(), + base::Bind(&BluetoothDeviceChromeOs::OnRemoteDataCallback, + weak_ptr_factory_.GetWeakPtr(), + callback, + error_callback)); +} + +void BluetoothDeviceChromeOs::SetObjectPath( + const dbus::ObjectPath& object_path) { + DCHECK(object_path_ == dbus::ObjectPath("")); + object_path_ = object_path; +} + +void BluetoothDeviceChromeOs::RemoveObjectPath() { + DCHECK(object_path_ != dbus::ObjectPath("")); + object_path_ = dbus::ObjectPath(""); +} + +void BluetoothDeviceChromeOs::Update( + const BluetoothDeviceClient::Properties* properties, + bool update_state) { + std::string address = properties->address.value(); + std::string name = properties->name.value(); + uint32 bluetooth_class = properties->bluetooth_class.value(); + const std::vector<std::string>& uuids = properties->uuids.value(); + + if (!address.empty()) + address_ = address; + if (!name.empty()) + name_ = name; + if (bluetooth_class) + bluetooth_class_ = bluetooth_class; + if (!uuids.empty()) { + service_uuids_.clear(); + service_uuids_.assign(uuids.begin(), uuids.end()); + } + + if (update_state) { + // BlueZ uses paired to mean link keys exchanged, whereas the Bluetooth + // spec refers to this as bonded. Use the spec name for our interface. + bonded_ = properties->paired.value(); + connected_ = properties->connected.value(); + } +} + +void BluetoothDeviceChromeOs::ConnectCallback( + const base::Closure& callback, + const ErrorCallback& error_callback, + const dbus::ObjectPath& device_path) { + DVLOG(1) << "Connection successful: " << device_path.value(); + if (object_path_.value().empty()) { + object_path_ = device_path; + } else { + LOG_IF(WARNING, object_path_ != device_path) + << "Conflicting device paths for objects, result gave: " + << device_path.value() << " but signal gave: " + << object_path_.value(); + } + + // Mark the device trusted so it can connect to us automatically, and + // we can connect after rebooting. This information is part of the + // pairing information of the device, and is unique to the combination + // of our bluetooth address and the device's bluetooth address. A + // different host needs a new pairing, so it's not useful to sync. + DBusThreadManager::Get()->GetBluetoothDeviceClient()-> + GetProperties(object_path_)->trusted.Set( + true, + base::Bind(&BluetoothDeviceChromeOs::OnSetTrusted, + weak_ptr_factory_.GetWeakPtr(), + callback, + error_callback)); + + // Connect application-layer protocols. + ConnectApplications(callback, error_callback); +} + +void BluetoothDeviceChromeOs::ConnectErrorCallback( + const ErrorCallback& error_callback, + const std::string& error_name, + const std::string& error_message) { + LOG(WARNING) << "Connection failed: " << address_ + << ": " << error_name << ": " << error_message; + error_callback.Run(); +} + +void BluetoothDeviceChromeOs::CollectServiceRecordsCallback( + const ServiceRecordsCallback& callback, + const ErrorCallback& error_callback, + const dbus::ObjectPath& device_path, + const BluetoothDeviceClient::ServiceMap& service_map, + bool success) { + if (!success) { + error_callback.Run(); + return; + } + + ScopedVector<BluetoothServiceRecord> records; + for (BluetoothDeviceClient::ServiceMap::const_iterator i = + service_map.begin(); i != service_map.end(); ++i) { + records.push_back( + new BluetoothServiceRecord(address(), i->second)); + } + callback.Run(records); +} + +void BluetoothDeviceChromeOs::OnSetTrusted(const base::Closure& callback, + const ErrorCallback& error_callback, + bool success) { + if (success) { + callback.Run(); + } else { + LOG(WARNING) << "Failed to set device as trusted: " << address_; + error_callback.Run(); + } +} + +void BluetoothDeviceChromeOs::ConnectApplications( + const base::Closure& callback, + const ErrorCallback& error_callback) { + // Introspect the device object to determine supported applications. + DBusThreadManager::Get()->GetIntrospectableClient()-> + Introspect(bluetooth_device::kBluetoothDeviceServiceName, + object_path_, + base::Bind(&BluetoothDeviceChromeOs::OnIntrospect, + weak_ptr_factory_.GetWeakPtr(), + callback, + error_callback)); +} + +void BluetoothDeviceChromeOs::OnIntrospect(const base::Closure& callback, + const ErrorCallback& error_callback, + const std::string& service_name, + const dbus::ObjectPath& device_path, + const std::string& xml_data, + bool success) { + if (!success) { + LOG(WARNING) << "Failed to determine supported applications: " << address_; + error_callback.Run(); + return; + } + + // The introspection data for the device object may list one or more + // additional D-Bus interfaces that BlueZ supports for this particular + // device. Send appropraite Connect calls for each of those interfaces + // to connect all of the application protocols for this device. + std::vector<std::string> interfaces = + IntrospectableClient::GetInterfacesFromIntrospectResult(xml_data); + + DCHECK_EQ(0, connecting_applications_counter_); + connecting_applications_counter_ = 0; + for (std::vector<std::string>::iterator iter = interfaces.begin(); + iter != interfaces.end(); ++iter) { + if (*iter == bluetooth_input::kBluetoothInputInterface) { + connecting_applications_counter_++; + // Supports Input interface. + DBusThreadManager::Get()->GetBluetoothInputClient()-> + Connect(object_path_, + base::Bind(&BluetoothDeviceChromeOs::OnConnect, + weak_ptr_factory_.GetWeakPtr(), + callback, + *iter), + base::Bind(&BluetoothDeviceChromeOs::OnConnectError, + weak_ptr_factory_.GetWeakPtr(), + error_callback, *iter)); + } + } + + // If OnConnect has been called for every call to Connect above, then this + // will decrement the counter to -1. In that case, call the callback + // directly as it has not been called by any of the OnConnect callbacks. + // This is safe because OnIntrospect and OnConnect run on the same thread. + connecting_applications_counter_--; + if (connecting_applications_counter_ == -1) + callback.Run(); +} + +void BluetoothDeviceChromeOs::OnConnect(const base::Closure& callback, + const std::string& interface_name, + const dbus::ObjectPath& device_path) { + DVLOG(1) << "Application connection successful: " << device_path.value() + << ": " << interface_name; + + connecting_applications_counter_--; + // |callback| should only be called once, meaning it cannot be called before + // all requests have been started. The extra decrement after all requests + // have been started, and the check for -1 instead of 0 below, insure only a + // single call to |callback| will occur (provided OnConnect and OnIntrospect + // run on the same thread, which is true). + if (connecting_applications_counter_ == -1) { + connecting_applications_counter_ = 0; + callback.Run(); + } +} + +void BluetoothDeviceChromeOs::OnConnectError( + const ErrorCallback& error_callback, + const std::string& interface_name, + const dbus::ObjectPath& device_path, + const std::string& error_name, + const std::string& error_message) { + LOG(WARNING) << "Connection failed: " << address_ << ": " << interface_name + << ": " << error_name << ": " << error_message; + error_callback.Run(); +} + +void BluetoothDeviceChromeOs::DisconnectCallback( + const base::Closure& callback, + const ErrorCallback& error_callback, + const dbus::ObjectPath& device_path, + bool success) { + DCHECK(device_path == object_path_); + if (success) { + DVLOG(1) << "Disconnection successful: " << address_; + callback.Run(); + } else { + LOG(WARNING) << "Disconnection failed: " << address_; + error_callback.Run(); + } +} + +void BluetoothDeviceChromeOs::ForgetCallback( + const ErrorCallback& error_callback, + const dbus::ObjectPath& adapter_path, + bool success) { + // It's quite normal that this path never gets called on success; we use a + // weak pointer, and bluetoothd might send the DeviceRemoved signal before + // the method reply, in which case this object is deleted and the + // callback never takes place. Therefore don't do anything here for the + // success case. + if (!success) { + LOG(WARNING) << "Forget failed: " << address_; + error_callback.Run(); + } +} + +void BluetoothDeviceChromeOs::SearchServicesForNameErrorCallback( + const ProvidesServiceCallback& callback) { + callback.Run(false); +} + +void BluetoothDeviceChromeOs::SearchServicesForNameCallback( + const std::string& name, + const ProvidesServiceCallback& callback, + const ServiceRecordList& list) { + for (ServiceRecordList::const_iterator i = list.begin(); + i != list.end(); ++i) { + if ((*i)->name() == name) { + callback.Run(true); + return; + } + } + callback.Run(false); +} + +void BluetoothDeviceChromeOs::GetServiceRecordsForConnectErrorCallback( + const SocketCallback& callback) { + callback.Run(NULL); +} + +void BluetoothDeviceChromeOs::GetServiceRecordsForConnectCallback( + const std::string& service_uuid, + const SocketCallback& callback, + const ServiceRecordList& list) { + for (ServiceRecordList::const_iterator i = list.begin(); + i != list.end(); ++i) { + if ((*i)->uuid() == service_uuid) { + // If multiple service records are found, use the first one that works. + scoped_refptr<BluetoothSocket> socket( + BluetoothSocketChromeOs::CreateBluetoothSocket(**i)); + if (socket.get() != NULL) { + callback.Run(socket); + return; + } + } + } + callback.Run(NULL); +} + +void BluetoothDeviceChromeOs::OnRemoteDataCallback( + const base::Closure& callback, + const ErrorCallback& error_callback, + bool success) { + if (success) + callback.Run(); + else + error_callback.Run(); +} + +void BluetoothDeviceChromeOs::DisconnectRequested( + const dbus::ObjectPath& object_path) { + DCHECK(object_path == object_path_); +} + +void BluetoothDeviceChromeOs::Release() { + DCHECK(agent_.get()); + DVLOG(1) << "Release: " << address_; + + DCHECK(pairing_delegate_); + pairing_delegate_->DismissDisplayOrConfirm(); + pairing_delegate_ = NULL; + + pincode_callback_.Reset(); + passkey_callback_.Reset(); + confirmation_callback_.Reset(); + + agent_.reset(); +} + +void BluetoothDeviceChromeOs::RequestPinCode( + const dbus::ObjectPath& device_path, + const PinCodeCallback& callback) { + DCHECK(agent_.get()); + DVLOG(1) << "RequestPinCode: " << device_path.value(); + + DCHECK(pairing_delegate_); + DCHECK(pincode_callback_.is_null()); + pincode_callback_ = callback; + pairing_delegate_->RequestPinCode(this); +} + +void BluetoothDeviceChromeOs::RequestPasskey( + const dbus::ObjectPath& device_path, + const PasskeyCallback& callback) { + DCHECK(agent_.get()); + DCHECK(device_path == object_path_); + DVLOG(1) << "RequestPasskey: " << device_path.value(); + + DCHECK(pairing_delegate_); + DCHECK(passkey_callback_.is_null()); + passkey_callback_ = callback; + pairing_delegate_->RequestPasskey(this); +} + +void BluetoothDeviceChromeOs::DisplayPinCode( + const dbus::ObjectPath& device_path, + const std::string& pincode) { + DCHECK(agent_.get()); + DCHECK(device_path == object_path_); + DVLOG(1) << "DisplayPinCode: " << device_path.value() << " " << pincode; + + DCHECK(pairing_delegate_); + pairing_delegate_->DisplayPinCode(this, pincode); +} + +void BluetoothDeviceChromeOs::DisplayPasskey( + const dbus::ObjectPath& device_path, + uint32 passkey) { + DCHECK(agent_.get()); + DCHECK(device_path == object_path_); + DVLOG(1) << "DisplayPasskey: " << device_path.value() << " " << passkey; + + DCHECK(pairing_delegate_); + pairing_delegate_->DisplayPasskey(this, passkey); +} + +void BluetoothDeviceChromeOs::RequestConfirmation( + const dbus::ObjectPath& device_path, + uint32 passkey, + const ConfirmationCallback& callback) { + DCHECK(agent_.get()); + DCHECK(device_path == object_path_); + DVLOG(1) << "RequestConfirmation: " << device_path.value() << " " << passkey; + + DCHECK(pairing_delegate_); + DCHECK(confirmation_callback_.is_null()); + confirmation_callback_ = callback; + pairing_delegate_->ConfirmPasskey(this, passkey); +} + +void BluetoothDeviceChromeOs::Authorize(const dbus::ObjectPath& device_path, + const std::string& uuid, + const ConfirmationCallback& callback) { + DCHECK(agent_.get()); + DCHECK(device_path == object_path_); + LOG(WARNING) << "Rejected authorization for service: " << uuid + << " requested from device: " << device_path.value(); + callback.Run(REJECTED); +} + +void BluetoothDeviceChromeOs::ConfirmModeChange( + Mode mode, + const ConfirmationCallback& callback) { + DCHECK(agent_.get()); + LOG(WARNING) << "Rejected adapter-level mode change: " << mode + << " made on agent for device: " << address_; + callback.Run(REJECTED); +} + +void BluetoothDeviceChromeOs::Cancel() { + DCHECK(agent_.get()); + DVLOG(1) << "Cancel: " << address_; + + DCHECK(pairing_delegate_); + pairing_delegate_->DismissDisplayOrConfirm(); +} + + +// static +BluetoothDeviceChromeOs* BluetoothDeviceChromeOs::Create( + BluetoothAdapterChromeOs* adapter) { + return new BluetoothDeviceChromeOs(adapter); +} + +} // namespace chromeos diff --git a/chrome/browser/chromeos/bluetooth/bluetooth_device_chromeos.h b/chrome/browser/chromeos/bluetooth/bluetooth_device_chromeos.h new file mode 100644 index 0000000..aacbeb9 --- /dev/null +++ b/chrome/browser/chromeos/bluetooth/bluetooth_device_chromeos.h @@ -0,0 +1,372 @@ +// 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. + +#ifndef CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_DEVICE_CHROMEOS_H_ +#define CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_DEVICE_CHROMEOS_H_ + +#include <string> +#include <vector> + +#include "base/basictypes.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/scoped_vector.h" +#include "base/memory/weak_ptr.h" +#include "base/string16.h" +#include "chrome/browser/chromeos/bluetooth/bluetooth_device.h" +#include "chromeos/dbus/bluetooth_agent_service_provider.h" +#include "chromeos/dbus/bluetooth_device_client.h" +#include "dbus/object_path.h" + +namespace chromeos { + +class BluetoothAdapterChromeOs; +class BluetoothServiceRecord; + +struct BluetoothOutOfBandPairingData; + +// The BluetoothDeviceChromeOs class is an implementation of BluetoothDevice +// for Chrome OS platform. +class BluetoothDeviceChromeOs : public BluetoothDevice, + public BluetoothDeviceClient::Observer, + public BluetoothAgentServiceProvider::Delegate { + public: + virtual ~BluetoothDeviceChromeOs(); + + // BluetoothDevice override + virtual bool IsPaired() const OVERRIDE; + virtual const ServiceList& GetServices() const OVERRIDE; + virtual void GetServiceRecords( + const ServiceRecordsCallback& callback, + const ErrorCallback& error_callback) OVERRIDE; + virtual bool ProvidesServiceWithUUID(const std::string& uuid) const OVERRIDE; + virtual void ProvidesServiceWithName( + const std::string& name, + const ProvidesServiceCallback& callback) OVERRIDE; + virtual bool ExpectingPinCode() const OVERRIDE; + virtual bool ExpectingPasskey() const OVERRIDE; + virtual bool ExpectingConfirmation() const OVERRIDE; + virtual void Connect( + BluetoothDevice::PairingDelegate* pairing_delegate, + const base::Closure& callback, + const ErrorCallback& error_callback) OVERRIDE; + virtual void SetPinCode(const std::string& pincode) OVERRIDE; + virtual void SetPasskey(uint32 passkey) OVERRIDE; + virtual void ConfirmPairing() OVERRIDE; + virtual void RejectPairing() OVERRIDE; + virtual void CancelPairing() OVERRIDE; + virtual void Disconnect( + const base::Closure& callback, + const ErrorCallback& error_callback) OVERRIDE; + virtual void Forget(const ErrorCallback& error_callback) OVERRIDE; + virtual void ConnectToService( + const std::string& service_uuid, + const SocketCallback& callback) OVERRIDE; + virtual void SetOutOfBandPairingData( + const chromeos::BluetoothOutOfBandPairingData& data, + const base::Closure& callback, + const ErrorCallback& error_callback) OVERRIDE; + virtual void ClearOutOfBandPairingData( + const base::Closure& callback, + const ErrorCallback& error_callback) OVERRIDE; + + private: + friend class BluetoothAdapterChromeOs; + friend class MockBluetoothDevice; + + explicit BluetoothDeviceChromeOs(BluetoothAdapterChromeOs* adapter); + + // Indicates whether the class of this device is supported by Chrome OS. + bool IsSupported() const; + + // Sets the dbus object path for the device to |object_path|, indicating + // that the device has gone from being discovered to paired or bonded. + void SetObjectPath(const dbus::ObjectPath& object_path); + + // Removes the dbus object path from the device, indicating that the + // device is no longer paired or bonded, but perhaps still visible. + void RemoveObjectPath(); + + // Sets whether the device is visible to the owning adapter to |visible|. + void SetVisible(bool visible) { visible_ = visible; } + + // Updates device information from the properties in |properties|, device + // state properties such as |paired_| and |connected_| are ignored unless + // |update_state| is true. + void Update(const BluetoothDeviceClient::Properties* properties, + bool update_state); + + // Called by BluetoothAdapterClient when a call to CreateDevice() or + // CreatePairedDevice() succeeds, provides the new object path for the remote + // device in |device_path|. |callback| and |error_callback| are the callbacks + // provided to Connect(). + void ConnectCallback(const base::Closure& callback, + const ErrorCallback& error_callback, + const dbus::ObjectPath& device_path); + + // Called by BluetoothAdapterClient when a call to CreateDevice() or + // CreatePairedDevice() fails with the error named |error_name| and + // optional message |error_message|, |error_callback| is the callback + // provided to Connect(). + void ConnectErrorCallback(const ErrorCallback& error_callback, + const std::string& error_name, + const std::string& error_message); + + // Called by BluetoothAdapterClient when a call to DiscoverServices() + // completes. |callback| and |error_callback| are the callbacks provided to + // GetServiceRecords. + void CollectServiceRecordsCallback( + const ServiceRecordsCallback& callback, + const ErrorCallback& error_callback, + const dbus::ObjectPath& device_path, + const BluetoothDeviceClient::ServiceMap& service_map, + bool success); + + // Called by BluetoothProperty when the call to Set() for the Trusted + // property completes. |success| indicates whether or not the request + // succeeded, |callback| and |error_callback| are the callbacks provided to + // Connect(). + void OnSetTrusted(const base::Closure& callback, + const ErrorCallback& error_callback, + bool success); + + // Connect application-level protocols of the device to the system, called + // on a successful connection or to reconnect to a device that is already + // paired or previously connected. |error_callback| is called on failure. + // Otherwise, |callback| is called when the request is complete. + void ConnectApplications(const base::Closure& callback, + const ErrorCallback& error_callback); + + // Called by IntrospectableClient when a call to Introspect() completes. + // |success| indicates whether or not the request succeeded, |callback| and + // |error_callback| are the callbacks provided to ConnectApplications(), + // |service_name| and |device_path| specify the remote object being + // introspected and |xml_data| contains the XML-formatted protocol data. + void OnIntrospect(const base::Closure& callback, + const ErrorCallback& error_callback, + const std::string& service_name, + const dbus::ObjectPath& device_path, + const std::string& xml_data, bool success); + + // Called by BluetoothInputClient when the call to Connect() succeeds. + // |error_callback| is the callback provided to ConnectApplications(), + // |interface_name| specifies the interface being connected and + // |device_path| the remote object path. + void OnConnect(const base::Closure& callback, + const std::string& interface_name, + const dbus::ObjectPath& device_path); + + // Called by BluetoothInputClient when the call to Connect() fails. + // |error_callback| is the callback provided to ConnectApplications(), + // |interface_name| specifies the interface being connected, + // |device_path| the remote object path, + // |error_name| the error name and |error_message| the optional message. + void OnConnectError(const ErrorCallback& error_callback, + const std::string& interface_name, + const dbus::ObjectPath& device_path, + const std::string& error_name, + const std::string& error_message); + + // Called by BluetoothDeviceClient when a call to Disconnect() completes, + // |success| indicates whether or not the request succeeded, |callback| and + // |error_callback| are the callbacks provided to Disconnect() and + // |device_path| is the device disconnected. + void DisconnectCallback(const base::Closure& callback, + const ErrorCallback& error_callback, + const dbus::ObjectPath& device_path, bool success); + + // Called by BluetoothAdapterClient when a call to RemoveDevice() + // completes, |success| indicates whether or not the request succeeded, + // |error_callback| is the callback provided to Forget() and |adapter_path| is + // the d-bus object path of the adapter that performed the removal. + void ForgetCallback(const ErrorCallback& error_callback, + const dbus::ObjectPath& adapter_path, bool success); + + // Called if the call to GetServiceRecords from ProvidesServiceWithName fails. + void SearchServicesForNameErrorCallback( + const ProvidesServiceCallback& callback); + + // Called by GetServiceRecords with the list of BluetoothServiceRecords to + // search for |name|. |callback| is the callback from + // ProvidesServiceWithName. + void SearchServicesForNameCallback( + const std::string& name, + const ProvidesServiceCallback& callback, + const ServiceRecordList& list); + + // Called if the call to GetServiceRecords from Connect fails. + void GetServiceRecordsForConnectErrorCallback( + const SocketCallback& callback); + + // Called by GetServiceRecords with the list of BluetoothServiceRecords. + // Connections are attempted to each service in the list matching + // |service_uuid|, and the socket from the first successful connection is + // passed to |callback|. + void GetServiceRecordsForConnectCallback( + const std::string& service_uuid, + const SocketCallback& callback, + const ServiceRecordList& list); + + // Called by BlueoothDeviceClient in response to the AddRemoteData and + // RemoveRemoteData method calls. + void OnRemoteDataCallback(const base::Closure& callback, + const ErrorCallback& error_callback, + bool success); + + // BluetoothDeviceClient::Observer override. + // + // Called when the device with object path |object_path| is about + // to be disconnected, giving a chance for application layers to + // shut down cleanly. + virtual void DisconnectRequested( + const dbus::ObjectPath& object_path) OVERRIDE; + + // BluetoothAgentServiceProvider::Delegate override. + // + // This method will be called when the agent is unregistered from the + // Bluetooth daemon, generally at the end of a pairing request. It may be + // used to perform cleanup tasks. + virtual void Release() OVERRIDE; + + // BluetoothAgentServiceProvider::Delegate override. + // + // This method will be called when the Bluetooth daemon requires a + // PIN Code for authentication of the device with object path |device_path|, + // the agent should obtain the code from the user and call |callback| + // to provide it, or indicate rejection or cancellation of the request. + // + // PIN Codes are generally required for Bluetooth 2.0 and earlier devices + // for which there is no automatic pairing or special handling. + virtual void RequestPinCode(const dbus::ObjectPath& device_path, + const PinCodeCallback& callback) OVERRIDE; + + // BluetoothAgentServiceProvider::Delegate override. + // + // This method will be called when the Bluetooth daemon requires a + // Passkey for authentication of the device with object path |device_path|, + // the agent should obtain the passkey from the user (a numeric in the + // range 0-999999) and call |callback| to provide it, or indicate + // rejection or cancellation of the request. + // + // Passkeys are generally required for Bluetooth 2.1 and later devices + // which cannot provide input or display on their own, and don't accept + // passkey-less pairing. + virtual void RequestPasskey(const dbus::ObjectPath& device_path, + const PasskeyCallback& callback) OVERRIDE; + + // BluetoothAgentServiceProvider::Delegate override. + // + // This method will be called when the Bluetooth daemon requires that the + // user enter the PIN code |pincode| into the device with object path + // |device_path| so that it may be authenticated. The Cancel() method + // will be called to dismiss the display once pairing is complete or + // cancelled. + // + // This is used for Bluetooth 2.0 and earlier keyboard devices, the + // |pincode| will always be a six-digit numeric in the range 000000-999999 + // for compatibilty with later specifications. + virtual void DisplayPinCode(const dbus::ObjectPath& device_path, + const std::string& pincode) OVERRIDE; + + // BluetoothAgentServiceProvider::Delegate override. + // + // This method will be called when the Bluetooth daemon requires that the + // user enter the Passkey |passkey| into the device with object path + // |device_path| so that it may be authenticated. The Cancel() method + // will be called to dismiss the display once pairing is complete or + // cancelled. + // + // This is used for Bluetooth 2.1 and later devices that support input + // but not display, such as keyboards. The Passkey is a numeric in the + // range 0-999999 and should be always presented zero-padded to six + // digits. + virtual void DisplayPasskey(const dbus::ObjectPath& device_path, + uint32 passkey) OVERRIDE; + + // BluetoothAgentServiceProvider::Delegate override. + // + // This method will be called when the Bluetooth daemon requires that the + // user confirm that the Passkey |passkey| is displayed on the screen + // of the device with object path |object_path| so that it may be + // authentication. The agent should display to the user and ask for + // confirmation, then call |callback| to provide their response (success, + // rejected or cancelled). + // + // This is used for Bluetooth 2.1 and later devices that support display, + // such as other computers or phones. The Passkey is a numeric in the + // range 0-999999 and should be always present zero-padded to six + // digits. + virtual void RequestConfirmation( + const dbus::ObjectPath& device_path, + uint32 passkey, + const ConfirmationCallback& callback) OVERRIDE; + + // BluetoothAgentServiceProvider::Delegate override. + // + // This method will be called when the Bluetooth daemon requires that the + // user confirm that the device with object path |object_path| is + // authorized to connect to the service with UUID |uuid|. The agent should + // confirm with the user and call |callback| to provide their response + // (success, rejected or cancelled). + virtual void Authorize(const dbus::ObjectPath& device_path, + const std::string& uuid, + const ConfirmationCallback& callback) OVERRIDE; + + // BluetoothAgentServiceProvider::Delegate override. + // + // This method will be called when the Bluetooth daemon requires that the + // user confirm that the device adapter may switch to mode |mode|. The + // agent should confirm with the user and call |callback| to provide + // their response (success, rejected or cancelled). + virtual void ConfirmModeChange(Mode mode, + const ConfirmationCallback& callback) OVERRIDE; + + // BluetoothAgentServiceProvider::Delegate override. + // + // This method will be called by the Bluetooth daemon to indicate that + // the request failed before a reply was returned from the device. + virtual void Cancel() OVERRIDE; + + // Creates a new BluetoothDeviceChromeOs object bound to the adapter + // |adapter|. + static BluetoothDeviceChromeOs* Create(BluetoothAdapterChromeOs* adapter); + + // The adapter that owns this device instance. + BluetoothAdapterChromeOs* adapter_; + + // The dbus object path of the device, will be empty if the device has only + // been discovered and not yet paired with. + dbus::ObjectPath object_path_; + + // The services (identified by UUIDs) that this device provides. + std::vector<std::string> service_uuids_; + + // During pairing this is set to an object that we don't own, but on which + // we can make method calls to request, display or confirm PIN Codes and + // Passkeys. Generally it is the object that owns this one. + BluetoothDevice::PairingDelegate* pairing_delegate_; + + // During pairing this is set to an instance of a D-Bus agent object + // intialized with our own class as its delegate. + scoped_ptr<BluetoothAgentServiceProvider> agent_; + + // During pairing these callbacks are set to those provided by method calls + // made on us by |agent_| and are called by our own method calls such as + // SetPinCode() and SetPasskey(). + PinCodeCallback pincode_callback_; + PasskeyCallback passkey_callback_; + ConfirmationCallback confirmation_callback_; + + // Used to keep track of pending application connection requests. + int connecting_applications_counter_; + + // Note: This should remain the last member so it'll be destroyed and + // invalidate its weak pointers before any other members are destroyed. + base::WeakPtrFactory<BluetoothDeviceChromeOs> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(BluetoothDeviceChromeOs); +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_DEVICE_CHROMEOS_H_ diff --git a/chrome/browser/chromeos/bluetooth/bluetooth_service_record.h b/chrome/browser/chromeos/bluetooth/bluetooth_service_record.h index 03a3232..2e43d72 100644 --- a/chrome/browser/chromeos/bluetooth/bluetooth_service_record.h +++ b/chrome/browser/chromeos/bluetooth/bluetooth_service_record.h @@ -13,7 +13,7 @@ class XmlReader; namespace chromeos { -// The BluetoothServiceRecord represents an SDP service record. +// BluetoothServiceRecord represents an SDP service record. // // This implementation is currently incomplete: it only supports those fields // that have been necessary so far. diff --git a/chrome/browser/chromeos/bluetooth/bluetooth_socket.h b/chrome/browser/chromeos/bluetooth/bluetooth_socket.h index 97a8679..326c0f7 100644 --- a/chrome/browser/chromeos/bluetooth/bluetooth_socket.h +++ b/chrome/browser/chromeos/bluetooth/bluetooth_socket.h @@ -5,36 +5,24 @@ #ifndef CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_SOCKET_H_ #define CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_SOCKET_H_ -#include <string> - -#include "base/memory/weak_ptr.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_service_record.h" +#include "base/memory/ref_counted.h" namespace chromeos { -class BluetoothDevice; - -// The BluetoothSocket class represents a socket to a specific service on -// a BluetoothDevice. BluetoothSocket objects are ref counted and may outlive +// BluetoothSocket represents a socket to a specific service on a +// BluetoothDevice. BluetoothSocket objects are ref counted and may outlive // both the BluetoothDevice and BluetoothAdapter that were involved in their // creation. class BluetoothSocket : public base::RefCounted<BluetoothSocket> { public: - static scoped_refptr<BluetoothSocket> CreateBluetoothSocket( - const BluetoothServiceRecord& service_record); - - int fd() const { return fd_; } + // TODO(youngki): Replace this with an opaque id when read/write calls are + // added. This interface is platform-independent and file descriptor is + // linux-specific hence this method has to be renamed. + virtual int fd() const = 0; - private: + protected: friend class base::RefCounted<BluetoothSocket>; - - BluetoothSocket(const std::string& address, int fd); - virtual ~BluetoothSocket(); - - const std::string address_; - const int fd_; - - DISALLOW_COPY_AND_ASSIGN(BluetoothSocket); + virtual ~BluetoothSocket() {} }; } // namespace chromeos diff --git a/chrome/browser/chromeos/bluetooth/bluetooth_socket.cc b/chrome/browser/chromeos/bluetooth/bluetooth_socket_chromeos.cc index 62806e0..f86f9c5 100644 --- a/chrome/browser/chromeos/bluetooth/bluetooth_socket.cc +++ b/chrome/browser/chromeos/bluetooth/bluetooth_socket_chromeos.cc @@ -2,7 +2,7 @@ // 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_socket.h" +#include "chrome/browser/chromeos/bluetooth/bluetooth_socket_chromeos.h" #include <vector> @@ -14,24 +14,26 @@ #include <string.h> #include <unistd.h> +#include "base/logging.h" #include "chrome/browser/chromeos/bluetooth/bluetooth_service_record.h" #include "chrome/browser/chromeos/bluetooth/bluetooth_utils.h" namespace chromeos { -BluetoothSocket::BluetoothSocket(const std::string& address, int fd) +BluetoothSocketChromeOs::BluetoothSocketChromeOs( + const std::string& address, int fd) : address_(address), fd_(fd) { } -BluetoothSocket::~BluetoothSocket() { +BluetoothSocketChromeOs::~BluetoothSocketChromeOs() { close(fd_); } // static -scoped_refptr<BluetoothSocket> BluetoothSocket::CreateBluetoothSocket( +scoped_refptr<BluetoothSocket> BluetoothSocketChromeOs::CreateBluetoothSocket( const BluetoothServiceRecord& service_record) { - BluetoothSocket* bluetooth_socket = NULL; + BluetoothSocketChromeOs* bluetooth_socket = NULL; if (service_record.SupportsRfcomm()) { int socket_fd = socket( AF_BLUETOOTH, SOCK_STREAM | SOCK_NONBLOCK, BTPROTO_RFCOMM); @@ -45,7 +47,7 @@ scoped_refptr<BluetoothSocket> BluetoothSocket::CreateBluetoothSocket( sizeof(socket_address)); int errsv = errno; if (status == 0 || errno == EINPROGRESS) { - bluetooth_socket = new BluetoothSocket(service_record.address(), + bluetooth_socket = new BluetoothSocketChromeOs(service_record.address(), socket_fd); } else { LOG(ERROR) << "Failed to connect bluetooth socket " @@ -56,7 +58,11 @@ scoped_refptr<BluetoothSocket> BluetoothSocket::CreateBluetoothSocket( } // TODO(bryeung): add support for L2CAP sockets as well. - return scoped_refptr<BluetoothSocket>(bluetooth_socket); + return scoped_refptr<BluetoothSocketChromeOs>(bluetooth_socket); +} + +int BluetoothSocketChromeOs::fd() const { + return fd_; } } // namespace chromeos diff --git a/chrome/browser/chromeos/bluetooth/bluetooth_socket_chromeos.h b/chrome/browser/chromeos/bluetooth/bluetooth_socket_chromeos.h new file mode 100644 index 0000000..7d0328c --- /dev/null +++ b/chrome/browser/chromeos/bluetooth/bluetooth_socket_chromeos.h @@ -0,0 +1,40 @@ +// 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. + +#ifndef CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_SOCKET_CHROMEOS_H_ +#define CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_SOCKET_CHROMEOS_H_ + +#include <string> + +#include "base/memory/ref_counted.h" +#include "chrome/browser/chromeos/bluetooth/bluetooth_service_record.h" +#include "chrome/browser/chromeos/bluetooth/bluetooth_socket.h" + +namespace chromeos { + +// This class is an implementation of BluetoothSocket class for Chrome OS +// platform. +class BluetoothSocketChromeOs : public BluetoothSocket { + public: + static scoped_refptr<BluetoothSocket> CreateBluetoothSocket( + const BluetoothServiceRecord& service_record); + + // BluetoothSocket override + virtual int fd() const OVERRIDE; + + protected: + virtual ~BluetoothSocketChromeOs(); + + private: + BluetoothSocketChromeOs(const std::string& address, int fd); + + const std::string address_; + const int fd_; + + DISALLOW_COPY_AND_ASSIGN(BluetoothSocketChromeOs); +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_SOCKET_CHROMEOS_H_ diff --git a/chrome/browser/chromeos/bluetooth/test/mock_bluetooth_adapter.h b/chrome/browser/chromeos/bluetooth/test/mock_bluetooth_adapter.h index 55194cf..ba94c20 100644 --- a/chrome/browser/chromeos/bluetooth/test/mock_bluetooth_adapter.h +++ b/chrome/browser/chromeos/bluetooth/test/mock_bluetooth_adapter.h @@ -24,30 +24,35 @@ class MockBluetoothAdapter : public BluetoothAdapter { MOCK_METHOD2(AdapterPresentChanged, void(BluetoothAdapter*, bool)); MOCK_METHOD2(AdapterPoweredChanged, void(BluetoothAdapter*, bool)); - MOCK_METHOD2(AdapterDiscoveringChanged, void(BluetoothAdapter *, bool)); - MOCK_METHOD2(DeviceAdded, void(BluetoothAdapter *, BluetoothDevice *)); - MOCK_METHOD2(DeviceChanged, void(BluetoothAdapter *, BluetoothDevice *)); - MOCK_METHOD2(DeviceRemoved, void(BluetoothAdapter *, BluetoothDevice *)); + MOCK_METHOD2(AdapterDiscoveringChanged, void(BluetoothAdapter*, bool)); + MOCK_METHOD2(DeviceAdded, void(BluetoothAdapter*, BluetoothDevice*)); + MOCK_METHOD2(DeviceChanged, void(BluetoothAdapter*, BluetoothDevice*)); + MOCK_METHOD2(DeviceRemoved, void(BluetoothAdapter*, BluetoothDevice*)); }; MockBluetoothAdapter(const std::string& address, const std::string& name); + MOCK_METHOD1(AddObserver, void(BluetoothAdapter::Observer*)); + MOCK_METHOD1(RemoveObserver, void(BluetoothAdapter::Observer*)); MOCK_CONST_METHOD0(IsPresent, bool()); MOCK_CONST_METHOD0(IsPowered, bool()); + MOCK_METHOD3(SetPowered, + void(bool discovering, + const base::Closure& callback, + const ErrorCallback& error_callback)); MOCK_CONST_METHOD0(IsDiscovering, bool()); MOCK_METHOD3(SetDiscovering, void(bool discovering, const base::Closure& callback, - const BluetoothAdapter::ErrorCallback& error_callback)); - MOCK_CONST_METHOD0(GetDevices, ConstDeviceList()); + const ErrorCallback& error_callback)); + MOCK_CONST_METHOD0(GetDevices, BluetoothAdapter::ConstDeviceList()); MOCK_METHOD1(GetDevice, BluetoothDevice*(const std::string& address)); MOCK_CONST_METHOD1(GetDevice, const BluetoothDevice*(const std::string& address)); MOCK_METHOD2( ReadLocalOutOfBandPairingData, - void(const BluetoothAdapter::BluetoothOutOfBandPairingDataCallback& - callback, - const BluetoothAdapter::ErrorCallback& error_callback)); + void(const BluetoothOutOfBandPairingDataCallback& callback, + const ErrorCallback& error_callback)); protected: virtual ~MockBluetoothAdapter(); }; diff --git a/chrome/browser/chromeos/bluetooth/test/mock_bluetooth_device.cc b/chrome/browser/chromeos/bluetooth/test/mock_bluetooth_device.cc index 5bc0cf7..1387fd2 100644 --- a/chrome/browser/chromeos/bluetooth/test/mock_bluetooth_device.cc +++ b/chrome/browser/chromeos/bluetooth/test/mock_bluetooth_device.cc @@ -14,8 +14,7 @@ MockBluetoothDevice::MockBluetoothDevice(MockBluetoothAdapter* adapter, bool paired, bool bonded, bool connected) - : BluetoothDevice(adapter), - name_(UTF8ToUTF16(name)), + : name_(UTF8ToUTF16(name)), address_(address) { ON_CALL(*this, GetName()) .WillByDefault(testing::Return(name_)); @@ -27,6 +26,14 @@ MockBluetoothDevice::MockBluetoothDevice(MockBluetoothAdapter* adapter, .WillByDefault(testing::Return(bonded)); ON_CALL(*this, IsConnected()) .WillByDefault(testing::Return(connected)); + ON_CALL(*this, ExpectingPinCode()) + .WillByDefault(testing::Return(false)); + ON_CALL(*this, ExpectingPasskey()) + .WillByDefault(testing::Return(false)); + ON_CALL(*this, ExpectingConfirmation()) + .WillByDefault(testing::Return(false)); + ON_CALL(*this, GetServices()) + .WillByDefault(testing::ReturnRef(service_list_)); } MockBluetoothDevice::~MockBluetoothDevice() {} diff --git a/chrome/browser/chromeos/bluetooth/test/mock_bluetooth_device.h b/chrome/browser/chromeos/bluetooth/test/mock_bluetooth_device.h index 7079f28..650928c 100644 --- a/chrome/browser/chromeos/bluetooth/test/mock_bluetooth_device.h +++ b/chrome/browser/chromeos/bluetooth/test/mock_bluetooth_device.h @@ -9,6 +9,7 @@ #include "base/string16.h" #include "chrome/browser/chromeos/bluetooth/bluetooth_device.h" +#include "chromeos/dbus/bluetooth_out_of_band_pairing_data.h" #include "testing/gmock/include/gmock/gmock.h" namespace chromeos { @@ -25,14 +26,38 @@ class MockBluetoothDevice : public BluetoothDevice { MOCK_CONST_METHOD0(address, const std::string&()); MOCK_CONST_METHOD0(GetName, string16()); + MOCK_CONST_METHOD0(GetDeviceType, BluetoothDevice::DeviceType()); MOCK_CONST_METHOD0(IsPaired, bool()); MOCK_CONST_METHOD0(IsBonded, bool()); MOCK_CONST_METHOD0(IsConnected, bool()); + MOCK_CONST_METHOD0(GetServices, const ServiceList&()); + MOCK_METHOD2(GetServiceRecords, + void(const BluetoothDevice::ServiceRecordsCallback&, + const BluetoothDevice::ErrorCallback&)); MOCK_CONST_METHOD1(ProvidesServiceWithUUID, bool(const std::string&)); - MOCK_METHOD2(ProvidesServiceWithName, - void(const std::string&, - const ProvidesServiceCallback& callback)); + void(const std::string&, + const BluetoothDevice::ProvidesServiceCallback&)); + MOCK_CONST_METHOD0(ExpectingPinCode, bool()); + MOCK_CONST_METHOD0(ExpectingPasskey, bool()); + MOCK_CONST_METHOD0(ExpectingConfirmation, bool()); + MOCK_METHOD3(Connect, + void(BluetoothDevice::PairingDelegate* pairnig_delegate, + const base::Closure& callback, + const BluetoothDevice::ErrorCallback& error_callback)); + MOCK_METHOD1(SetPinCode, void(const std::string&)); + MOCK_METHOD1(SetPasskey, void(uint32)); + MOCK_METHOD0(ConfirmPairing, void()); + MOCK_METHOD0(RejectPairing, void()); + MOCK_METHOD0(CancelPairing, void()); + MOCK_METHOD2(Disconnect, + void(const base::Closure& callback, + const BluetoothDevice::ErrorCallback& error_callback)); + MOCK_METHOD1(Forget, void(const BluetoothDevice::ErrorCallback&)); + MOCK_METHOD2(ConnectToService, + void(const std::string&, + const BluetoothDevice::SocketCallback&)); + MOCK_METHOD3(SetOutOfBandPairingData, void(const chromeos::BluetoothOutOfBandPairingData& data, const base::Closure& callback, @@ -44,6 +69,7 @@ class MockBluetoothDevice : public BluetoothDevice { private: string16 name_; std::string address_; + BluetoothDevice::ServiceList service_list_; }; } // namespace chromeos diff --git a/chrome/browser/chromeos/extensions/bluetooth_event_router.cc b/chrome/browser/chromeos/extensions/bluetooth_event_router.cc index c93c765..64331bf 100644 --- a/chrome/browser/chromeos/extensions/bluetooth_event_router.cc +++ b/chrome/browser/chromeos/extensions/bluetooth_event_router.cc @@ -11,7 +11,8 @@ #include "base/memory/scoped_vector.h" #include "base/utf_string_conversions.h" #include "chrome/browser/chromeos/bluetooth/bluetooth_adapter.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_device.h" +#include "chrome/browser/chromeos/bluetooth/bluetooth_adapter_factory.h" +#include "chrome/browser/chromeos/bluetooth/bluetooth_device_chromeos.h" #include "chrome/browser/chromeos/bluetooth/bluetooth_socket.h" #include "chrome/browser/extensions/api/bluetooth/bluetooth_api_utils.h" #include "chrome/browser/extensions/event_names.h" @@ -24,7 +25,7 @@ namespace chromeos { ExtensionBluetoothEventRouter::ExtensionBluetoothEventRouter(Profile* profile) : profile_(profile), - adapter_(chromeos::BluetoothAdapter::DefaultAdapter()), + adapter_(chromeos::BluetoothAdapterFactory::DefaultAdapter()), next_socket_id_(1) { DCHECK(profile_); DCHECK(adapter_.get()); diff --git a/chrome/browser/chromeos/system/ash_system_tray_delegate.cc b/chrome/browser/chromeos/system/ash_system_tray_delegate.cc index f483976..42e58ee 100644 --- a/chrome/browser/chromeos/system/ash_system_tray_delegate.cc +++ b/chrome/browser/chromeos/system/ash_system_tray_delegate.cc @@ -32,6 +32,7 @@ #include "chrome/browser/chromeos/accessibility/accessibility_util.h" #include "chrome/browser/chromeos/audio/audio_handler.h" #include "chrome/browser/chromeos/bluetooth/bluetooth_adapter.h" +#include "chrome/browser/chromeos/bluetooth/bluetooth_adapter_factory.h" #include "chrome/browser/chromeos/bluetooth/bluetooth_device.h" #include "chrome/browser/chromeos/cros/cros_library.h" #include "chrome/browser/chromeos/cros/network_library.h" @@ -216,7 +217,7 @@ class SystemTrayDelegate : public ash::SystemTrayDelegate, network_icon_->SetResourceColorTheme(NetworkMenuIcon::COLOR_LIGHT); network_icon_dark_->SetResourceColorTheme(NetworkMenuIcon::COLOR_DARK); - bluetooth_adapter_ = BluetoothAdapter::DefaultAdapter(); + bluetooth_adapter_ = BluetoothAdapterFactory::DefaultAdapter(); bluetooth_adapter_->AddObserver(this); } diff --git a/chrome/browser/extensions/api/bluetooth/bluetooth_api.cc b/chrome/browser/extensions/api/bluetooth/bluetooth_api.cc index ea750a3..f36470b 100644 --- a/chrome/browser/extensions/api/bluetooth/bluetooth_api.cc +++ b/chrome/browser/extensions/api/bluetooth/bluetooth_api.cc @@ -22,10 +22,12 @@ #include "base/safe_strerror_posix.h" #include "chrome/browser/chromeos/bluetooth/bluetooth_adapter.h" #include "chrome/browser/chromeos/bluetooth/bluetooth_device.h" +#include "chrome/browser/chromeos/bluetooth/bluetooth_service_record.h" #include "chrome/browser/chromeos/bluetooth/bluetooth_socket.h" #include "chrome/browser/chromeos/bluetooth/bluetooth_utils.h" #include "chrome/browser/chromeos/extensions/bluetooth_event_router.h" #include "chromeos/dbus/bluetooth_out_of_band_client.h" +#include "chromeos/dbus/bluetooth_out_of_band_pairing_data.h" namespace { diff --git a/chrome/browser/extensions/api/bluetooth/bluetooth_apitest_chromeos.cc b/chrome/browser/extensions/api/bluetooth/bluetooth_apitest_chromeos.cc index b9c0951..cf419c1 100644 --- a/chrome/browser/extensions/api/bluetooth/bluetooth_apitest_chromeos.cc +++ b/chrome/browser/extensions/api/bluetooth/bluetooth_apitest_chromeos.cc @@ -15,6 +15,7 @@ #include "chrome/browser/extensions/extension_test_message_listener.h" #include "chrome/browser/ui/browser.h" #include "chromeos/dbus/bluetooth_out_of_band_client.h" +#include "chromeos/dbus/bluetooth_out_of_band_pairing_data.h" #include "chrome/test/base/ui_test_utils.h" #include "testing/gmock/include/gmock/gmock.h" @@ -46,6 +47,10 @@ class BluetoothApiTest : public PlatformAppApiTest { false /* paired */, true /* bonded */, false /* connected */)); } + virtual void CleanUpOnMainThread() OVERRIDE { + EXPECT_CALL(*mock_adapter_, RemoveObserver(testing::_)); + } + void expectBooleanResult(bool expected, UIThreadExtensionFunction* function) { scoped_ptr<base::Value> result( @@ -108,9 +113,9 @@ static bool CallClosure(const base::Closure& callback) { } static void CallOutOfBandPairingDataCallback( - const chromeos::BluetoothAdapter::BluetoothOutOfBandPairingDataCallback& - callback, - const chromeos::BluetoothAdapter::ErrorCallback& error_callback) { + const chromeos::BluetoothAdapter::BluetoothOutOfBandPairingDataCallback& + callback, + const chromeos::BluetoothAdapter::ErrorCallback& error_callback) { callback.Run(GetOutOfBandPairingData()); } diff --git a/chrome/browser/ui/webui/options/chromeos/bluetooth_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/bluetooth_options_handler.cc index b6ca46a..f69fc34 100644 --- a/chrome/browser/ui/webui/options/chromeos/bluetooth_options_handler.cc +++ b/chrome/browser/ui/webui/options/chromeos/bluetooth_options_handler.cc @@ -12,6 +12,7 @@ #include "base/utf_string_conversions.h" #include "base/values.h" #include "chrome/browser/chromeos/bluetooth/bluetooth_adapter.h" +#include "chrome/browser/chromeos/bluetooth/bluetooth_adapter_factory.h" #include "chrome/browser/chromeos/bluetooth/bluetooth_device.h" #include "content/public/browser/web_ui.h" #include "grit/chromium_strings.h" @@ -166,7 +167,7 @@ void BluetoothOptionsHandler::RegisterMessages() { } void BluetoothOptionsHandler::InitializeHandler() { - adapter_ = BluetoothAdapter::DefaultAdapter(); + adapter_ = BluetoothAdapterFactory::DefaultAdapter(); adapter_->AddObserver(this); } diff --git a/chrome/browser/ui/webui/options/chromeos/bluetooth_options_handler.h b/chrome/browser/ui/webui/options/chromeos/bluetooth_options_handler.h index f27d4c4..b98763a 100644 --- a/chrome/browser/ui/webui/options/chromeos/bluetooth_options_handler.h +++ b/chrome/browser/ui/webui/options/chromeos/bluetooth_options_handler.h @@ -10,6 +10,7 @@ #include "base/callback.h" #include "base/compiler_specific.h" #include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" #include "chrome/browser/chromeos/bluetooth/bluetooth_adapter.h" #include "chrome/browser/chromeos/bluetooth/bluetooth_device.h" #include "chrome/browser/ui/webui/options/options_ui.h" @@ -88,8 +89,7 @@ class BluetoothOptionsHandler : public ::options::OptionsPageUIHandler, // but not display, such as keyboards. The Passkey is a numeric in the // range 0-999999 and should be always presented zero-padded to six // digits. - virtual void DisplayPasskey(BluetoothDevice* device, - uint32 passkey) OVERRIDE; + virtual void DisplayPasskey(BluetoothDevice* device, uint32 passkey) OVERRIDE; // BluetoothDevice::PairingDelegate override. // @@ -102,8 +102,7 @@ class BluetoothOptionsHandler : public ::options::OptionsPageUIHandler, // such as other computers or phones. The Passkey is a numeric in the // range 0-999999 and should be always present zero-padded to six // digits. - virtual void ConfirmPasskey(BluetoothDevice* device, - uint32 passkey) OVERRIDE; + virtual void ConfirmPasskey(BluetoothDevice* device, uint32 passkey) OVERRIDE; // BluetoothDevice::PairingDelegate override. // @@ -131,28 +130,28 @@ class BluetoothOptionsHandler : public ::options::OptionsPageUIHandler, BluetoothDevice* device) OVERRIDE; private: - // Called by BluetoothAdapter in response to a failure to change the - // power status of the adapter. + // Called by BluetoothAdapter in response to a failure to change the power + // status of the adapter. void EnableChangeError(); - // Called by BluetoothAdapter in response to a failure to set the adapter - // into discovery mode. + // Called by BluetoothAdapter in response to a failure to set the adapter into + // discovery mode. void FindDevicesError(); // Called by BluetoothAdapter in response to a failure to remove the adapter // from discovery mode. void StopDiscoveryError(); - // Called by BluetoothDevice in response to a failure to connect to the - // device with bluetooth address |address|. + // Called by BluetoothDevice in response to a failure to connect to the device + // with bluetooth address |address|. void ConnectError(const std::string& address); - // Called by BluetoothDevice in response to a failure to disconnect the - // device with bluetooth address |address|. + // Called by BluetoothDevice in response to a failure to disconnect the device + // with bluetooth address |address|. void DisconnectError(const std::string& address); - // Called by BluetoothDevice in response to a failure to disconnect and - // unpair the device with bluetooth address |address|. + // Called by BluetoothDevice in response to a failure to disconnect and unpair + // the device with bluetooth address |address|. void ForgetError(const std::string& address); // Called when the 'Enable bluetooth' checkbox value is changed. |