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