Home | History | Annotate | Download | only in dbus
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chromeos/dbus/bluetooth_adapter_client.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/logging.h"
      9 #include "dbus/bus.h"
     10 #include "dbus/message.h"
     11 #include "dbus/object_manager.h"
     12 #include "dbus/object_path.h"
     13 #include "dbus/object_proxy.h"
     14 #include "third_party/cros_system_api/dbus/service_constants.h"
     15 
     16 namespace chromeos {
     17 
     18 const char BluetoothAdapterClient::kNoResponseError[] =
     19     "org.chromium.Error.NoResponse";
     20 const char BluetoothAdapterClient::kUnknownAdapterError[] =
     21     "org.chromium.Error.UnknownAdapter";
     22 
     23 BluetoothAdapterClient::Properties::Properties(
     24     dbus::ObjectProxy* object_proxy,
     25     const std::string& interface_name,
     26     const PropertyChangedCallback& callback)
     27     : dbus::PropertySet(object_proxy, interface_name, callback) {
     28   RegisterProperty(bluetooth_adapter::kAddressProperty, &address);
     29   RegisterProperty(bluetooth_adapter::kNameProperty, &name);
     30   RegisterProperty(bluetooth_adapter::kAliasProperty, &alias);
     31   RegisterProperty(bluetooth_adapter::kClassProperty, &bluetooth_class);
     32   RegisterProperty(bluetooth_adapter::kPoweredProperty, &powered);
     33   RegisterProperty(bluetooth_adapter::kDiscoverableProperty, &discoverable);
     34   RegisterProperty(bluetooth_adapter::kPairableProperty, &pairable);
     35   RegisterProperty(bluetooth_adapter::kPairableTimeoutProperty,
     36                    &pairable_timeout);
     37   RegisterProperty(bluetooth_adapter::kDiscoverableTimeoutProperty,
     38                    &discoverable_timeout);
     39   RegisterProperty(bluetooth_adapter::kDiscoveringProperty, &discovering);
     40   RegisterProperty(bluetooth_adapter::kUUIDsProperty, &uuids);
     41   RegisterProperty(bluetooth_adapter::kModaliasProperty, &modalias);
     42 }
     43 
     44 BluetoothAdapterClient::Properties::~Properties() {
     45 }
     46 
     47 
     48 // The BluetoothAdapterClient implementation used in production.
     49 class BluetoothAdapterClientImpl
     50     : public BluetoothAdapterClient,
     51       public dbus::ObjectManager::Interface {
     52  public:
     53   BluetoothAdapterClientImpl() : weak_ptr_factory_(this) {}
     54 
     55   virtual ~BluetoothAdapterClientImpl() {
     56     object_manager_->UnregisterInterface(
     57         bluetooth_adapter::kBluetoothAdapterInterface);
     58   }
     59 
     60   // BluetoothAdapterClient override.
     61   virtual void AddObserver(BluetoothAdapterClient::Observer* observer)
     62       OVERRIDE {
     63     DCHECK(observer);
     64     observers_.AddObserver(observer);
     65   }
     66 
     67   // BluetoothAdapterClient override.
     68   virtual void RemoveObserver(BluetoothAdapterClient::Observer* observer)
     69       OVERRIDE {
     70     DCHECK(observer);
     71     observers_.RemoveObserver(observer);
     72   }
     73 
     74   // Returns the list of adapter object paths known to the system.
     75   virtual std::vector<dbus::ObjectPath> GetAdapters() OVERRIDE {
     76     return object_manager_->GetObjectsWithInterface(
     77         bluetooth_adapter::kBluetoothAdapterInterface);
     78   }
     79 
     80   // dbus::ObjectManager::Interface override.
     81   virtual dbus::PropertySet* CreateProperties(
     82       dbus::ObjectProxy* object_proxy,
     83       const dbus::ObjectPath& object_path,
     84       const std::string& interface_name) OVERRIDE {
     85     Properties* properties = new Properties(
     86         object_proxy,
     87         interface_name,
     88         base::Bind(&BluetoothAdapterClientImpl::OnPropertyChanged,
     89                    weak_ptr_factory_.GetWeakPtr(),
     90                    object_path));
     91     return static_cast<dbus::PropertySet*>(properties);
     92   }
     93 
     94   // BluetoothAdapterClient override.
     95   virtual Properties* GetProperties(const dbus::ObjectPath& object_path)
     96       OVERRIDE {
     97     return static_cast<Properties*>(
     98         object_manager_->GetProperties(
     99             object_path,
    100             bluetooth_adapter::kBluetoothAdapterInterface));
    101   }
    102 
    103   // BluetoothAdapterClient override.
    104   virtual void StartDiscovery(const dbus::ObjectPath& object_path,
    105                               const base::Closure& callback,
    106                               const ErrorCallback& error_callback) OVERRIDE {
    107     dbus::MethodCall method_call(
    108         bluetooth_adapter::kBluetoothAdapterInterface,
    109         bluetooth_adapter::kStartDiscovery);
    110 
    111     dbus::ObjectProxy* object_proxy =
    112         object_manager_->GetObjectProxy(object_path);
    113     if (!object_proxy) {
    114       error_callback.Run(kUnknownAdapterError, "");
    115       return;
    116     }
    117 
    118     object_proxy->CallMethodWithErrorCallback(
    119         &method_call,
    120         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    121         base::Bind(&BluetoothAdapterClientImpl::OnSuccess,
    122                    weak_ptr_factory_.GetWeakPtr(), callback),
    123         base::Bind(&BluetoothAdapterClientImpl::OnError,
    124                    weak_ptr_factory_.GetWeakPtr(), error_callback));
    125   }
    126 
    127   // BluetoothAdapterClient override.
    128   virtual void StopDiscovery(const dbus::ObjectPath& object_path,
    129                              const base::Closure& callback,
    130                              const ErrorCallback& error_callback) OVERRIDE {
    131     dbus::MethodCall method_call(
    132         bluetooth_adapter::kBluetoothAdapterInterface,
    133         bluetooth_adapter::kStopDiscovery);
    134 
    135     dbus::ObjectProxy* object_proxy =
    136         object_manager_->GetObjectProxy(object_path);
    137     if (!object_proxy) {
    138       error_callback.Run(kUnknownAdapterError, "");
    139       return;
    140     }
    141 
    142     object_proxy->CallMethodWithErrorCallback(
    143         &method_call,
    144         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    145         base::Bind(&BluetoothAdapterClientImpl::OnSuccess,
    146                    weak_ptr_factory_.GetWeakPtr(), callback),
    147         base::Bind(&BluetoothAdapterClientImpl::OnError,
    148                    weak_ptr_factory_.GetWeakPtr(), error_callback));
    149   }
    150 
    151   // BluetoothAdapterClient override.
    152   virtual void RemoveDevice(const dbus::ObjectPath& object_path,
    153                             const dbus::ObjectPath& device_path,
    154                             const base::Closure& callback,
    155                             const ErrorCallback& error_callback) OVERRIDE {
    156     dbus::MethodCall method_call(
    157         bluetooth_adapter::kBluetoothAdapterInterface,
    158         bluetooth_adapter::kRemoveDevice);
    159 
    160     dbus::MessageWriter writer(&method_call);
    161     writer.AppendObjectPath(device_path);
    162 
    163     dbus::ObjectProxy* object_proxy =
    164         object_manager_->GetObjectProxy(object_path);
    165     if (!object_proxy) {
    166       error_callback.Run(kUnknownAdapterError, "");
    167       return;
    168     }
    169 
    170     object_proxy->CallMethodWithErrorCallback(
    171         &method_call,
    172         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    173         base::Bind(&BluetoothAdapterClientImpl::OnSuccess,
    174                    weak_ptr_factory_.GetWeakPtr(), callback),
    175         base::Bind(&BluetoothAdapterClientImpl::OnError,
    176                    weak_ptr_factory_.GetWeakPtr(), error_callback));
    177   }
    178 
    179  protected:
    180   virtual void Init(dbus::Bus* bus) OVERRIDE {
    181     object_manager_ = bus->GetObjectManager(
    182         bluetooth_object_manager::kBluetoothObjectManagerServiceName,
    183         dbus::ObjectPath(
    184             bluetooth_object_manager::kBluetoothObjectManagerServicePath));
    185     object_manager_->RegisterInterface(
    186         bluetooth_adapter::kBluetoothAdapterInterface, this);
    187   }
    188 
    189  private:
    190   // Called by dbus::ObjectManager when an object with the adapter interface
    191   // is created. Informs observers.
    192   virtual void ObjectAdded(const dbus::ObjectPath& object_path,
    193                            const std::string& interface_name) OVERRIDE {
    194     FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_,
    195                       AdapterAdded(object_path));
    196   }
    197 
    198   // Called by dbus::ObjectManager when an object with the adapter interface
    199   // is removed. Informs observers.
    200   virtual void ObjectRemoved(const dbus::ObjectPath& object_path,
    201                              const std::string& interface_name) OVERRIDE {
    202     FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_,
    203                       AdapterRemoved(object_path));
    204   }
    205 
    206   // Called by dbus::PropertySet when a property value is changed,
    207   // either by result of a signal or response to a GetAll() or Get()
    208   // call. Informs observers.
    209   void OnPropertyChanged(const dbus::ObjectPath& object_path,
    210                          const std::string& property_name) {
    211     FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_,
    212                       AdapterPropertyChanged(object_path, property_name));
    213   }
    214 
    215   // Called when a response for successful method call is received.
    216   void OnSuccess(const base::Closure& callback,
    217                  dbus::Response* response) {
    218     DCHECK(response);
    219     callback.Run();
    220   }
    221 
    222   // Called when a response for a failed method call is received.
    223   void OnError(const ErrorCallback& error_callback,
    224                dbus::ErrorResponse* response) {
    225     // Error response has optional error message argument.
    226     std::string error_name;
    227     std::string error_message;
    228     if (response) {
    229       dbus::MessageReader reader(response);
    230       error_name = response->GetErrorName();
    231       reader.PopString(&error_message);
    232     } else {
    233       error_name = kNoResponseError;
    234       error_message = "";
    235     }
    236     error_callback.Run(error_name, error_message);
    237   }
    238 
    239   dbus::ObjectManager* object_manager_;
    240 
    241   // List of observers interested in event notifications from us.
    242   ObserverList<BluetoothAdapterClient::Observer> observers_;
    243 
    244   // Weak pointer factory for generating 'this' pointers that might live longer
    245   // than we do.
    246   // Note: This should remain the last member so it'll be destroyed and
    247   // invalidate its weak pointers before any other members are destroyed.
    248   base::WeakPtrFactory<BluetoothAdapterClientImpl>
    249       weak_ptr_factory_;
    250 
    251   DISALLOW_COPY_AND_ASSIGN(BluetoothAdapterClientImpl);
    252 };
    253 
    254 BluetoothAdapterClient::BluetoothAdapterClient() {
    255 }
    256 
    257 BluetoothAdapterClient::~BluetoothAdapterClient() {
    258 }
    259 
    260 BluetoothAdapterClient* BluetoothAdapterClient::Create() {
    261   return new BluetoothAdapterClientImpl;
    262 }
    263 
    264 }  // namespace chromeos
    265