Home | History | Annotate | Download | only in dbus
      1 // Copyright 2014 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_gatt_descriptor_client.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/memory/weak_ptr.h"
      9 #include "base/observer_list.h"
     10 #include "dbus/bus.h"
     11 #include "dbus/object_manager.h"
     12 #include "third_party/cros_system_api/dbus/service_constants.h"
     13 
     14 namespace chromeos {
     15 
     16 // static
     17 const char BluetoothGattDescriptorClient::kNoResponseError[] =
     18     "org.chromium.Error.NoResponse";
     19 // static
     20 const char BluetoothGattDescriptorClient::kUnknownDescriptorError[] =
     21     "org.chromium.Error.UnknownDescriptor";
     22 
     23 BluetoothGattDescriptorClient::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_gatt_descriptor::kUUIDProperty, &uuid);
     29   RegisterProperty(bluetooth_gatt_descriptor::kCharacteristicProperty,
     30                    &characteristic);
     31 }
     32 
     33 BluetoothGattDescriptorClient::Properties::~Properties() {
     34 }
     35 
     36 // The BluetoothGattDescriptorClient implementation used in production.
     37 class BluetoothGattDescriptorClientImpl
     38     : public BluetoothGattDescriptorClient,
     39       public dbus::ObjectManager::Interface {
     40  public:
     41   BluetoothGattDescriptorClientImpl()
     42       : object_manager_(NULL),
     43         weak_ptr_factory_(this) {
     44   }
     45 
     46   virtual ~BluetoothGattDescriptorClientImpl() {
     47     object_manager_->UnregisterInterface(
     48         bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface);
     49   }
     50 
     51   // BluetoothGattDescriptorClientImpl override.
     52   virtual void AddObserver(
     53       BluetoothGattDescriptorClient::Observer* observer) OVERRIDE {
     54     DCHECK(observer);
     55     observers_.AddObserver(observer);
     56   }
     57 
     58   // BluetoothGattDescriptorClientImpl override.
     59   virtual void RemoveObserver(
     60       BluetoothGattDescriptorClient::Observer* observer) OVERRIDE {
     61     DCHECK(observer);
     62     observers_.RemoveObserver(observer);
     63   }
     64 
     65   // BluetoothGattDescriptorClientImpl override.
     66   virtual std::vector<dbus::ObjectPath> GetDescriptors() OVERRIDE {
     67     DCHECK(object_manager_);
     68     return object_manager_->GetObjectsWithInterface(
     69         bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface);
     70   }
     71 
     72   // BluetoothGattDescriptorClientImpl override.
     73   virtual Properties* GetProperties(
     74       const dbus::ObjectPath& object_path) OVERRIDE {
     75     DCHECK(object_manager_);
     76     return static_cast<Properties*>(
     77         object_manager_->GetProperties(
     78             object_path,
     79             bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface));
     80   }
     81 
     82   // BluetoothGattDescriptorClientImpl override.
     83   virtual void ReadValue(const dbus::ObjectPath& object_path,
     84                          const ValueCallback& callback,
     85                          const ErrorCallback& error_callback) OVERRIDE {
     86     dbus::ObjectProxy* object_proxy =
     87         object_manager_->GetObjectProxy(object_path);
     88     if (!object_proxy) {
     89       error_callback.Run(kUnknownDescriptorError, "");
     90       return;
     91     }
     92 
     93     dbus::MethodCall method_call(
     94         bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface,
     95         bluetooth_gatt_descriptor::kReadValue);
     96 
     97     object_proxy->CallMethodWithErrorCallback(
     98         &method_call,
     99         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    100         base::Bind(&BluetoothGattDescriptorClientImpl::OnValueSuccess,
    101                    weak_ptr_factory_.GetWeakPtr(),
    102                    callback),
    103         base::Bind(&BluetoothGattDescriptorClientImpl::OnError,
    104                    weak_ptr_factory_.GetWeakPtr(),
    105                    error_callback));
    106   }
    107 
    108   // BluetoothGattDescriptorClientImpl override.
    109   virtual void WriteValue(const dbus::ObjectPath& object_path,
    110                           const std::vector<uint8>& value,
    111                           const base::Closure& callback,
    112                           const ErrorCallback& error_callback) OVERRIDE {
    113     dbus::ObjectProxy* object_proxy =
    114         object_manager_->GetObjectProxy(object_path);
    115     if (!object_proxy) {
    116       error_callback.Run(kUnknownDescriptorError, "");
    117       return;
    118     }
    119 
    120     dbus::MethodCall method_call(
    121         bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface,
    122         bluetooth_gatt_descriptor::kWriteValue);
    123     dbus::MessageWriter writer(&method_call);
    124     writer.AppendArrayOfBytes(value.data(), value.size());
    125 
    126     object_proxy->CallMethodWithErrorCallback(
    127         &method_call,
    128         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    129         base::Bind(&BluetoothGattDescriptorClientImpl::OnSuccess,
    130                    weak_ptr_factory_.GetWeakPtr(),
    131                    callback),
    132         base::Bind(&BluetoothGattDescriptorClientImpl::OnError,
    133                    weak_ptr_factory_.GetWeakPtr(),
    134                    error_callback));
    135   }
    136 
    137   // dbus::ObjectManager::Interface override.
    138   virtual dbus::PropertySet* CreateProperties(
    139       dbus::ObjectProxy *object_proxy,
    140       const dbus::ObjectPath& object_path,
    141       const std::string& interface_name) OVERRIDE {
    142     Properties* properties = new Properties(
    143         object_proxy,
    144         interface_name,
    145         base::Bind(&BluetoothGattDescriptorClientImpl::OnPropertyChanged,
    146                    weak_ptr_factory_.GetWeakPtr(),
    147                    object_path));
    148     return static_cast<dbus::PropertySet*>(properties);
    149   }
    150 
    151   // dbus::ObjectManager::Interface override.
    152   virtual void ObjectAdded(const dbus::ObjectPath& object_path,
    153                            const std::string& interface_name) OVERRIDE {
    154     VLOG(2) << "Remote GATT descriptor added: " << object_path.value();
    155     FOR_EACH_OBSERVER(BluetoothGattDescriptorClient::Observer, observers_,
    156                       GattDescriptorAdded(object_path));
    157   }
    158 
    159   // dbus::ObjectManager::Interface override.
    160   virtual void ObjectRemoved(const dbus::ObjectPath& object_path,
    161                              const std::string& interface_name) OVERRIDE {
    162     VLOG(2) << "Remote GATT descriptor removed: " << object_path.value();
    163     FOR_EACH_OBSERVER(BluetoothGattDescriptorClient::Observer, observers_,
    164                       GattDescriptorRemoved(object_path));
    165   }
    166 
    167  protected:
    168   // chromeos::DBusClient override.
    169   virtual void Init(dbus::Bus* bus) OVERRIDE {
    170     object_manager_ = bus->GetObjectManager(
    171         bluetooth_object_manager::kBluetoothObjectManagerServiceName,
    172         dbus::ObjectPath(
    173             bluetooth_object_manager::kBluetoothObjectManagerServicePath));
    174     object_manager_->RegisterInterface(
    175         bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface,
    176         this);
    177   }
    178 
    179  private:
    180   // Called by dbus::PropertySet when a property value is changed, either by
    181   // result of a signal or response to a GetAll() or Get() call. Informs
    182   // observers.
    183   virtual void OnPropertyChanged(const dbus::ObjectPath& object_path,
    184                                  const std::string& property_name) {
    185     VLOG(2) << "Remote GATT descriptor property changed: "
    186             << object_path.value() << ": " << property_name;
    187     FOR_EACH_OBSERVER(BluetoothGattDescriptorClient::Observer, observers_,
    188                       GattDescriptorPropertyChanged(object_path,
    189                                                     property_name));
    190   }
    191 
    192   // Called when a response for a successful method call is received.
    193   void OnSuccess(const base::Closure& callback, dbus::Response* response) {
    194     DCHECK(response);
    195     callback.Run();
    196   }
    197 
    198   // Called when a descriptor value response for a successful method call is
    199   // received.
    200   void OnValueSuccess(const ValueCallback& callback, dbus::Response* response) {
    201     DCHECK(response);
    202     dbus::MessageReader reader(response);
    203 
    204     const uint8* bytes = NULL;
    205     size_t length = 0;
    206 
    207     if (!reader.PopArrayOfBytes(&bytes, &length))
    208       VLOG(2) << "Error reading array of bytes in ValueCallback";
    209 
    210     std::vector<uint8> value;
    211 
    212     if (bytes)
    213       value.assign(bytes, bytes + length);
    214 
    215     callback.Run(value);
    216   }
    217 
    218   // Called when a response for a failed method call is received.
    219   void OnError(const ErrorCallback& error_callback,
    220                dbus::ErrorResponse* response) {
    221     // Error response has optional error message argument.
    222     std::string error_name;
    223     std::string error_message;
    224     if (response) {
    225       dbus::MessageReader reader(response);
    226       error_name = response->GetErrorName();
    227       reader.PopString(&error_message);
    228     } else {
    229       error_name = kNoResponseError;
    230       error_message = "";
    231     }
    232     error_callback.Run(error_name, error_message);
    233   }
    234 
    235   dbus::ObjectManager* object_manager_;
    236 
    237   // List of observers interested in event notifications from us.
    238   ObserverList<BluetoothGattDescriptorClient::Observer> observers_;
    239 
    240   // Weak pointer factory for generating 'this' pointers that might live longer
    241   // than we do.
    242   // Note: This should remain the last member so it'll be destroyed and
    243   // invalidate its weak pointers before any other members are destroyed.
    244   base::WeakPtrFactory<BluetoothGattDescriptorClientImpl> weak_ptr_factory_;
    245 
    246   DISALLOW_COPY_AND_ASSIGN(BluetoothGattDescriptorClientImpl);
    247 };
    248 
    249 BluetoothGattDescriptorClient::BluetoothGattDescriptorClient() {
    250 }
    251 
    252 BluetoothGattDescriptorClient::~BluetoothGattDescriptorClient() {
    253 }
    254 
    255 // static
    256 BluetoothGattDescriptorClient* BluetoothGattDescriptorClient::Create() {
    257   return new BluetoothGattDescriptorClientImpl();
    258 }
    259 
    260 }  // namespace chromeos
    261