Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / chromeos / dbus / bluetooth_gatt_characteristic_client.cc
blob45cae145d397f2b0212e7154484ef245179e4fd3
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.
5 #include "chromeos/dbus/bluetooth_gatt_characteristic_client.h"
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"
14 namespace chromeos {
16 // static
17 const char BluetoothGattCharacteristicClient::kNoResponseError[] =
18 "org.chromium.Error.NoResponse";
19 // static
20 const char BluetoothGattCharacteristicClient::kUnknownCharacteristicError[] =
21 "org.chromium.Error.UnknownCharacteristic";
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);
37 BluetoothGattCharacteristicClient::Properties::~Properties() {
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) {
50 virtual ~BluetoothGattCharacteristicClientImpl() {
51 object_manager_->UnregisterInterface(
52 bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface);
55 // BluetoothGattCharacteristicClient override.
56 virtual void AddObserver(
57 BluetoothGattCharacteristicClient::Observer* observer) OVERRIDE {
58 DCHECK(observer);
59 observers_.AddObserver(observer);
62 // BluetoothGattCharacteristicClient override.
63 virtual void RemoveObserver(
64 BluetoothGattCharacteristicClient::Observer* observer) OVERRIDE {
65 DCHECK(observer);
66 observers_.RemoveObserver(observer);
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);
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));
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;
98 dbus::MethodCall method_call(
99 bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface,
100 bluetooth_gatt_characteristic::kReadValue);
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));
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;
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());
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));
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;
153 dbus::MethodCall method_call(
154 bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface,
155 bluetooth_gatt_characteristic::kStartNotify);
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));
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;
179 dbus::MethodCall method_call(
180 bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface,
181 bluetooth_gatt_characteristic::kStopNotify);
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));
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);
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));
215 // Connect the "ValueUpdated" signal.
216 dbus::ObjectProxy* object_proxy =
217 object_manager_->GetObjectProxy(object_path);
218 DCHECK(object_proxy);
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()));
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));
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);
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));
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;
277 std::vector<uint8> value;
278 if (bytes)
279 value.assign(bytes, bytes + length);
281 FOR_EACH_OBSERVER(BluetoothGattCharacteristicClient::Observer,
282 observers_,
283 GattCharacteristicValueUpdated(object_path, value));
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";
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();
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);
305 const uint8* bytes = NULL;
306 size_t length = 0;
308 if (!reader.PopArrayOfBytes(&bytes, &length))
309 VLOG(2) << "Error reading array of bytes in ValueCallback";
311 std::vector<uint8> value;
313 if (bytes)
314 value.assign(bytes, bytes + length);
316 callback.Run(value);
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 = "";
333 error_callback.Run(error_name, error_message);
336 dbus::ObjectManager* object_manager_;
338 // List of observers interested in event notifications from us.
339 ObserverList<BluetoothGattCharacteristicClient::Observer> observers_;
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_;
348 DISALLOW_COPY_AND_ASSIGN(BluetoothGattCharacteristicClientImpl);
351 BluetoothGattCharacteristicClient::BluetoothGattCharacteristicClient() {
354 BluetoothGattCharacteristicClient::~BluetoothGattCharacteristicClient() {
357 // static
358 BluetoothGattCharacteristicClient* BluetoothGattCharacteristicClient::Create() {
359 return new BluetoothGattCharacteristicClientImpl();
362 } // namespace chromeos