bluetooth_device_client.cc 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812
  1. // Copyright 2013 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. #include "device/bluetooth/dbus/bluetooth_device_client.h"
  5. #include <memory>
  6. #include <utility>
  7. #include "base/bind.h"
  8. #include "base/logging.h"
  9. #include "base/memory/ptr_util.h"
  10. #include "base/memory/raw_ptr.h"
  11. #include "base/observer_list.h"
  12. #include "build/chromeos_buildflags.h"
  13. #include "dbus/bus.h"
  14. #include "dbus/message.h"
  15. #include "dbus/object_manager.h"
  16. #include "dbus/object_proxy.h"
  17. #include "device/bluetooth/bluez/bluetooth_service_attribute_value_bluez.h"
  18. #include "device/bluetooth/dbus/bluetooth_metrics_helper.h"
  19. #include "third_party/cros_system_api/dbus/service_constants.h"
  20. #if BUILDFLAG(IS_CHROMEOS_ASH)
  21. #include "ash/constants/ash_features.h"
  22. #endif // BUILDFLAG(IS_CHROMEOS_ASH)
  23. namespace bluez {
  24. namespace {
  25. #if BUILDFLAG(IS_CHROMEOS_ASH)
  26. // TODO(b/213229904): Remove this constant and replace with
  27. // |bluetooth_device::kDisconnectOld| once it has been uprev'd.
  28. constexpr char kDisconnectOldPlaceholder[] = "DisconnectOld";
  29. #endif // BUILDFLAG(IS_CHROMEOS_ASH)
  30. // Value returned for the the RSSI or TX power if it cannot be read.
  31. const int kUnknownPower = 127;
  32. // TODO(b/213229904): Remove this constant and replace with
  33. // |bluetooth_device::kConnectClassic| once it has been uprev'd.
  34. constexpr char kConnectClassicPlaceholder[] = "ConnectClassic";
  35. std::unique_ptr<BluetoothServiceAttributeValueBlueZ> ReadAttributeValue(
  36. dbus::MessageReader* struct_reader) {
  37. uint8_t type_val;
  38. if (!struct_reader->PopByte(&type_val))
  39. return nullptr;
  40. BluetoothServiceAttributeValueBlueZ::Type type =
  41. static_cast<BluetoothServiceAttributeValueBlueZ::Type>(type_val);
  42. uint32_t size;
  43. if (!struct_reader->PopUint32(&size))
  44. return nullptr;
  45. std::unique_ptr<base::Value> value;
  46. switch (type) {
  47. case bluez::BluetoothServiceAttributeValueBlueZ::NULLTYPE: {
  48. break;
  49. }
  50. case bluez::BluetoothServiceAttributeValueBlueZ::UINT:
  51. // Fall through.
  52. case bluez::BluetoothServiceAttributeValueBlueZ::INT: {
  53. switch (size) {
  54. // It doesn't matter what 'sign' the number is, only size.
  55. // Whenever we unpack this value, we will take the raw bits and
  56. // cast it back to the correct sign anyway.
  57. case 1:
  58. uint8_t byte;
  59. if (!struct_reader->PopVariantOfByte(&byte))
  60. return nullptr;
  61. value = std::make_unique<base::Value>(byte);
  62. break;
  63. case 2:
  64. uint16_t short_val;
  65. if (!struct_reader->PopVariantOfUint16(&short_val))
  66. return nullptr;
  67. value = std::make_unique<base::Value>(short_val);
  68. break;
  69. case 4:
  70. uint32_t val;
  71. if (!struct_reader->PopVariantOfUint32(&val))
  72. return nullptr;
  73. value = std::make_unique<base::Value>(static_cast<int32_t>(val));
  74. break;
  75. case 8:
  76. // Fall through.
  77. // BlueZ should never be sending us this size at the moment since
  78. // the Android SDP records we will create from these raw records
  79. // don't have any fields which use this size. If we ever decide to
  80. // change this, this needs to get fixed.
  81. default:
  82. NOTREACHED();
  83. }
  84. break;
  85. }
  86. case bluez::BluetoothServiceAttributeValueBlueZ::UUID:
  87. // Fall through.
  88. case bluez::BluetoothServiceAttributeValueBlueZ::STRING:
  89. // Fall through.
  90. case bluez::BluetoothServiceAttributeValueBlueZ::URL: {
  91. std::string str;
  92. if (!struct_reader->PopVariantOfString(&str))
  93. return nullptr;
  94. value = std::make_unique<base::Value>(str);
  95. break;
  96. }
  97. case bluez::BluetoothServiceAttributeValueBlueZ::BOOL: {
  98. bool b;
  99. if (!struct_reader->PopVariantOfBool(&b))
  100. return nullptr;
  101. value = std::make_unique<base::Value>(b);
  102. break;
  103. }
  104. case bluez::BluetoothServiceAttributeValueBlueZ::SEQUENCE: {
  105. dbus::MessageReader variant_reader(nullptr);
  106. if (!struct_reader->PopVariant(&variant_reader))
  107. return nullptr;
  108. dbus::MessageReader array_reader(nullptr);
  109. if (!variant_reader.PopArray(&array_reader))
  110. return nullptr;
  111. std::unique_ptr<BluetoothServiceAttributeValueBlueZ::Sequence> sequence =
  112. std::make_unique<BluetoothServiceAttributeValueBlueZ::Sequence>();
  113. while (array_reader.HasMoreData()) {
  114. dbus::MessageReader sequence_element_struct_reader(nullptr);
  115. if (!array_reader.PopStruct(&sequence_element_struct_reader))
  116. return nullptr;
  117. std::unique_ptr<BluetoothServiceAttributeValueBlueZ> attribute_value =
  118. ReadAttributeValue(&sequence_element_struct_reader);
  119. if (!attribute_value)
  120. return nullptr;
  121. sequence->emplace_back(*attribute_value);
  122. }
  123. return std::make_unique<BluetoothServiceAttributeValueBlueZ>(
  124. std::move(sequence));
  125. }
  126. }
  127. return std::make_unique<BluetoothServiceAttributeValueBlueZ>(
  128. type, size, std::move(value));
  129. }
  130. std::unique_ptr<BluetoothServiceRecordBlueZ> ReadRecord(
  131. dbus::MessageReader* array_reader) {
  132. std::unique_ptr<BluetoothServiceRecordBlueZ> record =
  133. std::make_unique<BluetoothServiceRecordBlueZ>();
  134. while (array_reader->HasMoreData()) {
  135. dbus::MessageReader dict_entry_reader(nullptr);
  136. if (!array_reader->PopDictEntry(&dict_entry_reader))
  137. return nullptr;
  138. uint16_t id;
  139. if (!dict_entry_reader.PopUint16(&id))
  140. return nullptr;
  141. dbus::MessageReader struct_reader(nullptr);
  142. if (!dict_entry_reader.PopStruct(&struct_reader))
  143. return nullptr;
  144. std::unique_ptr<BluetoothServiceAttributeValueBlueZ> attribute_value =
  145. ReadAttributeValue(&struct_reader);
  146. if (!attribute_value)
  147. return nullptr;
  148. record->AddRecordEntry(id, *attribute_value);
  149. }
  150. // return std::move(record);
  151. return record;
  152. }
  153. bool ReadRecordsFromMessage(dbus::MessageReader* reader,
  154. BluetoothDeviceClient::ServiceRecordList* records) {
  155. dbus::MessageReader array_reader(nullptr);
  156. if (!reader->PopArray(&array_reader)) {
  157. return false;
  158. LOG(ERROR) << "Arguments for GetConnInfo invalid.";
  159. }
  160. while (array_reader.HasMoreData()) {
  161. dbus::MessageReader nested_array_reader(nullptr);
  162. if (!array_reader.PopArray(&nested_array_reader))
  163. return false;
  164. std::unique_ptr<BluetoothServiceRecordBlueZ> record =
  165. ReadRecord(&nested_array_reader);
  166. if (!record)
  167. return false;
  168. records->emplace_back(*record);
  169. }
  170. return true;
  171. }
  172. } // namespace
  173. const char BluetoothDeviceClient::kNoResponseError[] =
  174. "org.chromium.Error.NoResponse";
  175. const char BluetoothDeviceClient::kUnknownDeviceError[] =
  176. "org.chromium.Error.UnknownDevice";
  177. const char BluetoothDeviceClient::kTypeBredr[] = "BR/EDR";
  178. const char BluetoothDeviceClient::kTypeLe[] = "LE";
  179. const char BluetoothDeviceClient::kTypeDual[] = "DUAL";
  180. BluetoothDeviceClient::Properties::Properties(
  181. dbus::ObjectProxy* object_proxy,
  182. const std::string& interface_name,
  183. const PropertyChangedCallback& callback)
  184. : dbus::PropertySet(object_proxy, interface_name, callback) {
  185. RegisterProperty(bluetooth_device::kAddressProperty, &address);
  186. RegisterProperty(bluetooth_device::kAddressTypeProperty, &address_type);
  187. RegisterProperty(bluetooth_device::kNameProperty, &name);
  188. RegisterProperty(bluetooth_device::kIconProperty, &icon);
  189. RegisterProperty(bluetooth_device::kClassProperty, &bluetooth_class);
  190. RegisterProperty(bluetooth_device::kTypeProperty, &type);
  191. RegisterProperty(bluetooth_device::kAppearanceProperty, &appearance);
  192. RegisterProperty(bluetooth_device::kUUIDsProperty, &uuids);
  193. RegisterProperty(bluetooth_device::kPairedProperty, &paired);
  194. RegisterProperty(bluetooth_device::kConnectedProperty, &connected);
  195. RegisterProperty(bluetooth_device::kConnectedLEProperty, &connected_le);
  196. RegisterProperty(bluetooth_device::kTrustedProperty, &trusted);
  197. RegisterProperty(bluetooth_device::kBlockedProperty, &blocked);
  198. RegisterProperty(bluetooth_device::kAliasProperty, &alias);
  199. RegisterProperty(bluetooth_device::kAdapterProperty, &adapter);
  200. RegisterProperty(bluetooth_device::kLegacyPairingProperty, &legacy_pairing);
  201. RegisterProperty(bluetooth_device::kModaliasProperty, &modalias);
  202. RegisterProperty(bluetooth_device::kRSSIProperty, &rssi);
  203. RegisterProperty(bluetooth_device::kTxPowerProperty, &tx_power);
  204. RegisterProperty(bluetooth_device::kManufacturerDataProperty,
  205. &manufacturer_data);
  206. RegisterProperty(bluetooth_device::kServiceDataProperty, &service_data);
  207. RegisterProperty(bluetooth_device::kServicesResolvedProperty,
  208. &services_resolved);
  209. RegisterProperty(bluetooth_device::kAdvertisingDataFlagsProperty,
  210. &advertising_data_flags);
  211. RegisterProperty(bluetooth_device::kMTUProperty, &mtu);
  212. RegisterProperty(bluetooth_device::kEIRProperty, &eir);
  213. }
  214. BluetoothDeviceClient::Properties::~Properties() = default;
  215. // The BluetoothDeviceClient implementation used in production.
  216. class BluetoothDeviceClientImpl : public BluetoothDeviceClient,
  217. public dbus::ObjectManager::Interface {
  218. public:
  219. BluetoothDeviceClientImpl() : object_manager_(nullptr) {}
  220. BluetoothDeviceClientImpl(const BluetoothDeviceClientImpl&) = delete;
  221. BluetoothDeviceClientImpl& operator=(const BluetoothDeviceClientImpl&) =
  222. delete;
  223. ~BluetoothDeviceClientImpl() override {
  224. // There is an instance of this client that is created but not initialized
  225. // on Linux. See 'Alternate D-Bus Client' note in bluez_dbus_manager.h.
  226. if (object_manager_) {
  227. object_manager_->UnregisterInterface(
  228. bluetooth_adapter::kBluetoothAdapterInterface);
  229. }
  230. }
  231. // BluetoothDeviceClient override.
  232. void AddObserver(BluetoothDeviceClient::Observer* observer) override {
  233. DCHECK(observer);
  234. observers_.AddObserver(observer);
  235. }
  236. // BluetoothDeviceClient override.
  237. void RemoveObserver(BluetoothDeviceClient::Observer* observer) override {
  238. DCHECK(observer);
  239. observers_.RemoveObserver(observer);
  240. }
  241. // dbus::ObjectManager::Interface override.
  242. dbus::PropertySet* CreateProperties(
  243. dbus::ObjectProxy* object_proxy,
  244. const dbus::ObjectPath& object_path,
  245. const std::string& interface_name) override {
  246. return new Properties(
  247. object_proxy, interface_name,
  248. base::BindRepeating(&BluetoothDeviceClientImpl::OnPropertyChanged,
  249. weak_ptr_factory_.GetWeakPtr(), object_path));
  250. }
  251. // BluetoothDeviceClient override.
  252. std::vector<dbus::ObjectPath> GetDevicesForAdapter(
  253. const dbus::ObjectPath& adapter_path) override {
  254. std::vector<dbus::ObjectPath> object_paths, device_paths;
  255. device_paths = object_manager_->GetObjectsWithInterface(
  256. bluetooth_device::kBluetoothDeviceInterface);
  257. for (auto iter = device_paths.begin(); iter != device_paths.end(); ++iter) {
  258. Properties* properties = GetProperties(*iter);
  259. if (properties->adapter.value() == adapter_path)
  260. object_paths.push_back(*iter);
  261. }
  262. return object_paths;
  263. }
  264. // BluetoothDeviceClient override.
  265. Properties* GetProperties(const dbus::ObjectPath& object_path) override {
  266. return static_cast<Properties*>(object_manager_->GetProperties(
  267. object_path, bluetooth_device::kBluetoothDeviceInterface));
  268. }
  269. // BluetoothDeviceClient override.
  270. void Connect(const dbus::ObjectPath& object_path,
  271. base::OnceClosure callback,
  272. ErrorCallback error_callback) override {
  273. dbus::MethodCall method_call(bluetooth_device::kBluetoothDeviceInterface,
  274. bluetooth_device::kConnect);
  275. dbus::ObjectProxy* object_proxy =
  276. object_manager_->GetObjectProxy(object_path);
  277. if (!object_proxy) {
  278. std::move(error_callback).Run(kUnknownDeviceError, "");
  279. return;
  280. }
  281. // Connect may take an arbitrary length of time, so use no timeout.
  282. object_proxy->CallMethodWithErrorCallback(
  283. &method_call, dbus::ObjectProxy::TIMEOUT_INFINITE,
  284. base::BindOnce(&BluetoothDeviceClientImpl::OnSuccess,
  285. weak_ptr_factory_.GetWeakPtr(), std::move(callback)),
  286. base::BindOnce(&BluetoothDeviceClientImpl::OnError,
  287. weak_ptr_factory_.GetWeakPtr(),
  288. std::move(error_callback)));
  289. }
  290. // BluetoothDeviceClient override.
  291. void ConnectClassic(const dbus::ObjectPath& object_path,
  292. base::OnceClosure callback,
  293. ErrorCallback error_callback) override {
  294. dbus::MethodCall method_call(bluetooth_device::kBluetoothDeviceInterface,
  295. kConnectClassicPlaceholder);
  296. dbus::ObjectProxy* object_proxy =
  297. object_manager_->GetObjectProxy(object_path);
  298. if (!object_proxy) {
  299. std::move(error_callback).Run(kUnknownDeviceError, "");
  300. return;
  301. }
  302. // ConnectClassic may take an arbitrary length of time, so use no timeout.
  303. object_proxy->CallMethodWithErrorCallback(
  304. &method_call, dbus::ObjectProxy::TIMEOUT_INFINITE,
  305. base::BindOnce(&BluetoothDeviceClientImpl::OnSuccess,
  306. weak_ptr_factory_.GetWeakPtr(), std::move(callback)),
  307. base::BindOnce(&BluetoothDeviceClientImpl::OnError,
  308. weak_ptr_factory_.GetWeakPtr(),
  309. std::move(error_callback)));
  310. }
  311. // BluetoothDeviceClient override.
  312. void ConnectLE(const dbus::ObjectPath& object_path,
  313. base::OnceClosure callback,
  314. ErrorCallback error_callback) override {
  315. dbus::MethodCall method_call(bluetooth_device::kBluetoothDeviceInterface,
  316. bluetooth_device::kConnectLE);
  317. dbus::ObjectProxy* object_proxy =
  318. object_manager_->GetObjectProxy(object_path);
  319. if (!object_proxy) {
  320. std::move(error_callback).Run(kUnknownDeviceError, "");
  321. return;
  322. }
  323. // ConnectLE may take an arbitrary length of time, so use no timeout.
  324. object_proxy->CallMethodWithErrorCallback(
  325. &method_call, dbus::ObjectProxy::TIMEOUT_INFINITE,
  326. base::BindOnce(&BluetoothDeviceClientImpl::OnSuccess,
  327. weak_ptr_factory_.GetWeakPtr(), std::move(callback)),
  328. base::BindOnce(&BluetoothDeviceClientImpl::OnError,
  329. weak_ptr_factory_.GetWeakPtr(),
  330. std::move(error_callback)));
  331. }
  332. // BluetoothDeviceClient override.
  333. void Disconnect(const dbus::ObjectPath& object_path,
  334. base::OnceClosure callback,
  335. ErrorCallback error_callback) override {
  336. // TODO(b/208933029): Only use the new disconnect method, e.g.
  337. // |bluetooth_device::kDisconnect|, once the Bluetooth revamp is fully launched.
  338. #if BUILDFLAG(IS_CHROMEOS_ASH)
  339. // For the Bluetooth revamp we want to use an updated disconnect mechanism
  340. // that does not disable auto-reconnect since we no longer provide a
  341. // "connect" button for HID devices.
  342. const char* method_name = ash::features::IsBluetoothRevampEnabled()
  343. ? bluetooth_device::kDisconnect
  344. : kDisconnectOldPlaceholder;
  345. #else // BUILDFLAG(IS_CHROMEOS_ASH)
  346. const char* method_name = bluetooth_device::kDisconnect;
  347. #endif // BUILDFLAG(IS_CHROMEOS_ASH)
  348. dbus::MethodCall method_call(bluetooth_device::kBluetoothDeviceInterface,
  349. method_name);
  350. dbus::ObjectProxy* object_proxy =
  351. object_manager_->GetObjectProxy(object_path);
  352. if (!object_proxy) {
  353. std::move(error_callback).Run(kUnknownDeviceError, "");
  354. return;
  355. }
  356. object_proxy->CallMethodWithErrorCallback(
  357. &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  358. base::BindOnce(&BluetoothDeviceClientImpl::OnSuccess,
  359. weak_ptr_factory_.GetWeakPtr(), std::move(callback)),
  360. base::BindOnce(&BluetoothDeviceClientImpl::OnError,
  361. weak_ptr_factory_.GetWeakPtr(),
  362. std::move(error_callback)));
  363. }
  364. // BluetoothDeviceClient override.
  365. void DisconnectLE(const dbus::ObjectPath& object_path,
  366. base::OnceClosure callback,
  367. ErrorCallback error_callback) override {
  368. dbus::MethodCall method_call(bluetooth_device::kBluetoothDeviceInterface,
  369. bluetooth_device::kDisconnectLE);
  370. dbus::ObjectProxy* object_proxy =
  371. object_manager_->GetObjectProxy(object_path);
  372. if (!object_proxy) {
  373. std::move(error_callback).Run(kUnknownDeviceError, "");
  374. return;
  375. }
  376. object_proxy->CallMethodWithErrorCallback(
  377. &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  378. base::BindOnce(&BluetoothDeviceClientImpl::OnSuccess,
  379. weak_ptr_factory_.GetWeakPtr(), std::move(callback)),
  380. base::BindOnce(&BluetoothDeviceClientImpl::OnError,
  381. weak_ptr_factory_.GetWeakPtr(),
  382. std::move(error_callback)));
  383. }
  384. // BluetoothDeviceClient override.
  385. void ConnectProfile(const dbus::ObjectPath& object_path,
  386. const std::string& uuid,
  387. base::OnceClosure callback,
  388. ErrorCallback error_callback) override {
  389. dbus::MethodCall method_call(bluetooth_device::kBluetoothDeviceInterface,
  390. bluetooth_device::kConnectProfile);
  391. dbus::MessageWriter writer(&method_call);
  392. writer.AppendString(uuid);
  393. dbus::ObjectProxy* object_proxy =
  394. object_manager_->GetObjectProxy(object_path);
  395. if (!object_proxy) {
  396. std::move(error_callback).Run(kUnknownDeviceError, "");
  397. return;
  398. }
  399. // Connect may take an arbitrary length of time, so use no timeout.
  400. object_proxy->CallMethodWithErrorCallback(
  401. &method_call, dbus::ObjectProxy::TIMEOUT_INFINITE,
  402. base::BindOnce(&BluetoothDeviceClientImpl::OnSuccess,
  403. weak_ptr_factory_.GetWeakPtr(), std::move(callback)),
  404. base::BindOnce(&BluetoothDeviceClientImpl::OnError,
  405. weak_ptr_factory_.GetWeakPtr(),
  406. std::move(error_callback)));
  407. }
  408. // BluetoothDeviceClient override.
  409. void DisconnectProfile(const dbus::ObjectPath& object_path,
  410. const std::string& uuid,
  411. base::OnceClosure callback,
  412. ErrorCallback error_callback) override {
  413. dbus::MethodCall method_call(bluetooth_device::kBluetoothDeviceInterface,
  414. bluetooth_device::kDisconnectProfile);
  415. dbus::MessageWriter writer(&method_call);
  416. writer.AppendString(uuid);
  417. dbus::ObjectProxy* object_proxy =
  418. object_manager_->GetObjectProxy(object_path);
  419. if (!object_proxy) {
  420. std::move(error_callback).Run(kUnknownDeviceError, "");
  421. return;
  422. }
  423. object_proxy->CallMethodWithErrorCallback(
  424. &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  425. base::BindOnce(&BluetoothDeviceClientImpl::OnDisconnectProfileSuccess,
  426. weak_ptr_factory_.GetWeakPtr(), std::move(callback),
  427. /*start_time=*/base::Time::Now()),
  428. base::BindOnce(&BluetoothDeviceClientImpl::OnDisconnectProfileError,
  429. weak_ptr_factory_.GetWeakPtr(),
  430. std::move(error_callback)));
  431. }
  432. // BluetoothDeviceClient override.
  433. void Pair(const dbus::ObjectPath& object_path,
  434. base::OnceClosure callback,
  435. ErrorCallback error_callback) override {
  436. dbus::MethodCall method_call(bluetooth_device::kBluetoothDeviceInterface,
  437. bluetooth_device::kPair);
  438. dbus::ObjectProxy* object_proxy =
  439. object_manager_->GetObjectProxy(object_path);
  440. if (!object_proxy) {
  441. std::move(error_callback).Run(kUnknownDeviceError, "");
  442. return;
  443. }
  444. // Pairing may take an arbitrary length of time, so use no timeout.
  445. object_proxy->CallMethodWithErrorCallback(
  446. &method_call, dbus::ObjectProxy::TIMEOUT_INFINITE,
  447. base::BindOnce(&BluetoothDeviceClientImpl::OnSuccess,
  448. weak_ptr_factory_.GetWeakPtr(), std::move(callback)),
  449. base::BindOnce(&BluetoothDeviceClientImpl::OnError,
  450. weak_ptr_factory_.GetWeakPtr(),
  451. std::move(error_callback)));
  452. }
  453. // BluetoothDeviceClient override.
  454. void CancelPairing(const dbus::ObjectPath& object_path,
  455. base::OnceClosure callback,
  456. ErrorCallback error_callback) override {
  457. dbus::MethodCall method_call(bluetooth_device::kBluetoothDeviceInterface,
  458. bluetooth_device::kCancelPairing);
  459. dbus::ObjectProxy* object_proxy =
  460. object_manager_->GetObjectProxy(object_path);
  461. if (!object_proxy) {
  462. std::move(error_callback).Run(kUnknownDeviceError, "");
  463. return;
  464. }
  465. object_proxy->CallMethodWithErrorCallback(
  466. &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  467. base::BindOnce(&BluetoothDeviceClientImpl::OnSuccess,
  468. weak_ptr_factory_.GetWeakPtr(), std::move(callback)),
  469. base::BindOnce(&BluetoothDeviceClientImpl::OnError,
  470. weak_ptr_factory_.GetWeakPtr(),
  471. std::move(error_callback)));
  472. }
  473. // BluetoothDeviceClient override.
  474. void GetConnInfo(const dbus::ObjectPath& object_path,
  475. ConnInfoCallback callback,
  476. ErrorCallback error_callback) override {
  477. dbus::MethodCall method_call(
  478. bluetooth_plugin_device::kBluetoothPluginInterface,
  479. bluetooth_plugin_device::kGetConnInfo);
  480. dbus::ObjectProxy* object_proxy =
  481. object_manager_->GetObjectProxy(object_path);
  482. if (!object_proxy) {
  483. std::move(error_callback).Run(kUnknownDeviceError, "");
  484. return;
  485. }
  486. object_proxy->CallMethodWithErrorCallback(
  487. &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  488. base::BindOnce(&BluetoothDeviceClientImpl::OnGetConnInfoSuccess,
  489. weak_ptr_factory_.GetWeakPtr(), std::move(callback)),
  490. base::BindOnce(&BluetoothDeviceClientImpl::OnError,
  491. weak_ptr_factory_.GetWeakPtr(),
  492. std::move(error_callback)));
  493. }
  494. void SetLEConnectionParameters(const dbus::ObjectPath& object_path,
  495. const ConnectionParameters& conn_params,
  496. base::OnceClosure callback,
  497. ErrorCallback error_callback) override {
  498. dbus::ObjectProxy* object_proxy =
  499. object_manager_->GetObjectProxy(object_path);
  500. if (!object_proxy) {
  501. std::move(error_callback).Run(kUnknownDeviceError, "");
  502. return;
  503. }
  504. dbus::MethodCall method_call(
  505. bluetooth_plugin_device::kBluetoothPluginInterface,
  506. bluetooth_plugin_device::kSetLEConnectionParameters);
  507. dbus::MessageWriter writer(&method_call);
  508. dbus::MessageWriter dict_writer(nullptr);
  509. writer.OpenArray("{sq}", &dict_writer);
  510. {
  511. dbus::MessageWriter dict_entry_writer(nullptr);
  512. dict_writer.OpenDictEntry(&dict_entry_writer);
  513. dict_entry_writer.AppendString(
  514. bluetooth_plugin_device::
  515. kLEConnectionParameterMinimumConnectionInterval);
  516. dict_entry_writer.AppendUint16(conn_params.min_connection_interval);
  517. dict_writer.CloseContainer(&dict_entry_writer);
  518. }
  519. {
  520. dbus::MessageWriter dict_entry_writer(nullptr);
  521. dict_writer.OpenDictEntry(&dict_entry_writer);
  522. dict_entry_writer.AppendString(
  523. bluetooth_plugin_device::
  524. kLEConnectionParameterMaximumConnectionInterval);
  525. dict_entry_writer.AppendUint16(conn_params.max_connection_interval);
  526. dict_writer.CloseContainer(&dict_entry_writer);
  527. }
  528. writer.CloseContainer(&dict_writer);
  529. object_proxy->CallMethodWithErrorCallback(
  530. &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  531. base::BindOnce(&BluetoothDeviceClientImpl::OnSuccess,
  532. weak_ptr_factory_.GetWeakPtr(), std::move(callback)),
  533. base::BindOnce(&BluetoothDeviceClientImpl::OnError,
  534. weak_ptr_factory_.GetWeakPtr(),
  535. std::move(error_callback)));
  536. }
  537. void GetServiceRecords(const dbus::ObjectPath& object_path,
  538. ServiceRecordsCallback callback,
  539. ErrorCallback error_callback) override {
  540. dbus::MethodCall method_call(bluetooth_device::kBluetoothDeviceInterface,
  541. bluetooth_device::kGetServiceRecords);
  542. dbus::ObjectProxy* object_proxy =
  543. object_manager_->GetObjectProxy(object_path);
  544. if (!object_proxy) {
  545. std::move(error_callback).Run(kUnknownDeviceError, "");
  546. return;
  547. }
  548. object_proxy->CallMethodWithErrorCallback(
  549. &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  550. base::BindOnce(&BluetoothDeviceClientImpl::OnGetServiceRecordsSuccess,
  551. weak_ptr_factory_.GetWeakPtr(), std::move(callback),
  552. /*start_time=*/base::Time::Now()),
  553. base::BindOnce(&BluetoothDeviceClientImpl::OnGetServiceRecordsError,
  554. weak_ptr_factory_.GetWeakPtr(),
  555. std::move(error_callback)));
  556. }
  557. void ExecuteWrite(const dbus::ObjectPath& object_path,
  558. base::OnceClosure callback,
  559. ErrorCallback error_callback) override {
  560. dbus::MethodCall method_call(bluetooth_device::kBluetoothDeviceInterface,
  561. bluetooth_device::kExecuteWrite);
  562. dbus::ObjectProxy* object_proxy =
  563. object_manager_->GetObjectProxy(object_path);
  564. if (!object_proxy) {
  565. std::move(error_callback).Run(kUnknownDeviceError, "");
  566. return;
  567. }
  568. dbus::MessageWriter writer(&method_call);
  569. writer.AppendBool(true);
  570. object_proxy->CallMethodWithErrorCallback(
  571. &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  572. base::BindOnce(&BluetoothDeviceClientImpl::OnSuccess,
  573. weak_ptr_factory_.GetWeakPtr(), std::move(callback)),
  574. base::BindOnce(&BluetoothDeviceClientImpl::OnError,
  575. weak_ptr_factory_.GetWeakPtr(),
  576. std::move(error_callback)));
  577. }
  578. void AbortWrite(const dbus::ObjectPath& object_path,
  579. base::OnceClosure callback,
  580. ErrorCallback error_callback) override {
  581. dbus::MethodCall method_call(bluetooth_device::kBluetoothDeviceInterface,
  582. bluetooth_device::kExecuteWrite);
  583. dbus::ObjectProxy* object_proxy =
  584. object_manager_->GetObjectProxy(object_path);
  585. if (!object_proxy) {
  586. std::move(error_callback).Run(kUnknownDeviceError, "");
  587. return;
  588. }
  589. dbus::MessageWriter writer(&method_call);
  590. writer.AppendBool(false);
  591. object_proxy->CallMethodWithErrorCallback(
  592. &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  593. base::BindOnce(&BluetoothDeviceClientImpl::OnSuccess,
  594. weak_ptr_factory_.GetWeakPtr(), std::move(callback)),
  595. base::BindOnce(&BluetoothDeviceClientImpl::OnError,
  596. weak_ptr_factory_.GetWeakPtr(),
  597. std::move(error_callback)));
  598. }
  599. protected:
  600. void Init(dbus::Bus* bus,
  601. const std::string& bluetooth_service_name) override {
  602. object_manager_ = bus->GetObjectManager(
  603. bluetooth_service_name,
  604. dbus::ObjectPath(
  605. bluetooth_object_manager::kBluetoothObjectManagerServicePath));
  606. object_manager_->RegisterInterface(
  607. bluetooth_device::kBluetoothDeviceInterface, this);
  608. }
  609. private:
  610. // Called by dbus::ObjectManager when an object with the device interface
  611. // is created. Informs observers.
  612. void ObjectAdded(const dbus::ObjectPath& object_path,
  613. const std::string& interface_name) override {
  614. for (auto& observer : observers_)
  615. observer.DeviceAdded(object_path);
  616. }
  617. // Called by dbus::ObjectManager when an object with the device interface
  618. // is removed. Informs observers.
  619. void ObjectRemoved(const dbus::ObjectPath& object_path,
  620. const std::string& interface_name) override {
  621. for (auto& observer : observers_)
  622. observer.DeviceRemoved(object_path);
  623. }
  624. // Called by BluetoothPropertySet when a property value is changed,
  625. // either by result of a signal or response to a GetAll() or Get()
  626. // call. Informs observers.
  627. void OnPropertyChanged(const dbus::ObjectPath& object_path,
  628. const std::string& property_name) {
  629. for (auto& observer : observers_)
  630. observer.DevicePropertyChanged(object_path, property_name);
  631. }
  632. // Called when a response for successful method call is received.
  633. void OnSuccess(base::OnceClosure callback, dbus::Response* response) {
  634. DCHECK(response);
  635. std::move(callback).Run();
  636. }
  637. void OnDisconnectProfileSuccess(base::OnceClosure callback,
  638. base::Time time_started,
  639. dbus::Response* response) {
  640. DCHECK(response);
  641. RecordSuccess(kDisconnectProfileMethod, time_started);
  642. std::move(callback).Run();
  643. }
  644. void OnDisconnectProfileError(ErrorCallback error_callback,
  645. dbus::ErrorResponse* response) {
  646. RecordFailure(kDisconnectProfileMethod, response);
  647. OnError(std::move(error_callback), response);
  648. }
  649. // Called when a response for the GetConnInfo method is received.
  650. void OnGetConnInfoSuccess(ConnInfoCallback callback,
  651. dbus::Response* response) {
  652. int16_t rssi = kUnknownPower;
  653. int16_t transmit_power = kUnknownPower;
  654. int16_t max_transmit_power = kUnknownPower;
  655. if (!response) {
  656. LOG(ERROR) << "GetConnInfo succeeded, but no response received.";
  657. std::move(callback).Run(rssi, transmit_power, max_transmit_power);
  658. return;
  659. }
  660. dbus::MessageReader reader(response);
  661. if (!reader.PopInt16(&rssi) || !reader.PopInt16(&transmit_power) ||
  662. !reader.PopInt16(&max_transmit_power)) {
  663. LOG(ERROR) << "Arguments for GetConnInfo invalid.";
  664. }
  665. std::move(callback).Run(rssi, transmit_power, max_transmit_power);
  666. }
  667. void OnGetServiceRecordsSuccess(ServiceRecordsCallback callback,
  668. base::Time start_time,
  669. dbus::Response* response) {
  670. RecordSuccess(kGetServiceRecordsMethod, start_time);
  671. ServiceRecordList records;
  672. if (!response) {
  673. LOG(ERROR) << "GetServiceRecords succeeded, but no response received.";
  674. std::move(callback).Run(records);
  675. return;
  676. }
  677. dbus::MessageReader reader(response);
  678. if (!ReadRecordsFromMessage(&reader, &records)) {
  679. std::move(callback).Run(ServiceRecordList());
  680. return;
  681. }
  682. std::move(callback).Run(records);
  683. }
  684. void OnGetServiceRecordsError(ErrorCallback error_callback,
  685. dbus::ErrorResponse* response) {
  686. RecordFailure(kGetServiceRecordsMethod, response);
  687. OnError(std::move(error_callback), response);
  688. }
  689. // Called when a response for a failed method call is received.
  690. void OnError(ErrorCallback error_callback, dbus::ErrorResponse* response) {
  691. // Error response has optional error message argument.
  692. std::string error_name;
  693. std::string error_message;
  694. if (response) {
  695. dbus::MessageReader reader(response);
  696. error_name = response->GetErrorName();
  697. reader.PopString(&error_message);
  698. } else {
  699. error_name = kNoResponseError;
  700. error_message = "";
  701. }
  702. std::move(error_callback).Run(error_name, error_message);
  703. }
  704. raw_ptr<dbus::ObjectManager> object_manager_;
  705. // List of observers interested in event notifications from us.
  706. base::ObserverList<BluetoothDeviceClient::Observer>::Unchecked observers_;
  707. // Weak pointer factory for generating 'this' pointers that might live longer
  708. // than we do.
  709. // Note: This should remain the last member so it'll be destroyed and
  710. // invalidate its weak pointers before any other members are destroyed.
  711. base::WeakPtrFactory<BluetoothDeviceClientImpl> weak_ptr_factory_{this};
  712. };
  713. BluetoothDeviceClient::BluetoothDeviceClient() = default;
  714. BluetoothDeviceClient::~BluetoothDeviceClient() = default;
  715. BluetoothDeviceClient* BluetoothDeviceClient::Create() {
  716. return new BluetoothDeviceClientImpl();
  717. }
  718. } // namespace bluez