bluetooth_advertisement_monitor_manager_client.cc 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. // Copyright 2021 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_advertisement_monitor_manager_client.h"
  5. #include "base/bind.h"
  6. #include "base/callback_helpers.h"
  7. #include "base/check.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 "dbus/bus.h"
  13. #include "dbus/message.h"
  14. #include "dbus/object_manager.h"
  15. #include "dbus/object_proxy.h"
  16. #include "third_party/cros_system_api/dbus/service_constants.h"
  17. namespace {
  18. const char kNoResponseError[] = "org.chromium.Error.NoResponse";
  19. const char kFailedError[] = "org.chromium.Error.Failed";
  20. } // namespace
  21. namespace bluez {
  22. BluetoothAdvertisementMonitorManagerClient::Observer::~Observer() = default;
  23. BluetoothAdvertisementMonitorManagerClient::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(
  29. bluetooth_advertisement_monitor_manager::kSupportedMonitorTypes,
  30. &supported_monitor_types);
  31. RegisterProperty(bluetooth_advertisement_monitor_manager::kSupportedFeatures,
  32. &supported_features);
  33. }
  34. BluetoothAdvertisementMonitorManagerClient::Properties::~Properties() = default;
  35. // The BluetoothAdvertisementMonitorManagerClient implementation used in
  36. // production.
  37. class BluetoothAdvertisementMonitorManagerClientImpl final
  38. : public BluetoothAdvertisementMonitorManagerClient,
  39. public dbus::ObjectManager::Interface {
  40. public:
  41. BluetoothAdvertisementMonitorManagerClientImpl() = default;
  42. ~BluetoothAdvertisementMonitorManagerClientImpl() override {
  43. // There is an instance of this client that is created but not initialized
  44. // on Linux. See 'Alternate D-Bus Client' note in bluez_dbus_manager.h.
  45. if (object_manager_) {
  46. object_manager_->UnregisterInterface(
  47. bluetooth_advertisement_monitor_manager::
  48. kBluetoothAdvertisementMonitorManagerInterface);
  49. }
  50. }
  51. BluetoothAdvertisementMonitorManagerClientImpl(
  52. const BluetoothAdvertisementMonitorManagerClientImpl&) = delete;
  53. BluetoothAdvertisementMonitorManagerClientImpl& operator=(
  54. const BluetoothAdvertisementMonitorManagerClientImpl&) = delete;
  55. // BluetoothAdvertisementMonitorManagerClient override.
  56. void RegisterMonitor(const dbus::ObjectPath& application,
  57. const dbus::ObjectPath& adapter,
  58. base::OnceClosure callback,
  59. ErrorCallback error_callback) override {
  60. dbus::MethodCall method_call(
  61. bluetooth_advertisement_monitor_manager::
  62. kBluetoothAdvertisementMonitorManagerInterface,
  63. bluetooth_advertisement_monitor_manager::kRegisterMonitor);
  64. dbus::MessageWriter writer(&method_call);
  65. writer.AppendObjectPath(application);
  66. CallObjectProxyMethod(adapter, &method_call, std::move(callback),
  67. std::move(error_callback));
  68. }
  69. // BluetoothAdvertisementMonitorManagerClient override.
  70. void UnregisterMonitor(const dbus::ObjectPath& application,
  71. const dbus::ObjectPath& adapter,
  72. base::OnceClosure callback,
  73. ErrorCallback error_callback) override {
  74. dbus::MethodCall method_call(
  75. bluetooth_advertisement_monitor_manager::
  76. kBluetoothAdvertisementMonitorManagerInterface,
  77. bluetooth_advertisement_monitor_manager::kUnregisterMonitor);
  78. dbus::MessageWriter writer(&method_call);
  79. writer.AppendObjectPath(application);
  80. CallObjectProxyMethod(adapter, &method_call, std::move(callback),
  81. std::move(error_callback));
  82. }
  83. // dbus::ObjectManager::Interface override.
  84. dbus::PropertySet* CreateProperties(
  85. dbus::ObjectProxy* object_proxy,
  86. const dbus::ObjectPath& object_path,
  87. const std::string& interface_name) override {
  88. return new Properties(
  89. object_proxy, interface_name,
  90. base::BindRepeating(
  91. &BluetoothAdvertisementMonitorManagerClientImpl::OnPropertyChanged,
  92. weak_ptr_factory_.GetWeakPtr(), object_path));
  93. ;
  94. }
  95. // BluetoothAdvertisementMonitorManagerClient override.
  96. void AddObserver(
  97. BluetoothAdvertisementMonitorManagerClient::Observer* observer) override {
  98. DCHECK(observer);
  99. observers_.AddObserver(observer);
  100. }
  101. void RemoveObserver(
  102. BluetoothAdvertisementMonitorManagerClient::Observer* observer) override {
  103. DCHECK(observer);
  104. observers_.RemoveObserver(observer);
  105. }
  106. Properties* GetProperties(const dbus::ObjectPath& object_path) override {
  107. DCHECK(object_manager_);
  108. return static_cast<Properties*>(object_manager_->GetProperties(
  109. object_path, bluetooth_advertisement_monitor_manager::
  110. kBluetoothAdvertisementMonitorManagerInterface));
  111. }
  112. protected:
  113. void Init(dbus::Bus* bus,
  114. const std::string& bluetooth_service_name) override {
  115. DCHECK(bus);
  116. object_manager_ = bus->GetObjectManager(
  117. bluetooth_service_name,
  118. dbus::ObjectPath(
  119. bluetooth_object_manager::kBluetoothObjectManagerServicePath));
  120. object_manager_->RegisterInterface(
  121. bluetooth_advertisement_monitor_manager::
  122. kBluetoothAdvertisementMonitorManagerInterface,
  123. this);
  124. }
  125. private:
  126. // Called by dbus::PropertySet when a property value is changed. Informs
  127. // observers.
  128. void OnPropertyChanged(const dbus::ObjectPath& object_path,
  129. const std::string& property_name) {
  130. DVLOG(2) << "Bluetooth Advertisement Monitor Client property changed: "
  131. << object_path.value() << ": " << property_name;
  132. if (property_name ==
  133. bluetooth_advertisement_monitor_manager::kSupportedFeatures) {
  134. for (auto& observer : observers_)
  135. observer.SupportedAdvertisementMonitorFeaturesChanged();
  136. }
  137. }
  138. void CallObjectProxyMethod(const dbus::ObjectPath& manager_object_path,
  139. dbus::MethodCall* method_call,
  140. base::OnceClosure callback,
  141. ErrorCallback error_callback) {
  142. DCHECK(object_manager_);
  143. dbus::ObjectProxy* object_proxy =
  144. object_manager_->GetObjectProxy(manager_object_path);
  145. if (!object_proxy) {
  146. std::move(error_callback).Run(kFailedError, "Adapter does not exist.");
  147. return;
  148. }
  149. object_proxy->CallMethodWithErrorCallback(
  150. method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  151. base::BindOnce(
  152. &BluetoothAdvertisementMonitorManagerClientImpl::OnSuccess,
  153. weak_ptr_factory_.GetWeakPtr(), std::move(callback)),
  154. base::BindOnce(&BluetoothAdvertisementMonitorManagerClientImpl::OnError,
  155. weak_ptr_factory_.GetWeakPtr(),
  156. std::move(error_callback)));
  157. }
  158. // Called when a response for successful method call is received.
  159. void OnSuccess(base::OnceClosure callback, dbus::Response* response) {
  160. DCHECK(response);
  161. std::move(callback).Run();
  162. }
  163. // Called when a response for a failed method call is received.
  164. void OnError(ErrorCallback error_callback, dbus::ErrorResponse* response) {
  165. // Error response has optional error message argument.
  166. std::string error_name;
  167. std::string error_message;
  168. if (response) {
  169. dbus::MessageReader reader(response);
  170. error_name = response->GetErrorName();
  171. reader.PopString(&error_message);
  172. } else {
  173. error_name = kNoResponseError;
  174. error_message = "D-Bus did not provide a response.";
  175. }
  176. std::move(error_callback).Run(error_name, error_message);
  177. }
  178. base::ObserverList<Observer> observers_;
  179. raw_ptr<dbus::ObjectManager> object_manager_ = nullptr;
  180. base::WeakPtrFactory<BluetoothAdvertisementMonitorManagerClientImpl>
  181. weak_ptr_factory_{this};
  182. };
  183. BluetoothAdvertisementMonitorManagerClient::
  184. BluetoothAdvertisementMonitorManagerClient() = default;
  185. BluetoothAdvertisementMonitorManagerClient::
  186. ~BluetoothAdvertisementMonitorManagerClient() = default;
  187. // static
  188. std::unique_ptr<BluetoothAdvertisementMonitorManagerClient>
  189. BluetoothAdvertisementMonitorManagerClient::Create() {
  190. return base::WrapUnique(new BluetoothAdvertisementMonitorManagerClientImpl());
  191. }
  192. } // namespace bluez