• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
Properties(dbus::ObjectProxy * object_proxy,const std::string & interface_name,const PropertyChangedCallback & callback)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 
~Properties()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:
BluetoothGattDescriptorClientImpl()41   BluetoothGattDescriptorClientImpl()
42       : object_manager_(NULL),
43         weak_ptr_factory_(this) {
44   }
45 
~BluetoothGattDescriptorClientImpl()46   virtual ~BluetoothGattDescriptorClientImpl() {
47     object_manager_->UnregisterInterface(
48         bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface);
49   }
50 
51   // BluetoothGattDescriptorClientImpl override.
AddObserver(BluetoothGattDescriptorClient::Observer * observer)52   virtual void AddObserver(
53       BluetoothGattDescriptorClient::Observer* observer) OVERRIDE {
54     DCHECK(observer);
55     observers_.AddObserver(observer);
56   }
57 
58   // BluetoothGattDescriptorClientImpl override.
RemoveObserver(BluetoothGattDescriptorClient::Observer * observer)59   virtual void RemoveObserver(
60       BluetoothGattDescriptorClient::Observer* observer) OVERRIDE {
61     DCHECK(observer);
62     observers_.RemoveObserver(observer);
63   }
64 
65   // BluetoothGattDescriptorClientImpl override.
GetDescriptors()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.
GetProperties(const dbus::ObjectPath & object_path)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.
ReadValue(const dbus::ObjectPath & object_path,const ValueCallback & callback,const ErrorCallback & error_callback)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.
WriteValue(const dbus::ObjectPath & object_path,const std::vector<uint8> & value,const base::Closure & callback,const ErrorCallback & error_callback)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.
CreateProperties(dbus::ObjectProxy * object_proxy,const dbus::ObjectPath & object_path,const std::string & interface_name)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.
ObjectAdded(const dbus::ObjectPath & object_path,const std::string & interface_name)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.
ObjectRemoved(const dbus::ObjectPath & object_path,const std::string & interface_name)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.
Init(dbus::Bus * bus)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.
OnPropertyChanged(const dbus::ObjectPath & object_path,const std::string & property_name)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.
OnSuccess(const base::Closure & callback,dbus::Response * response)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.
OnValueSuccess(const ValueCallback & callback,dbus::Response * response)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.
OnError(const ErrorCallback & error_callback,dbus::ErrorResponse * response)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 
BluetoothGattDescriptorClient()249 BluetoothGattDescriptorClient::BluetoothGattDescriptorClient() {
250 }
251 
~BluetoothGattDescriptorClient()252 BluetoothGattDescriptorClient::~BluetoothGattDescriptorClient() {
253 }
254 
255 // static
Create()256 BluetoothGattDescriptorClient* BluetoothGattDescriptorClient::Create() {
257   return new BluetoothGattDescriptorClientImpl();
258 }
259 
260 }  // namespace chromeos
261