[Extensions UI] Fix another chrome://extensions commands bug
[chromium-blink-merge.git] / chromeos / dbus / bluetooth_gatt_characteristic_client.cc
blob5e486010bb40be2603ac181a8d674ea0b293e159
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 namespace {
18 // TODO(armansito): Move this constant to cros_system_api.
19 const char kValueProperty[] = "Value";
21 } // namespace
23 // static
24 const char BluetoothGattCharacteristicClient::kNoResponseError[] =
25 "org.chromium.Error.NoResponse";
26 // static
27 const char BluetoothGattCharacteristicClient::kUnknownCharacteristicError[] =
28 "org.chromium.Error.UnknownCharacteristic";
30 BluetoothGattCharacteristicClient::Properties::Properties(
31 dbus::ObjectProxy* object_proxy,
32 const std::string& interface_name,
33 const PropertyChangedCallback& callback)
34 : dbus::PropertySet(object_proxy, interface_name, callback) {
35 RegisterProperty(bluetooth_gatt_characteristic::kUUIDProperty, &uuid);
36 RegisterProperty(bluetooth_gatt_characteristic::kServiceProperty, &service);
37 RegisterProperty(kValueProperty, &value);
38 RegisterProperty(bluetooth_gatt_characteristic::kNotifyingProperty,
39 &notifying);
40 RegisterProperty(bluetooth_gatt_characteristic::kFlagsProperty, &flags);
41 RegisterProperty(bluetooth_gatt_characteristic::kDescriptorsProperty,
42 &descriptors);
45 BluetoothGattCharacteristicClient::Properties::~Properties() {
48 // The BluetoothGattCharacteristicClient implementation used in production.
49 class BluetoothGattCharacteristicClientImpl
50 : public BluetoothGattCharacteristicClient,
51 public dbus::ObjectManager::Interface {
52 public:
53 BluetoothGattCharacteristicClientImpl()
54 : object_manager_(NULL),
55 weak_ptr_factory_(this) {
58 ~BluetoothGattCharacteristicClientImpl() override {
59 object_manager_->UnregisterInterface(
60 bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface);
63 // BluetoothGattCharacteristicClient override.
64 void AddObserver(
65 BluetoothGattCharacteristicClient::Observer* observer) override {
66 DCHECK(observer);
67 observers_.AddObserver(observer);
70 // BluetoothGattCharacteristicClient override.
71 void RemoveObserver(
72 BluetoothGattCharacteristicClient::Observer* observer) override {
73 DCHECK(observer);
74 observers_.RemoveObserver(observer);
77 // BluetoothGattCharacteristicClient override.
78 std::vector<dbus::ObjectPath> GetCharacteristics() override {
79 DCHECK(object_manager_);
80 return object_manager_->GetObjectsWithInterface(
81 bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface);
84 // BluetoothGattCharacteristicClient override.
85 Properties* GetProperties(const dbus::ObjectPath& object_path) override {
86 DCHECK(object_manager_);
87 return static_cast<Properties*>(
88 object_manager_->GetProperties(
89 object_path,
90 bluetooth_gatt_characteristic::
91 kBluetoothGattCharacteristicInterface));
94 // BluetoothGattCharacteristicClient override.
95 void ReadValue(const dbus::ObjectPath& object_path,
96 const ValueCallback& callback,
97 const ErrorCallback& error_callback) override {
98 dbus::ObjectProxy* object_proxy =
99 object_manager_->GetObjectProxy(object_path);
100 if (!object_proxy) {
101 error_callback.Run(kUnknownCharacteristicError, "");
102 return;
105 dbus::MethodCall method_call(
106 bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface,
107 bluetooth_gatt_characteristic::kReadValue);
109 object_proxy->CallMethodWithErrorCallback(
110 &method_call,
111 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
112 base::Bind(&BluetoothGattCharacteristicClientImpl::OnValueSuccess,
113 weak_ptr_factory_.GetWeakPtr(),
114 callback),
115 base::Bind(&BluetoothGattCharacteristicClientImpl::OnError,
116 weak_ptr_factory_.GetWeakPtr(),
117 error_callback));
120 // BluetoothGattCharacteristicClient override.
121 void WriteValue(const dbus::ObjectPath& object_path,
122 const std::vector<uint8>& value,
123 const base::Closure& callback,
124 const ErrorCallback& error_callback) override {
125 dbus::ObjectProxy* object_proxy =
126 object_manager_->GetObjectProxy(object_path);
127 if (!object_proxy) {
128 error_callback.Run(kUnknownCharacteristicError, "");
129 return;
132 dbus::MethodCall method_call(
133 bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface,
134 bluetooth_gatt_characteristic::kWriteValue);
135 dbus::MessageWriter writer(&method_call);
136 writer.AppendArrayOfBytes(value.data(), value.size());
138 object_proxy->CallMethodWithErrorCallback(
139 &method_call,
140 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
141 base::Bind(&BluetoothGattCharacteristicClientImpl::OnSuccess,
142 weak_ptr_factory_.GetWeakPtr(),
143 callback),
144 base::Bind(&BluetoothGattCharacteristicClientImpl::OnError,
145 weak_ptr_factory_.GetWeakPtr(),
146 error_callback));
149 // BluetoothGattCharacteristicClient override.
150 void StartNotify(const dbus::ObjectPath& object_path,
151 const base::Closure& callback,
152 const ErrorCallback& error_callback) override {
153 dbus::ObjectProxy* object_proxy =
154 object_manager_->GetObjectProxy(object_path);
155 if (!object_proxy) {
156 error_callback.Run(kUnknownCharacteristicError, "");
157 return;
160 dbus::MethodCall method_call(
161 bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface,
162 bluetooth_gatt_characteristic::kStartNotify);
164 object_proxy->CallMethodWithErrorCallback(
165 &method_call,
166 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
167 base::Bind(&BluetoothGattCharacteristicClientImpl::OnSuccess,
168 weak_ptr_factory_.GetWeakPtr(),
169 callback),
170 base::Bind(&BluetoothGattCharacteristicClientImpl::OnError,
171 weak_ptr_factory_.GetWeakPtr(),
172 error_callback));
175 // BluetoothGattCharacteristicClient override.
176 void StopNotify(const dbus::ObjectPath& object_path,
177 const base::Closure& callback,
178 const ErrorCallback& error_callback) override {
179 dbus::ObjectProxy* object_proxy =
180 object_manager_->GetObjectProxy(object_path);
181 if (!object_proxy) {
182 error_callback.Run(kUnknownCharacteristicError, "");
183 return;
186 dbus::MethodCall method_call(
187 bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface,
188 bluetooth_gatt_characteristic::kStopNotify);
190 object_proxy->CallMethodWithErrorCallback(
191 &method_call,
192 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
193 base::Bind(&BluetoothGattCharacteristicClientImpl::OnSuccess,
194 weak_ptr_factory_.GetWeakPtr(),
195 callback),
196 base::Bind(&BluetoothGattCharacteristicClientImpl::OnError,
197 weak_ptr_factory_.GetWeakPtr(),
198 error_callback));
201 // dbus::ObjectManager::Interface override.
202 dbus::PropertySet* CreateProperties(
203 dbus::ObjectProxy* object_proxy,
204 const dbus::ObjectPath& object_path,
205 const std::string& interface_name) override {
206 Properties* properties = new Properties(
207 object_proxy,
208 interface_name,
209 base::Bind(&BluetoothGattCharacteristicClientImpl::OnPropertyChanged,
210 weak_ptr_factory_.GetWeakPtr(),
211 object_path));
212 return static_cast<dbus::PropertySet*>(properties);
215 // dbus::ObjectManager::Interface override.
216 void ObjectAdded(const dbus::ObjectPath& object_path,
217 const std::string& interface_name) override {
218 VLOG(2) << "Remote GATT characteristic added: " << object_path.value();
219 FOR_EACH_OBSERVER(BluetoothGattCharacteristicClient::Observer, observers_,
220 GattCharacteristicAdded(object_path));
223 // dbus::ObjectManager::Interface override.
224 void ObjectRemoved(const dbus::ObjectPath& object_path,
225 const std::string& interface_name) override {
226 VLOG(2) << "Remote GATT characteristic removed: " << object_path.value();
227 FOR_EACH_OBSERVER(BluetoothGattCharacteristicClient::Observer, observers_,
228 GattCharacteristicRemoved(object_path));
231 protected:
232 // chromeos::DBusClient override.
233 void Init(dbus::Bus* bus) override {
234 object_manager_ = bus->GetObjectManager(
235 bluetooth_object_manager::kBluetoothObjectManagerServiceName,
236 dbus::ObjectPath(
237 bluetooth_object_manager::kBluetoothObjectManagerServicePath));
238 object_manager_->RegisterInterface(
239 bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface,
240 this);
243 private:
244 // Called by dbus::PropertySet when a property value is changed, either by
245 // result of a signal or response to a GetAll() or Get() call. Informs
246 // observers.
247 virtual void OnPropertyChanged(const dbus::ObjectPath& object_path,
248 const std::string& property_name) {
249 VLOG(2) << "Remote GATT characteristic property changed: "
250 << object_path.value() << ": " << property_name;
251 FOR_EACH_OBSERVER(BluetoothGattCharacteristicClient::Observer, observers_,
252 GattCharacteristicPropertyChanged(object_path,
253 property_name));
256 // Called when a response for successful method call is received.
257 void OnSuccess(const base::Closure& callback, dbus::Response* response) {
258 DCHECK(response);
259 callback.Run();
262 // Called when a characteristic value response for a successful method call
263 // is received.
264 void OnValueSuccess(const ValueCallback& callback, dbus::Response* response) {
265 DCHECK(response);
266 dbus::MessageReader reader(response);
268 const uint8* bytes = NULL;
269 size_t length = 0;
271 if (!reader.PopArrayOfBytes(&bytes, &length))
272 VLOG(2) << "Error reading array of bytes in ValueCallback";
274 std::vector<uint8> value;
276 if (bytes)
277 value.assign(bytes, bytes + length);
279 callback.Run(value);
282 // Called when a response for a failed method call is received.
283 void OnError(const ErrorCallback& error_callback,
284 dbus::ErrorResponse* response) {
285 // Error response has optional error message argument.
286 std::string error_name;
287 std::string error_message;
288 if (response) {
289 dbus::MessageReader reader(response);
290 error_name = response->GetErrorName();
291 reader.PopString(&error_message);
292 } else {
293 error_name = kNoResponseError;
294 error_message = "";
296 error_callback.Run(error_name, error_message);
299 dbus::ObjectManager* object_manager_;
301 // List of observers interested in event notifications from us.
302 base::ObserverList<BluetoothGattCharacteristicClient::Observer> observers_;
304 // Weak pointer factory for generating 'this' pointers that might live longer
305 // than we do.
306 // Note: This should remain the last member so it'll be destroyed and
307 // invalidate its weak pointers before any other members are destroyed.
308 base::WeakPtrFactory<BluetoothGattCharacteristicClientImpl>
309 weak_ptr_factory_;
311 DISALLOW_COPY_AND_ASSIGN(BluetoothGattCharacteristicClientImpl);
314 BluetoothGattCharacteristicClient::BluetoothGattCharacteristicClient() {
317 BluetoothGattCharacteristicClient::~BluetoothGattCharacteristicClient() {
320 // static
321 BluetoothGattCharacteristicClient* BluetoothGattCharacteristicClient::Create() {
322 return new BluetoothGattCharacteristicClientImpl();
325 } // namespace chromeos