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 "chromeos/dbus/fake_bluetooth_adapter_client.h"
     10 #include "dbus/bus.h"
     11 #include "dbus/message.h"
     12 #include "dbus/object_manager.h"
     13 #include "dbus/object_path.h"
     14 #include "dbus/object_proxy.h"
     15 #include "third_party/cros_system_api/dbus/service_constants.h"
     16 
     17 namespace chromeos {
     18 
     19 const char BluetoothAdapterClient::kNoResponseError[] =
     20     "org.chromium.Error.NoResponse";
     21 const char BluetoothAdapterClient::kUnknownAdapterError[] =
     22     "org.chromium.Error.UnknownAdapter";
     23 
     24 BluetoothAdapterClient::Properties::Properties(
     25     dbus::ObjectProxy* object_proxy,
     26     const std::string& interface_name,
     27     const PropertyChangedCallback& callback)
     28     : dbus::PropertySet(object_proxy, interface_name, callback) {
     29   RegisterProperty(bluetooth_adapter::kAddressProperty, &address);
     30   RegisterProperty(bluetooth_adapter::kNameProperty, &name);
     31   RegisterProperty(bluetooth_adapter::kAliasProperty, &alias);
     32   RegisterProperty(bluetooth_adapter::kClassProperty, &bluetooth_class);
     33   RegisterProperty(bluetooth_adapter::kPoweredProperty, &powered);
     34   RegisterProperty(bluetooth_adapter::kDiscoverableProperty, &discoverable);
     35   RegisterProperty(bluetooth_adapter::kPairableProperty, &pairable);
     36   RegisterProperty(bluetooth_adapter::kPairableTimeoutProperty,
     37                    &pairable_timeout);
     38   RegisterProperty(bluetooth_adapter::kDiscoverableTimeoutProperty,
     39                    &discoverable_timeout);
     40   RegisterProperty(bluetooth_adapter::kDiscoveringProperty, &discovering);
     41   RegisterProperty(bluetooth_adapter::kUUIDsProperty, &uuids);
     42   RegisterProperty(bluetooth_adapter::kModaliasProperty, &modalias);
     43 }
     44 
     45 BluetoothAdapterClient::Properties::~Properties() {
     46 }
     47 
     48 
     49 // The BluetoothAdapterClient implementation used in production.
     50 class BluetoothAdapterClientImpl
     51     : public BluetoothAdapterClient,
     52       public dbus::ObjectManager::Interface {
     53  public:
     54   explicit BluetoothAdapterClientImpl(dbus::Bus* bus)
     55       : bus_(bus),
     56         weak_ptr_factory_(this) {
     57     object_manager_ = bus_->GetObjectManager(
     58         bluetooth_object_manager::kBluetoothObjectManagerServiceName,
     59         dbus::ObjectPath(
     60             bluetooth_object_manager::kBluetoothObjectManagerServicePath));
     61     object_manager_->RegisterInterface(
     62         bluetooth_adapter::kBluetoothAdapterInterface, this);
     63   }
     64 
     65   virtual ~BluetoothAdapterClientImpl() {
     66     object_manager_->UnregisterInterface(
     67         bluetooth_adapter::kBluetoothAdapterInterface);
     68   }
     69 
     70   // BluetoothAdapterClient override.
     71   virtual void AddObserver(BluetoothAdapterClient::Observer* observer)
     72       OVERRIDE {
     73     DCHECK(observer);
     74     observers_.AddObserver(observer);
     75   }
     76 
     77   // BluetoothAdapterClient override.
     78   virtual void RemoveObserver(BluetoothAdapterClient::Observer* observer)
     79       OVERRIDE {
     80     DCHECK(observer);
     81     observers_.RemoveObserver(observer);
     82   }
     83 
     84   // Returns the list of adapter object paths known to the system.
     85   virtual std::vector<dbus::ObjectPath> GetAdapters() OVERRIDE {
     86     return object_manager_->GetObjectsWithInterface(
     87         bluetooth_adapter::kBluetoothAdapterInterface);
     88   }
     89 
     90   // dbus::ObjectManager::Interface override.
     91   virtual dbus::PropertySet* CreateProperties(
     92       dbus::ObjectProxy* object_proxy,
     93       const dbus::ObjectPath& object_path,
     94       const std::string& interface_name) OVERRIDE {
     95     Properties* properties = new Properties(
     96         object_proxy,
     97         interface_name,
     98         base::Bind(&BluetoothAdapterClientImpl::OnPropertyChanged,
     99                    weak_ptr_factory_.GetWeakPtr(),
    100                    object_path));
    101     return static_cast<dbus::PropertySet*>(properties);
    102   }
    103 
    104   // BluetoothAdapterClient override.
    105   virtual Properties* GetProperties(const dbus::ObjectPath& object_path)
    106       OVERRIDE {
    107     return static_cast<Properties*>(
    108         object_manager_->GetProperties(
    109             object_path,
    110             bluetooth_adapter::kBluetoothAdapterInterface));
    111   }
    112 
    113   // BluetoothAdapterClient override.
    114   virtual void StartDiscovery(const dbus::ObjectPath& object_path,
    115                               const base::Closure& callback,
    116                               const ErrorCallback& error_callback) OVERRIDE {
    117     dbus::MethodCall method_call(
    118         bluetooth_adapter::kBluetoothAdapterInterface,
    119         bluetooth_adapter::kStartDiscovery);
    120 
    121     dbus::ObjectProxy* object_proxy =
    122         object_manager_->GetObjectProxy(object_path);
    123     if (!object_proxy) {
    124       error_callback.Run(kUnknownAdapterError, "");
    125       return;
    126     }
    127 
    128     object_proxy->CallMethodWithErrorCallback(
    129         &method_call,
    130         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    131         base::Bind(&BluetoothAdapterClientImpl::OnSuccess,
    132                    weak_ptr_factory_.GetWeakPtr(), callback),
    133         base::Bind(&BluetoothAdapterClientImpl::OnError,
    134                    weak_ptr_factory_.GetWeakPtr(), error_callback));
    135   }
    136 
    137   // BluetoothAdapterClient override.
    138   virtual void StopDiscovery(const dbus::ObjectPath& object_path,
    139                              const base::Closure& callback,
    140                              const ErrorCallback& error_callback) OVERRIDE {
    141     dbus::MethodCall method_call(
    142         bluetooth_adapter::kBluetoothAdapterInterface,
    143         bluetooth_adapter::kStopDiscovery);
    144 
    145     dbus::ObjectProxy* object_proxy =
    146         object_manager_->GetObjectProxy(object_path);
    147     if (!object_proxy) {
    148       error_callback.Run(kUnknownAdapterError, "");
    149       return;
    150     }
    151 
    152     object_proxy->CallMethodWithErrorCallback(
    153         &method_call,
    154         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    155         base::Bind(&BluetoothAdapterClientImpl::OnSuccess,
    156                    weak_ptr_factory_.GetWeakPtr(), callback),
    157         base::Bind(&BluetoothAdapterClientImpl::OnError,
    158                    weak_ptr_factory_.GetWeakPtr(), error_callback));
    159   }
    160 
    161   // BluetoothAdapterClient override.
    162   virtual void RemoveDevice(const dbus::ObjectPath& object_path,
    163                             const dbus::ObjectPath& device_path,
    164                             const base::Closure& callback,
    165                             const ErrorCallback& error_callback) OVERRIDE {
    166     dbus::MethodCall method_call(
    167         bluetooth_adapter::kBluetoothAdapterInterface,
    168         bluetooth_adapter::kRemoveDevice);
    169 
    170     dbus::MessageWriter writer(&method_call);
    171     writer.AppendObjectPath(device_path);
    172 
    173     dbus::ObjectProxy* object_proxy =
    174         object_manager_->GetObjectProxy(object_path);
    175     if (!object_proxy) {
    176       error_callback.Run(kUnknownAdapterError, "");
    177       return;
    178     }
    179 
    180     object_proxy->CallMethodWithErrorCallback(
    181         &method_call,
    182         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    183         base::Bind(&BluetoothAdapterClientImpl::OnSuccess,
    184                    weak_ptr_factory_.GetWeakPtr(), callback),
    185         base::Bind(&BluetoothAdapterClientImpl::OnError,
    186                    weak_ptr_factory_.GetWeakPtr(), error_callback));
    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::Bus* bus_;
    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     DBusClientImplementationType type,
    263     dbus::Bus* bus) {
    264   if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
    265     return new BluetoothAdapterClientImpl(bus);
    266   DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type);
    267   return new FakeBluetoothAdapterClient();
    268 }
    269 
    270 }  // namespace chromeos
    271