bluetooth_advertisement_monitor_application_service_provider_impl.cc 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  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_application_service_provider_impl.h"
  5. #include "base/bind.h"
  6. #include "base/containers/contains.h"
  7. #include "base/logging.h"
  8. #include "third_party/cros_system_api/dbus/service_constants.h"
  9. namespace bluez {
  10. BluetoothAdvertisementMonitorApplicationServiceProviderImpl::
  11. BluetoothAdvertisementMonitorApplicationServiceProviderImpl(
  12. dbus::Bus* bus,
  13. const dbus::ObjectPath& object_path)
  14. : origin_thread_id_(base::PlatformThread::CurrentId()),
  15. bus_(bus),
  16. object_path_(object_path) {
  17. DVLOG(1) << "Creating Bluetooth Advertisement Monitor application: "
  18. << object_path_.value();
  19. DCHECK(bus_);
  20. DCHECK(object_path_.IsValid());
  21. exported_object_ = bus_->GetExportedObject(object_path_);
  22. if (!exported_object_) {
  23. LOG(WARNING) << "Invalid exported_object";
  24. return;
  25. }
  26. exported_object_->ExportMethod(
  27. dbus::kDBusObjectManagerInterface,
  28. dbus::kDBusObjectManagerGetManagedObjects,
  29. base::BindRepeating(
  30. &BluetoothAdvertisementMonitorApplicationServiceProviderImpl::
  31. GetManagedObjects,
  32. weak_ptr_factory_.GetWeakPtr()),
  33. base::BindOnce(
  34. &BluetoothAdvertisementMonitorApplicationServiceProviderImpl::
  35. OnExported,
  36. weak_ptr_factory_.GetWeakPtr()));
  37. }
  38. BluetoothAdvertisementMonitorApplicationServiceProviderImpl::
  39. ~BluetoothAdvertisementMonitorApplicationServiceProviderImpl() {
  40. DVLOG(1) << "Cleaning up Advertisement Monitor Application: "
  41. << object_path_.value();
  42. DCHECK(bus_);
  43. bus_->UnregisterExportedObject(object_path_);
  44. }
  45. void BluetoothAdvertisementMonitorApplicationServiceProviderImpl::AddMonitor(
  46. std::unique_ptr<BluetoothAdvertisementMonitorServiceProvider>
  47. advertisement_monitor_service_provider) {
  48. dbus::ObjectPath monitor_path =
  49. advertisement_monitor_service_provider->object_path();
  50. DVLOG(1) << "Adding Advertisement Monitor: " << monitor_path.value();
  51. advertisement_monitor_providers_.insert(std::make_pair(
  52. monitor_path.value(), std::move(advertisement_monitor_service_provider)));
  53. dbus::Signal signal(dbus::kDBusObjectManagerInterface,
  54. dbus::kDBusObjectManagerInterfacesAddedSignal);
  55. dbus::MessageWriter writer(&signal);
  56. writer.AppendObjectPath(monitor_path);
  57. dbus::MessageWriter array_writer(nullptr);
  58. writer.OpenArray("{sa{sv}}", &array_writer);
  59. WriteInterfaceDict(
  60. &array_writer,
  61. bluetooth_advertisement_monitor::kBluetoothAdvertisementMonitorInterface,
  62. advertisement_monitor_providers_[monitor_path.value()].get());
  63. writer.CloseContainer(&array_writer);
  64. exported_object_->SendSignal(&signal);
  65. }
  66. void BluetoothAdvertisementMonitorApplicationServiceProviderImpl::RemoveMonitor(
  67. const dbus::ObjectPath& monitor_path) {
  68. if (!base::Contains(advertisement_monitor_providers_, monitor_path.value())) {
  69. LOG(WARNING)
  70. << "Failed to remove Advertisement Monitor because it does not exist "
  71. << monitor_path.value();
  72. return;
  73. }
  74. DVLOG(1) << "Removing Advertisement Monitor: " << monitor_path.value();
  75. dbus::Signal signal(dbus::kDBusObjectManagerInterface,
  76. dbus::kDBusObjectManagerInterfacesRemovedSignal);
  77. dbus::MessageWriter writer(&signal);
  78. writer.AppendObjectPath(monitor_path);
  79. std::vector<std::string> interfaces;
  80. interfaces.push_back(
  81. bluetooth_advertisement_monitor::kBluetoothAdvertisementMonitorInterface);
  82. writer.AppendArrayOfStrings(interfaces);
  83. exported_object_->SendSignal(&signal);
  84. advertisement_monitor_providers_.erase(monitor_path.value());
  85. }
  86. bool BluetoothAdvertisementMonitorApplicationServiceProviderImpl::
  87. OnOriginThread() const {
  88. return base::PlatformThread::CurrentId() == origin_thread_id_;
  89. }
  90. void BluetoothAdvertisementMonitorApplicationServiceProviderImpl::
  91. WriteObjectDict(dbus::MessageWriter* writer,
  92. const std::string& attribute_interface,
  93. BluetoothAdvertisementMonitorServiceProvider*
  94. advertisement_monitor_service_provider) {
  95. // Open a dict entry for { object_path : interface_list }.
  96. dbus::MessageWriter object_dict_writer(nullptr);
  97. // [ {oa{sa{sv}} ]
  98. writer->OpenDictEntry(&object_dict_writer);
  99. // Key: Object path. [ {o ]
  100. object_dict_writer.AppendObjectPath(
  101. advertisement_monitor_service_provider->object_path());
  102. // Value: Open array for single entry interface_list. [ a{sa{sv}} ]
  103. dbus::MessageWriter interface_array_writer(nullptr);
  104. object_dict_writer.OpenArray("(sa{sv})", &interface_array_writer);
  105. WriteInterfaceDict(&interface_array_writer, attribute_interface,
  106. advertisement_monitor_service_provider);
  107. object_dict_writer.CloseContainer(&interface_array_writer);
  108. writer->CloseContainer(&object_dict_writer);
  109. }
  110. void BluetoothAdvertisementMonitorApplicationServiceProviderImpl::
  111. WriteInterfaceDict(dbus::MessageWriter* writer,
  112. const std::string& attribute_interface,
  113. BluetoothAdvertisementMonitorServiceProvider*
  114. advertisement_monitor_service_provider) {
  115. // Open a dict entry for { interface_name : properties_list }.
  116. dbus::MessageWriter interface_dict_writer(nullptr);
  117. // [ {sa{sv}} ]
  118. writer->OpenDictEntry(&interface_dict_writer);
  119. // Key: Interface name. [ {s ]
  120. interface_dict_writer.AppendString(attribute_interface);
  121. // Value: Open a array for properties_list. [ a{sv}} ]
  122. advertisement_monitor_service_provider->WriteProperties(
  123. &interface_dict_writer);
  124. writer->CloseContainer(&interface_dict_writer);
  125. }
  126. void BluetoothAdvertisementMonitorApplicationServiceProviderImpl::
  127. GetManagedObjects(dbus::MethodCall* method_call,
  128. dbus::ExportedObject::ResponseSender response_sender) {
  129. dbus::MessageReader reader(method_call);
  130. std::unique_ptr<dbus::Response> response =
  131. dbus::Response::FromMethodCall(method_call);
  132. // The expected format by GetManagedObjects is [ a{oa{sa{sv}}} ]
  133. dbus::MessageWriter writer(response.get());
  134. dbus::MessageWriter array_writer(nullptr);
  135. // {object path, dict {string, dict {string, variant}}}
  136. writer.OpenArray("{oa{sa{sv}}}", &array_writer);
  137. for (const auto& it : advertisement_monitor_providers_) {
  138. WriteObjectDict(&array_writer,
  139. bluetooth_advertisement_monitor::
  140. kBluetoothAdvertisementMonitorInterface,
  141. it.second.get());
  142. }
  143. writer.CloseContainer(&array_writer);
  144. DVLOG(3) << "Sending response to BlueZ for GetManagedObjects: \n"
  145. << response->ToString();
  146. std::move(response_sender).Run(std::move(response));
  147. }
  148. void BluetoothAdvertisementMonitorApplicationServiceProviderImpl::OnExported(
  149. const std::string& interface_name,
  150. const std::string& method_name,
  151. bool success) {
  152. // Failure case not actionable.
  153. DVLOG_IF(1, !success) << "Failed to export " << interface_name << "."
  154. << method_name;
  155. }
  156. } // namespace bluez