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()
     54       : object_manager_(NULL), weak_ptr_factory_(this) {}
     55 
     56   virtual ~BluetoothAdapterClientImpl() {
     57     object_manager_->UnregisterInterface(
     58         bluetooth_adapter::kBluetoothAdapterInterface);
     59   }
     60 
     61   // BluetoothAdapterClient override.
     62   virtual void AddObserver(BluetoothAdapterClient::Observer* observer)
     63       OVERRIDE {
     64     DCHECK(observer);
     65     observers_.AddObserver(observer);
     66   }
     67 
     68   // BluetoothAdapterClient override.
     69   virtual void RemoveObserver(BluetoothAdapterClient::Observer* observer)
     70       OVERRIDE {
     71     DCHECK(observer);
     72     observers_.RemoveObserver(observer);
     73   }
     74 
     75   // Returns the list of adapter object paths known to the system.
     76   virtual std::vector<dbus::ObjectPath> GetAdapters() OVERRIDE {
     77     return object_manager_->GetObjectsWithInterface(
     78         bluetooth_adapter::kBluetoothAdapterInterface);
     79   }
     80 
     81   // dbus::ObjectManager::Interface override.
     82   virtual dbus::PropertySet* CreateProperties(
     83       dbus::ObjectProxy* object_proxy,
     84       const dbus::ObjectPath& object_path,
     85       const std::string& interface_name) OVERRIDE {
     86     Properties* properties = new Properties(
     87         object_proxy,
     88         interface_name,
     89         base::Bind(&BluetoothAdapterClientImpl::OnPropertyChanged,
     90                    weak_ptr_factory_.GetWeakPtr(),
     91                    object_path));
     92     return static_cast<dbus::PropertySet*>(properties);
     93   }
     94 
     95   // BluetoothAdapterClient override.
     96   virtual Properties* GetProperties(const dbus::ObjectPath& object_path)
     97       OVERRIDE {
     98     return static_cast<Properties*>(
     99         object_manager_->GetProperties(
    100             object_path,
    101             bluetooth_adapter::kBluetoothAdapterInterface));
    102   }
    103 
    104   // BluetoothAdapterClient override.
    105   virtual void StartDiscovery(const dbus::ObjectPath& object_path,
    106                               const base::Closure& callback,
    107                               const ErrorCallback& error_callback) OVERRIDE {
    108     dbus::MethodCall method_call(
    109         bluetooth_adapter::kBluetoothAdapterInterface,
    110         bluetooth_adapter::kStartDiscovery);
    111 
    112     dbus::ObjectProxy* object_proxy =
    113         object_manager_->GetObjectProxy(object_path);
    114     if (!object_proxy) {
    115       error_callback.Run(kUnknownAdapterError, "");
    116       return;
    117     }
    118 
    119     object_proxy->CallMethodWithErrorCallback(
    120         &method_call,
    121         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    122         base::Bind(&BluetoothAdapterClientImpl::OnSuccess,
    123                    weak_ptr_factory_.GetWeakPtr(), callback),
    124         base::Bind(&BluetoothAdapterClientImpl::OnError,
    125                    weak_ptr_factory_.GetWeakPtr(), error_callback));
    126   }
    127 
    128   // BluetoothAdapterClient override.
    129   virtual void StopDiscovery(const dbus::ObjectPath& object_path,
    130                              const base::Closure& callback,
    131                              const ErrorCallback& error_callback) OVERRIDE {
    132     dbus::MethodCall method_call(
    133         bluetooth_adapter::kBluetoothAdapterInterface,
    134         bluetooth_adapter::kStopDiscovery);
    135 
    136     dbus::ObjectProxy* object_proxy =
    137         object_manager_->GetObjectProxy(object_path);
    138     if (!object_proxy) {
    139       error_callback.Run(kUnknownAdapterError, "");
    140       return;
    141     }
    142 
    143     object_proxy->CallMethodWithErrorCallback(
    144         &method_call,
    145         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    146         base::Bind(&BluetoothAdapterClientImpl::OnSuccess,
    147                    weak_ptr_factory_.GetWeakPtr(), callback),
    148         base::Bind(&BluetoothAdapterClientImpl::OnError,
    149                    weak_ptr_factory_.GetWeakPtr(), error_callback));
    150   }
    151 
    152   // BluetoothAdapterClient override.
    153   virtual void RemoveDevice(const dbus::ObjectPath& object_path,
    154                             const dbus::ObjectPath& device_path,
    155                             const base::Closure& callback,
    156                             const ErrorCallback& error_callback) OVERRIDE {
    157     dbus::MethodCall method_call(
    158         bluetooth_adapter::kBluetoothAdapterInterface,
    159         bluetooth_adapter::kRemoveDevice);
    160 
    161     dbus::MessageWriter writer(&method_call);
    162     writer.AppendObjectPath(device_path);
    163 
    164     dbus::ObjectProxy* object_proxy =
    165         object_manager_->GetObjectProxy(object_path);
    166     if (!object_proxy) {
    167       error_callback.Run(kUnknownAdapterError, "");
    168       return;
    169     }
    170 
    171     object_proxy->CallMethodWithErrorCallback(
    172         &method_call,
    173         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    174         base::Bind(&BluetoothAdapterClientImpl::OnSuccess,
    175                    weak_ptr_factory_.GetWeakPtr(), callback),
    176         base::Bind(&BluetoothAdapterClientImpl::OnError,
    177                    weak_ptr_factory_.GetWeakPtr(), error_callback));
    178   }
    179 
    180  protected:
    181   virtual void Init(dbus::Bus* bus) OVERRIDE {
    182     object_manager_ = bus->GetObjectManager(
    183         bluetooth_object_manager::kBluetoothObjectManagerServiceName,
    184         dbus::ObjectPath(
    185             bluetooth_object_manager::kBluetoothObjectManagerServicePath));
    186     object_manager_->RegisterInterface(
    187         bluetooth_adapter::kBluetoothAdapterInterface, this);
    188   }
    189 
    190  private:
    191   // Called by dbus::ObjectManager when an object with the adapter interface
    192   // is created. Informs observers.
    193   virtual void ObjectAdded(const dbus::ObjectPath& object_path,
    194                            const std::string& interface_name) OVERRIDE {
    195     FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_,
    196                       AdapterAdded(object_path));
    197   }
    198 
    199   // Called by dbus::ObjectManager when an object with the adapter interface
    200   // is removed. Informs observers.
    201   virtual void ObjectRemoved(const dbus::ObjectPath& object_path,
    202                              const std::string& interface_name) OVERRIDE {
    203     FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_,
    204                       AdapterRemoved(object_path));
    205   }
    206 
    207   // Called by dbus::PropertySet when a property value is changed,
    208   // either by result of a signal or response to a GetAll() or Get()
    209   // call. Informs observers.
    210   void OnPropertyChanged(const dbus::ObjectPath& object_path,
    211                          const std::string& property_name) {
    212     FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_,
    213                       AdapterPropertyChanged(object_path, property_name));
    214   }
    215 
    216   // Called when a response for successful method call is received.
    217   void OnSuccess(const base::Closure& callback,
    218                  dbus::Response* response) {
    219     DCHECK(response);
    220     callback.Run();
    221   }
    222 
    223   // Called when a response for a failed method call is received.
    224   void OnError(const ErrorCallback& error_callback,
    225                dbus::ErrorResponse* response) {
    226     // Error response has optional error message argument.
    227     std::string error_name;
    228     std::string error_message;
    229     if (response) {
    230       dbus::MessageReader reader(response);
    231       error_name = response->GetErrorName();
    232       reader.PopString(&error_message);
    233     } else {
    234       error_name = kNoResponseError;
    235       error_message = "";
    236     }
    237     error_callback.Run(error_name, error_message);
    238   }
    239 
    240   dbus::ObjectManager* object_manager_;
    241 
    242   // List of observers interested in event notifications from us.
    243   ObserverList<BluetoothAdapterClient::Observer> observers_;
    244 
    245   // Weak pointer factory for generating 'this' pointers that might live longer
    246   // than we do.
    247   // Note: This should remain the last member so it'll be destroyed and
    248   // invalidate its weak pointers before any other members are destroyed.
    249   base::WeakPtrFactory<BluetoothAdapterClientImpl>
    250       weak_ptr_factory_;
    251 
    252   DISALLOW_COPY_AND_ASSIGN(BluetoothAdapterClientImpl);
    253 };
    254 
    255 BluetoothAdapterClient::BluetoothAdapterClient() {
    256 }
    257 
    258 BluetoothAdapterClient::~BluetoothAdapterClient() {
    259 }
    260 
    261 BluetoothAdapterClient* BluetoothAdapterClient::Create() {
    262   return new BluetoothAdapterClientImpl;
    263 }
    264 
    265 }  // namespace chromeos
    266