Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chromeos / dbus / bluetooth_gatt_characteristic_client.cc
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_characteristic_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 BluetoothGattCharacteristicClient::kNoResponseError[] =
18     "org.chromium.Error.NoResponse";
19 // static
20 const char BluetoothGattCharacteristicClient::kUnknownCharacteristicError[] =
21     "org.chromium.Error.UnknownCharacteristic";
22
23 BluetoothGattCharacteristicClient::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_characteristic::kUUIDProperty, &uuid);
29   RegisterProperty(bluetooth_gatt_characteristic::kServiceProperty, &service);
30   RegisterProperty(bluetooth_gatt_characteristic::kNotifyingProperty,
31                    &notifying);
32   RegisterProperty(bluetooth_gatt_characteristic::kFlagsProperty, &flags);
33   RegisterProperty(bluetooth_gatt_characteristic::kDescriptorsProperty,
34                    &descriptors);
35 }
36
37 BluetoothGattCharacteristicClient::Properties::~Properties() {
38 }
39
40 // The BluetoothGattCharacteristicClient implementation used in production.
41 class BluetoothGattCharacteristicClientImpl
42     : public BluetoothGattCharacteristicClient,
43       public dbus::ObjectManager::Interface {
44  public:
45   BluetoothGattCharacteristicClientImpl()
46       : object_manager_(NULL),
47         weak_ptr_factory_(this) {
48   }
49
50   virtual ~BluetoothGattCharacteristicClientImpl() {
51     object_manager_->UnregisterInterface(
52         bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface);
53   }
54
55   // BluetoothGattCharacteristicClient override.
56   virtual void AddObserver(
57       BluetoothGattCharacteristicClient::Observer* observer) OVERRIDE {
58     DCHECK(observer);
59     observers_.AddObserver(observer);
60   }
61
62   // BluetoothGattCharacteristicClient override.
63   virtual void RemoveObserver(
64       BluetoothGattCharacteristicClient::Observer* observer) OVERRIDE {
65     DCHECK(observer);
66     observers_.RemoveObserver(observer);
67   }
68
69   // BluetoothGattCharacteristicClient override.
70   virtual std::vector<dbus::ObjectPath> GetCharacteristics() OVERRIDE {
71     DCHECK(object_manager_);
72     return object_manager_->GetObjectsWithInterface(
73         bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface);
74   }
75
76   // BluetoothGattCharacteristicClient override.
77   virtual Properties* GetProperties(
78       const dbus::ObjectPath& object_path) OVERRIDE {
79     DCHECK(object_manager_);
80     return static_cast<Properties*>(
81         object_manager_->GetProperties(
82             object_path,
83             bluetooth_gatt_characteristic::
84                 kBluetoothGattCharacteristicInterface));
85   }
86
87   // BluetoothGattCharacteristicClient override.
88   virtual void ReadValue(const dbus::ObjectPath& object_path,
89                          const ValueCallback& callback,
90                          const ErrorCallback& error_callback) OVERRIDE {
91     dbus::ObjectProxy* object_proxy =
92         object_manager_->GetObjectProxy(object_path);
93     if (!object_proxy) {
94       error_callback.Run(kUnknownCharacteristicError, "");
95       return;
96     }
97
98     dbus::MethodCall method_call(
99         bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface,
100         bluetooth_gatt_characteristic::kReadValue);
101
102     object_proxy->CallMethodWithErrorCallback(
103         &method_call,
104         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
105         base::Bind(&BluetoothGattCharacteristicClientImpl::OnValueSuccess,
106                    weak_ptr_factory_.GetWeakPtr(),
107                    callback),
108         base::Bind(&BluetoothGattCharacteristicClientImpl::OnError,
109                    weak_ptr_factory_.GetWeakPtr(),
110                    error_callback));
111   }
112
113   // BluetoothGattCharacteristicClient override.
114   virtual void WriteValue(const dbus::ObjectPath& object_path,
115                           const std::vector<uint8>& value,
116                           const base::Closure& callback,
117                           const ErrorCallback& error_callback) OVERRIDE {
118     dbus::ObjectProxy* object_proxy =
119         object_manager_->GetObjectProxy(object_path);
120     if (!object_proxy) {
121       error_callback.Run(kUnknownCharacteristicError, "");
122       return;
123     }
124
125     dbus::MethodCall method_call(
126         bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface,
127         bluetooth_gatt_characteristic::kWriteValue);
128     dbus::MessageWriter writer(&method_call);
129     writer.AppendArrayOfBytes(value.data(), value.size());
130
131     object_proxy->CallMethodWithErrorCallback(
132         &method_call,
133         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
134         base::Bind(&BluetoothGattCharacteristicClientImpl::OnSuccess,
135                    weak_ptr_factory_.GetWeakPtr(),
136                    callback),
137         base::Bind(&BluetoothGattCharacteristicClientImpl::OnError,
138                    weak_ptr_factory_.GetWeakPtr(),
139                    error_callback));
140   }
141
142   // BluetoothGattCharacteristicClient override.
143   virtual void StartNotify(const dbus::ObjectPath& object_path,
144                            const base::Closure& callback,
145                            const ErrorCallback& error_callback) OVERRIDE {
146     dbus::ObjectProxy* object_proxy =
147         object_manager_->GetObjectProxy(object_path);
148     if (!object_proxy) {
149       error_callback.Run(kUnknownCharacteristicError, "");
150       return;
151     }
152
153     dbus::MethodCall method_call(
154         bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface,
155         bluetooth_gatt_characteristic::kStartNotify);
156
157     object_proxy->CallMethodWithErrorCallback(
158         &method_call,
159         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
160         base::Bind(&BluetoothGattCharacteristicClientImpl::OnSuccess,
161                    weak_ptr_factory_.GetWeakPtr(),
162                    callback),
163         base::Bind(&BluetoothGattCharacteristicClientImpl::OnError,
164                    weak_ptr_factory_.GetWeakPtr(),
165                    error_callback));
166   }
167
168   // BluetoothGattCharacteristicClient override.
169   virtual void StopNotify(const dbus::ObjectPath& object_path,
170                           const base::Closure& callback,
171                           const ErrorCallback& error_callback) OVERRIDE {
172     dbus::ObjectProxy* object_proxy =
173         object_manager_->GetObjectProxy(object_path);
174     if (!object_proxy) {
175       error_callback.Run(kUnknownCharacteristicError, "");
176       return;
177     }
178
179     dbus::MethodCall method_call(
180         bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface,
181         bluetooth_gatt_characteristic::kStopNotify);
182
183     object_proxy->CallMethodWithErrorCallback(
184         &method_call,
185         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
186         base::Bind(&BluetoothGattCharacteristicClientImpl::OnSuccess,
187                    weak_ptr_factory_.GetWeakPtr(),
188                    callback),
189         base::Bind(&BluetoothGattCharacteristicClientImpl::OnError,
190                    weak_ptr_factory_.GetWeakPtr(),
191                    error_callback));
192   }
193
194   // dbus::ObjectManager::Interface override.
195   virtual dbus::PropertySet* CreateProperties(
196       dbus::ObjectProxy *object_proxy,
197       const dbus::ObjectPath& object_path,
198       const std::string& interface_name) OVERRIDE {
199     Properties* properties = new Properties(
200         object_proxy,
201         interface_name,
202         base::Bind(&BluetoothGattCharacteristicClientImpl::OnPropertyChanged,
203                    weak_ptr_factory_.GetWeakPtr(),
204                    object_path));
205     return static_cast<dbus::PropertySet*>(properties);
206   }
207
208   // dbus::ObjectManager::Interface override.
209   virtual void ObjectAdded(const dbus::ObjectPath& object_path,
210                            const std::string& interface_name) OVERRIDE {
211     VLOG(2) << "Remote GATT characteristic added: " << object_path.value();
212     FOR_EACH_OBSERVER(BluetoothGattCharacteristicClient::Observer, observers_,
213                       GattCharacteristicAdded(object_path));
214
215     // Connect the "ValueUpdated" signal.
216     dbus::ObjectProxy* object_proxy =
217         object_manager_->GetObjectProxy(object_path);
218     DCHECK(object_proxy);
219
220     object_proxy->ConnectToSignal(
221         bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface,
222         bluetooth_gatt_characteristic::kValueUpdatedSignal,
223         base::Bind(&BluetoothGattCharacteristicClientImpl::ValueUpdatedReceived,
224                    weak_ptr_factory_.GetWeakPtr(),
225                    object_path),
226         base::Bind(
227             &BluetoothGattCharacteristicClientImpl::ValueUpdatedConnected,
228             weak_ptr_factory_.GetWeakPtr()));
229   }
230
231   // dbus::ObjectManager::Interface override.
232   virtual void ObjectRemoved(const dbus::ObjectPath& object_path,
233                              const std::string& interface_name) OVERRIDE {
234     VLOG(2) << "Remote GATT characteristic removed: " << object_path.value();
235     FOR_EACH_OBSERVER(BluetoothGattCharacteristicClient::Observer, observers_,
236                       GattCharacteristicRemoved(object_path));
237   }
238
239  protected:
240   // chromeos::DBusClient override.
241   virtual void Init(dbus::Bus* bus) OVERRIDE {
242     object_manager_ = bus->GetObjectManager(
243         bluetooth_object_manager::kBluetoothObjectManagerServiceName,
244         dbus::ObjectPath(
245             bluetooth_object_manager::kBluetoothObjectManagerServicePath));
246     object_manager_->RegisterInterface(
247         bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface,
248         this);
249   }
250
251  private:
252   // Called by dbus::PropertySet when a property value is changed, either by
253   // result of a signal or response to a GetAll() or Get() call. Informs
254   // observers.
255   virtual void OnPropertyChanged(const dbus::ObjectPath& object_path,
256                                  const std::string& property_name) {
257     VLOG(2) << "Remote GATT characteristic property changed: "
258             << object_path.value() << ": " << property_name;
259     FOR_EACH_OBSERVER(BluetoothGattCharacteristicClient::Observer, observers_,
260                       GattCharacteristicPropertyChanged(object_path,
261                                                         property_name));
262   }
263
264   // Called by dbus:: when a "ValueUpdated" signal is received.
265   void ValueUpdatedReceived(const dbus::ObjectPath& object_path,
266                             dbus::Signal* signal) {
267     DCHECK(signal);
268     const uint8* bytes = NULL;
269     size_t length = 0;
270     dbus::MessageReader reader(signal);
271     if (!reader.PopArrayOfBytes(&bytes, &length)) {
272       LOG(WARNING) << "ValueUpdated signal has incorrect parameters: "
273                    << signal->ToString();
274       return;
275     }
276
277     std::vector<uint8> value;
278     if (bytes)
279       value.assign(bytes, bytes + length);
280
281     FOR_EACH_OBSERVER(BluetoothGattCharacteristicClient::Observer,
282                       observers_,
283                       GattCharacteristicValueUpdated(object_path, value));
284   }
285
286   // Called by dbus:: when the "ValueUpdated" signal is initially connected.
287   void ValueUpdatedConnected(const std::string& interface_name,
288                              const std::string& signal_name,
289                              bool success) {
290     LOG_IF(WARNING, !success) << "Failed to connect to the ValueUpdated signal";
291   }
292
293   // Called when a response for successful method call is received.
294   void OnSuccess(const base::Closure& callback, dbus::Response* response) {
295     DCHECK(response);
296     callback.Run();
297   }
298
299   // Called when a characteristic value response for a successful method call
300   // is received.
301   void OnValueSuccess(const ValueCallback& callback, dbus::Response* response) {
302     DCHECK(response);
303     dbus::MessageReader reader(response);
304
305     const uint8* bytes = NULL;
306     size_t length = 0;
307
308     if (!reader.PopArrayOfBytes(&bytes, &length))
309       VLOG(2) << "Error reading array of bytes in ValueCallback";
310
311     std::vector<uint8> value;
312
313     if (bytes)
314       value.assign(bytes, bytes + length);
315
316     callback.Run(value);
317   }
318
319   // Called when a response for a failed method call is received.
320   void OnError(const ErrorCallback& error_callback,
321                dbus::ErrorResponse* response) {
322     // Error response has optional error message argument.
323     std::string error_name;
324     std::string error_message;
325     if (response) {
326       dbus::MessageReader reader(response);
327       error_name = response->GetErrorName();
328       reader.PopString(&error_message);
329     } else {
330       error_name = kNoResponseError;
331       error_message = "";
332     }
333     error_callback.Run(error_name, error_message);
334   }
335
336   dbus::ObjectManager* object_manager_;
337
338   // List of observers interested in event notifications from us.
339   ObserverList<BluetoothGattCharacteristicClient::Observer> observers_;
340
341   // Weak pointer factory for generating 'this' pointers that might live longer
342   // than we do.
343   // Note: This should remain the last member so it'll be destroyed and
344   // invalidate its weak pointers before any other members are destroyed.
345   base::WeakPtrFactory<BluetoothGattCharacteristicClientImpl>
346       weak_ptr_factory_;
347
348   DISALLOW_COPY_AND_ASSIGN(BluetoothGattCharacteristicClientImpl);
349 };
350
351 BluetoothGattCharacteristicClient::BluetoothGattCharacteristicClient() {
352 }
353
354 BluetoothGattCharacteristicClient::~BluetoothGattCharacteristicClient() {
355 }
356
357 // static
358 BluetoothGattCharacteristicClient* BluetoothGattCharacteristicClient::Create() {
359   return new BluetoothGattCharacteristicClientImpl();
360 }
361
362 }  // namespace chromeos