OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider.h
" | 5 #include "device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider.h
" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <utility> |
8 | 9 |
9 #include "base/bind.h" | 10 #include "base/bind.h" |
10 #include "base/logging.h" | 11 #include "base/logging.h" |
11 #include "base/macros.h" | 12 #include "base/macros.h" |
12 #include "base/memory/weak_ptr.h" | 13 #include "base/memory/weak_ptr.h" |
13 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" |
14 #include "base/threading/platform_thread.h" | 15 #include "base/threading/platform_thread.h" |
15 #include "dbus/exported_object.h" | 16 #include "dbus/exported_object.h" |
16 #include "dbus/message.h" | 17 #include "dbus/message.h" |
17 #include "device/bluetooth/dbus/bluez_dbus_manager.h" | 18 #include "device/bluetooth/dbus/bluez_dbus_manager.h" |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 | 135 |
135 dbus::MessageReader reader(method_call); | 136 dbus::MessageReader reader(method_call); |
136 | 137 |
137 std::string interface_name; | 138 std::string interface_name; |
138 std::string property_name; | 139 std::string property_name; |
139 if (!reader.PopString(&interface_name) || | 140 if (!reader.PopString(&interface_name) || |
140 !reader.PopString(&property_name) || reader.HasMoreData()) { | 141 !reader.PopString(&property_name) || reader.HasMoreData()) { |
141 scoped_ptr<dbus::ErrorResponse> error_response = | 142 scoped_ptr<dbus::ErrorResponse> error_response = |
142 dbus::ErrorResponse::FromMethodCall(method_call, kErrorInvalidArgs, | 143 dbus::ErrorResponse::FromMethodCall(method_call, kErrorInvalidArgs, |
143 "Expected 'ss'."); | 144 "Expected 'ss'."); |
144 response_sender.Run(error_response.Pass()); | 145 response_sender.Run(std::move(error_response)); |
145 return; | 146 return; |
146 } | 147 } |
147 | 148 |
148 // Only the GATT characteristic interface is supported. | 149 // Only the GATT characteristic interface is supported. |
149 if (interface_name != | 150 if (interface_name != |
150 bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface) { | 151 bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface) { |
151 scoped_ptr<dbus::ErrorResponse> error_response = | 152 scoped_ptr<dbus::ErrorResponse> error_response = |
152 dbus::ErrorResponse::FromMethodCall( | 153 dbus::ErrorResponse::FromMethodCall( |
153 method_call, kErrorInvalidArgs, | 154 method_call, kErrorInvalidArgs, |
154 "No such interface: '" + interface_name + "'."); | 155 "No such interface: '" + interface_name + "'."); |
155 response_sender.Run(error_response.Pass()); | 156 response_sender.Run(std::move(error_response)); |
156 return; | 157 return; |
157 } | 158 } |
158 | 159 |
159 // If getting the "Value" property, obtain the value from the delegate. | 160 // If getting the "Value" property, obtain the value from the delegate. |
160 if (property_name == bluetooth_gatt_characteristic::kValueProperty) { | 161 if (property_name == bluetooth_gatt_characteristic::kValueProperty) { |
161 DCHECK(delegate_); | 162 DCHECK(delegate_); |
162 delegate_->GetCharacteristicValue( | 163 delegate_->GetCharacteristicValue( |
163 base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnGet, | 164 base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnGet, |
164 weak_ptr_factory_.GetWeakPtr(), method_call, | 165 weak_ptr_factory_.GetWeakPtr(), method_call, |
165 response_sender), | 166 response_sender), |
(...skipping 17 matching lines...) Expand all Loading... |
183 bluetooth_gatt_characteristic::kServiceProperty) { | 184 bluetooth_gatt_characteristic::kServiceProperty) { |
184 writer.OpenVariant("o", &variant_writer); | 185 writer.OpenVariant("o", &variant_writer); |
185 variant_writer.AppendObjectPath(service_path_); | 186 variant_writer.AppendObjectPath(service_path_); |
186 writer.CloseContainer(&variant_writer); | 187 writer.CloseContainer(&variant_writer); |
187 } else { | 188 } else { |
188 response = dbus::ErrorResponse::FromMethodCall( | 189 response = dbus::ErrorResponse::FromMethodCall( |
189 method_call, kErrorInvalidArgs, | 190 method_call, kErrorInvalidArgs, |
190 "No such property: '" + property_name + "'."); | 191 "No such property: '" + property_name + "'."); |
191 } | 192 } |
192 | 193 |
193 response_sender.Run(response.Pass()); | 194 response_sender.Run(std::move(response)); |
194 } | 195 } |
195 | 196 |
196 // Called by dbus:: when the Bluetooth daemon sets a single property of the | 197 // Called by dbus:: when the Bluetooth daemon sets a single property of the |
197 // characteristic. | 198 // characteristic. |
198 void Set(dbus::MethodCall* method_call, | 199 void Set(dbus::MethodCall* method_call, |
199 dbus::ExportedObject::ResponseSender response_sender) { | 200 dbus::ExportedObject::ResponseSender response_sender) { |
200 VLOG(2) << "BluetoothGattCharacteristicServiceProvider::Set: " | 201 VLOG(2) << "BluetoothGattCharacteristicServiceProvider::Set: " |
201 << object_path_.value(); | 202 << object_path_.value(); |
202 DCHECK(OnOriginThread()); | 203 DCHECK(OnOriginThread()); |
203 | 204 |
204 dbus::MessageReader reader(method_call); | 205 dbus::MessageReader reader(method_call); |
205 | 206 |
206 std::string interface_name; | 207 std::string interface_name; |
207 std::string property_name; | 208 std::string property_name; |
208 dbus::MessageReader variant_reader(NULL); | 209 dbus::MessageReader variant_reader(NULL); |
209 if (!reader.PopString(&interface_name) || | 210 if (!reader.PopString(&interface_name) || |
210 !reader.PopString(&property_name) || | 211 !reader.PopString(&property_name) || |
211 !reader.PopVariant(&variant_reader) || reader.HasMoreData()) { | 212 !reader.PopVariant(&variant_reader) || reader.HasMoreData()) { |
212 scoped_ptr<dbus::ErrorResponse> error_response = | 213 scoped_ptr<dbus::ErrorResponse> error_response = |
213 dbus::ErrorResponse::FromMethodCall(method_call, kErrorInvalidArgs, | 214 dbus::ErrorResponse::FromMethodCall(method_call, kErrorInvalidArgs, |
214 "Expected 'ssv'."); | 215 "Expected 'ssv'."); |
215 response_sender.Run(error_response.Pass()); | 216 response_sender.Run(std::move(error_response)); |
216 return; | 217 return; |
217 } | 218 } |
218 | 219 |
219 // Only the GATT characteristic interface is allowed. | 220 // Only the GATT characteristic interface is allowed. |
220 if (interface_name != | 221 if (interface_name != |
221 bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface) { | 222 bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface) { |
222 scoped_ptr<dbus::ErrorResponse> error_response = | 223 scoped_ptr<dbus::ErrorResponse> error_response = |
223 dbus::ErrorResponse::FromMethodCall( | 224 dbus::ErrorResponse::FromMethodCall( |
224 method_call, kErrorInvalidArgs, | 225 method_call, kErrorInvalidArgs, |
225 "No such interface: '" + interface_name + "'."); | 226 "No such interface: '" + interface_name + "'."); |
226 response_sender.Run(error_response.Pass()); | 227 response_sender.Run(std::move(error_response)); |
227 return; | 228 return; |
228 } | 229 } |
229 | 230 |
230 // Only the "Value" property is writeable. | 231 // Only the "Value" property is writeable. |
231 if (property_name != bluetooth_gatt_characteristic::kValueProperty) { | 232 if (property_name != bluetooth_gatt_characteristic::kValueProperty) { |
232 std::string error_name; | 233 std::string error_name; |
233 std::string error_message; | 234 std::string error_message; |
234 if (property_name == bluetooth_gatt_characteristic::kUUIDProperty || | 235 if (property_name == bluetooth_gatt_characteristic::kUUIDProperty || |
235 property_name == bluetooth_gatt_characteristic::kServiceProperty) { | 236 property_name == bluetooth_gatt_characteristic::kServiceProperty) { |
236 error_name = kErrorPropertyReadOnly; | 237 error_name = kErrorPropertyReadOnly; |
237 error_message = "Read-only property: '" + property_name + "'."; | 238 error_message = "Read-only property: '" + property_name + "'."; |
238 } else { | 239 } else { |
239 error_name = kErrorInvalidArgs; | 240 error_name = kErrorInvalidArgs; |
240 error_message = "No such property: '" + property_name + "'."; | 241 error_message = "No such property: '" + property_name + "'."; |
241 } | 242 } |
242 scoped_ptr<dbus::ErrorResponse> error_response = | 243 scoped_ptr<dbus::ErrorResponse> error_response = |
243 dbus::ErrorResponse::FromMethodCall(method_call, error_name, | 244 dbus::ErrorResponse::FromMethodCall(method_call, error_name, |
244 error_message); | 245 error_message); |
245 response_sender.Run(error_response.Pass()); | 246 response_sender.Run(std::move(error_response)); |
246 return; | 247 return; |
247 } | 248 } |
248 | 249 |
249 // Obtain the value. | 250 // Obtain the value. |
250 const uint8_t* bytes = NULL; | 251 const uint8_t* bytes = NULL; |
251 size_t length = 0; | 252 size_t length = 0; |
252 if (!variant_reader.PopArrayOfBytes(&bytes, &length)) { | 253 if (!variant_reader.PopArrayOfBytes(&bytes, &length)) { |
253 scoped_ptr<dbus::ErrorResponse> error_response = | 254 scoped_ptr<dbus::ErrorResponse> error_response = |
254 dbus::ErrorResponse::FromMethodCall( | 255 dbus::ErrorResponse::FromMethodCall( |
255 method_call, kErrorInvalidArgs, | 256 method_call, kErrorInvalidArgs, |
256 "Property '" + property_name + "' has type 'ay'."); | 257 "Property '" + property_name + "' has type 'ay'."); |
257 response_sender.Run(error_response.Pass()); | 258 response_sender.Run(std::move(error_response)); |
258 return; | 259 return; |
259 } | 260 } |
260 | 261 |
261 // Pass the set request onto the delegate. | 262 // Pass the set request onto the delegate. |
262 std::vector<uint8_t> value(bytes, bytes + length); | 263 std::vector<uint8_t> value(bytes, bytes + length); |
263 DCHECK(delegate_); | 264 DCHECK(delegate_); |
264 delegate_->SetCharacteristicValue( | 265 delegate_->SetCharacteristicValue( |
265 value, | 266 value, |
266 base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnSet, | 267 base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnSet, |
267 weak_ptr_factory_.GetWeakPtr(), method_call, | 268 weak_ptr_factory_.GetWeakPtr(), method_call, |
(...skipping 11 matching lines...) Expand all Loading... |
279 << object_path_.value(); | 280 << object_path_.value(); |
280 DCHECK(OnOriginThread()); | 281 DCHECK(OnOriginThread()); |
281 | 282 |
282 dbus::MessageReader reader(method_call); | 283 dbus::MessageReader reader(method_call); |
283 | 284 |
284 std::string interface_name; | 285 std::string interface_name; |
285 if (!reader.PopString(&interface_name) || reader.HasMoreData()) { | 286 if (!reader.PopString(&interface_name) || reader.HasMoreData()) { |
286 scoped_ptr<dbus::ErrorResponse> error_response = | 287 scoped_ptr<dbus::ErrorResponse> error_response = |
287 dbus::ErrorResponse::FromMethodCall(method_call, kErrorInvalidArgs, | 288 dbus::ErrorResponse::FromMethodCall(method_call, kErrorInvalidArgs, |
288 "Expected 's'."); | 289 "Expected 's'."); |
289 response_sender.Run(error_response.Pass()); | 290 response_sender.Run(std::move(error_response)); |
290 return; | 291 return; |
291 } | 292 } |
292 | 293 |
293 // Only the GATT characteristic interface is supported. | 294 // Only the GATT characteristic interface is supported. |
294 if (interface_name != | 295 if (interface_name != |
295 bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface) { | 296 bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface) { |
296 scoped_ptr<dbus::ErrorResponse> error_response = | 297 scoped_ptr<dbus::ErrorResponse> error_response = |
297 dbus::ErrorResponse::FromMethodCall( | 298 dbus::ErrorResponse::FromMethodCall( |
298 method_call, kErrorInvalidArgs, | 299 method_call, kErrorInvalidArgs, |
299 "No such interface: '" + interface_name + "'."); | 300 "No such interface: '" + interface_name + "'."); |
300 response_sender.Run(error_response.Pass()); | 301 response_sender.Run(std::move(error_response)); |
301 return; | 302 return; |
302 } | 303 } |
303 | 304 |
304 // Try to obtain the value from the delegate. We will construct the | 305 // Try to obtain the value from the delegate. We will construct the |
305 // response in the success callback. | 306 // response in the success callback. |
306 DCHECK(delegate_); | 307 DCHECK(delegate_); |
307 delegate_->GetCharacteristicValue( | 308 delegate_->GetCharacteristicValue( |
308 base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnGetAll, | 309 base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnGetAll, |
309 weak_ptr_factory_.GetWeakPtr(), method_call, | 310 weak_ptr_factory_.GetWeakPtr(), method_call, |
310 response_sender), | 311 response_sender), |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
356 bluetooth_gatt_characteristic::kValueProperty); | 357 bluetooth_gatt_characteristic::kValueProperty); |
357 dict_entry_writer.OpenVariant("ay", &variant_writer); | 358 dict_entry_writer.OpenVariant("ay", &variant_writer); |
358 variant_writer.AppendArrayOfBytes(value.data(), value.size()); | 359 variant_writer.AppendArrayOfBytes(value.data(), value.size()); |
359 dict_entry_writer.CloseContainer(&variant_writer); | 360 dict_entry_writer.CloseContainer(&variant_writer); |
360 array_writer.CloseContainer(&dict_entry_writer); | 361 array_writer.CloseContainer(&dict_entry_writer); |
361 | 362 |
362 // TODO(armansito): Process Flags & Permissions properties. | 363 // TODO(armansito): Process Flags & Permissions properties. |
363 | 364 |
364 writer.CloseContainer(&array_writer); | 365 writer.CloseContainer(&array_writer); |
365 | 366 |
366 response_sender.Run(response.Pass()); | 367 response_sender.Run(std::move(response)); |
367 } | 368 } |
368 | 369 |
369 // Called by the Delegate in response to a successful method call to get the | 370 // Called by the Delegate in response to a successful method call to get the |
370 // characteristic value. | 371 // characteristic value. |
371 void OnGet(dbus::MethodCall* method_call, | 372 void OnGet(dbus::MethodCall* method_call, |
372 dbus::ExportedObject::ResponseSender response_sender, | 373 dbus::ExportedObject::ResponseSender response_sender, |
373 const std::vector<uint8_t>& value) { | 374 const std::vector<uint8_t>& value) { |
374 VLOG(2) << "Returning characteristic value obtained from delegate."; | 375 VLOG(2) << "Returning characteristic value obtained from delegate."; |
375 scoped_ptr<dbus::Response> response = | 376 scoped_ptr<dbus::Response> response = |
376 dbus::Response::FromMethodCall(method_call); | 377 dbus::Response::FromMethodCall(method_call); |
377 dbus::MessageWriter writer(response.get()); | 378 dbus::MessageWriter writer(response.get()); |
378 dbus::MessageWriter variant_writer(NULL); | 379 dbus::MessageWriter variant_writer(NULL); |
379 | 380 |
380 writer.OpenVariant("ay", &variant_writer); | 381 writer.OpenVariant("ay", &variant_writer); |
381 variant_writer.AppendArrayOfBytes(value.data(), value.size()); | 382 variant_writer.AppendArrayOfBytes(value.data(), value.size()); |
382 writer.CloseContainer(&variant_writer); | 383 writer.CloseContainer(&variant_writer); |
383 | 384 |
384 response_sender.Run(response.Pass()); | 385 response_sender.Run(std::move(response)); |
385 } | 386 } |
386 | 387 |
387 // Called by the Delegate in response to a successful method call to set the | 388 // Called by the Delegate in response to a successful method call to set the |
388 // characteristic value. | 389 // characteristic value. |
389 void OnSet(dbus::MethodCall* method_call, | 390 void OnSet(dbus::MethodCall* method_call, |
390 dbus::ExportedObject::ResponseSender response_sender) { | 391 dbus::ExportedObject::ResponseSender response_sender) { |
391 VLOG(2) << "Successfully set characteristic value. Return success."; | 392 VLOG(2) << "Successfully set characteristic value. Return success."; |
392 response_sender.Run(dbus::Response::FromMethodCall(method_call)); | 393 response_sender.Run(dbus::Response::FromMethodCall(method_call)); |
393 } | 394 } |
394 | 395 |
395 // Called by the Delegate in response to a failed method call to get or set | 396 // Called by the Delegate in response to a failed method call to get or set |
396 // the characteristic value. | 397 // the characteristic value. |
397 void OnFailure(dbus::MethodCall* method_call, | 398 void OnFailure(dbus::MethodCall* method_call, |
398 dbus::ExportedObject::ResponseSender response_sender) { | 399 dbus::ExportedObject::ResponseSender response_sender) { |
399 VLOG(2) << "Failed to get/set characteristic value. Report error."; | 400 VLOG(2) << "Failed to get/set characteristic value. Report error."; |
400 scoped_ptr<dbus::ErrorResponse> error_response = | 401 scoped_ptr<dbus::ErrorResponse> error_response = |
401 dbus::ErrorResponse::FromMethodCall( | 402 dbus::ErrorResponse::FromMethodCall( |
402 method_call, kErrorFailed, | 403 method_call, kErrorFailed, |
403 "Failed to get/set characteristic value."); | 404 "Failed to get/set characteristic value."); |
404 response_sender.Run(error_response.Pass()); | 405 response_sender.Run(std::move(error_response)); |
405 } | 406 } |
406 | 407 |
407 // Origin thread (i.e. the UI thread in production). | 408 // Origin thread (i.e. the UI thread in production). |
408 base::PlatformThreadId origin_thread_id_; | 409 base::PlatformThreadId origin_thread_id_; |
409 | 410 |
410 // 128-bit characteristic UUID of this object. | 411 // 128-bit characteristic UUID of this object. |
411 std::string uuid_; | 412 std::string uuid_; |
412 | 413 |
413 // D-Bus bus object is exported on, not owned by this object and must | 414 // D-Bus bus object is exported on, not owned by this object and must |
414 // outlive it. | 415 // outlive it. |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
458 const dbus::ObjectPath& service_path) { | 459 const dbus::ObjectPath& service_path) { |
459 if (!bluez::BluezDBusManager::Get()->IsUsingStub()) { | 460 if (!bluez::BluezDBusManager::Get()->IsUsingStub()) { |
460 return new BluetoothGattCharacteristicServiceProviderImpl( | 461 return new BluetoothGattCharacteristicServiceProviderImpl( |
461 bus, object_path, delegate, uuid, flags, permissions, service_path); | 462 bus, object_path, delegate, uuid, flags, permissions, service_path); |
462 } | 463 } |
463 return new FakeBluetoothGattCharacteristicServiceProvider( | 464 return new FakeBluetoothGattCharacteristicServiceProvider( |
464 object_path, delegate, uuid, flags, permissions, service_path); | 465 object_path, delegate, uuid, flags, permissions, service_path); |
465 } | 466 } |
466 | 467 |
467 } // namespace bluez | 468 } // namespace bluez |
OLD | NEW |