bluetooth_advertisement_monitor_application_service_provider_unittest.cc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  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 <cstdint>
  5. #include <memory>
  6. #include <vector>
  7. #include "base/callback_helpers.h"
  8. #include "base/logging.h"
  9. #include "base/time/time.h"
  10. #include "dbus/bus.h"
  11. #include "dbus/message.h"
  12. #include "dbus/mock_bus.h"
  13. #include "dbus/mock_exported_object.h"
  14. #include "device/bluetooth/bluetooth_low_energy_scan_filter.h"
  15. #include "device/bluetooth/bluetooth_low_energy_scan_session.h"
  16. #include "device/bluetooth/bluez/bluetooth_low_energy_scan_session_bluez.h"
  17. #include "device/bluetooth/dbus/bluetooth_advertisement_monitor_application_service_provider_impl.h"
  18. #include "device/bluetooth/dbus/bluetooth_advertisement_monitor_service_provider_impl.h"
  19. #include "device/bluetooth/dbus/fake_bluetooth_advertisement_monitor_service_provider.h"
  20. #include "testing/gtest/include/gtest/gtest.h"
  21. #include "third_party/abseil-cpp/absl/types/optional.h"
  22. #include "third_party/cros_system_api/dbus/service_constants.h"
  23. namespace bluez {
  24. namespace {
  25. constexpr char kExpectedMessage1[] = R"(message_type: MESSAGE_METHOD_RETURN
  26. signature: a{oa{sa{sv}}}
  27. reply_serial: 123
  28. array [
  29. ]
  30. )";
  31. constexpr char kExpectedMessage2[] = R"(message_type: MESSAGE_METHOD_RETURN
  32. signature: a{oa{sa{sv}}}
  33. reply_serial: 123
  34. array [
  35. dict entry {
  36. object_path "/path/monitor1"
  37. array [
  38. dict entry {
  39. string "org.bluez.AdvertisementMonitor1"
  40. array [
  41. dict entry {
  42. string "Type"
  43. variant string "or_patterns"
  44. }
  45. dict entry {
  46. string "RSSIHighThreshold"
  47. variant int16_t -65
  48. }
  49. dict entry {
  50. string "RSSIHighTimeout"
  51. variant uint16_t 1
  52. }
  53. dict entry {
  54. string "RSSILowThreshold"
  55. variant int16_t -80
  56. }
  57. dict entry {
  58. string "RSSILowTimeout"
  59. variant uint16_t 3
  60. }
  61. dict entry {
  62. string "Patterns"
  63. variant array [
  64. struct {
  65. byte 0
  66. byte 22
  67. array [
  68. byte 44
  69. byte 254
  70. byte 252
  71. byte 18
  72. byte 142
  73. ]
  74. }
  75. ]
  76. }
  77. ]
  78. }
  79. ]
  80. }
  81. ]
  82. )";
  83. constexpr char kExpectedMessage3[] = R"(message_type: MESSAGE_SIGNAL
  84. interface: org.freedesktop.DBus.ObjectManager
  85. member: InterfacesAdded
  86. signature: oa{sa{sv}}
  87. object_path "/path/monitor1"
  88. array [
  89. dict entry {
  90. string "org.bluez.AdvertisementMonitor1"
  91. array [
  92. dict entry {
  93. string "Type"
  94. variant string "or_patterns"
  95. }
  96. dict entry {
  97. string "RSSIHighThreshold"
  98. variant int16_t -65
  99. }
  100. dict entry {
  101. string "RSSIHighTimeout"
  102. variant uint16_t 1
  103. }
  104. dict entry {
  105. string "RSSILowThreshold"
  106. variant int16_t -80
  107. }
  108. dict entry {
  109. string "RSSILowTimeout"
  110. variant uint16_t 3
  111. }
  112. dict entry {
  113. string "Patterns"
  114. variant array [
  115. struct {
  116. byte 0
  117. byte 22
  118. array [
  119. byte 44
  120. byte 254
  121. byte 252
  122. byte 18
  123. byte 142
  124. ]
  125. }
  126. ]
  127. }
  128. ]
  129. }
  130. ]
  131. )";
  132. constexpr char kExpectedMessage4[] = R"(message_type: MESSAGE_SIGNAL
  133. interface: org.freedesktop.DBus.ObjectManager
  134. member: InterfacesRemoved
  135. signature: oas
  136. object_path "/path/monitor1"
  137. array [
  138. string "org.bluez.AdvertisementMonitor1"
  139. ]
  140. )";
  141. constexpr base::TimeDelta kDeviceFoundTimeout = base::Seconds(1);
  142. constexpr base::TimeDelta kDeviceLostTimeout = base::Seconds(3);
  143. // Used to verify the filter pattern value provided by the scanner.
  144. constexpr uint8_t kPatternValue[] = {0x2c, 0xfe, 0xfc, 0x12, 0x8e};
  145. class FakeBluetoothLowEnergyScanSessionDelegate
  146. : public device::BluetoothLowEnergyScanSession::Delegate {
  147. public:
  148. FakeBluetoothLowEnergyScanSessionDelegate() = default;
  149. // BluetoothLowEnergyScanSession::Delegate
  150. void OnSessionStarted(
  151. device::BluetoothLowEnergyScanSession* scan_session,
  152. absl::optional<device::BluetoothLowEnergyScanSession::ErrorCode>
  153. error_code) override {}
  154. void OnDeviceFound(device::BluetoothLowEnergyScanSession* scan_session,
  155. device::BluetoothDevice* device) override {}
  156. void OnDeviceLost(device::BluetoothLowEnergyScanSession* scan_session,
  157. device::BluetoothDevice* device) override {}
  158. void OnSessionInvalidated(
  159. device::BluetoothLowEnergyScanSession* scan_session) override {}
  160. base::WeakPtr<FakeBluetoothLowEnergyScanSessionDelegate> GetWeakPtr() {
  161. return weak_ptr_factory_.GetWeakPtr();
  162. }
  163. private:
  164. base::WeakPtrFactory<FakeBluetoothLowEnergyScanSessionDelegate>
  165. weak_ptr_factory_{this};
  166. };
  167. void ResponseSenderCallback(const std::string& expected_message,
  168. std::unique_ptr<dbus::Response> response) {
  169. EXPECT_EQ(expected_message, response->ToString());
  170. }
  171. void SendSignal(const std::string& expected_message, dbus::Signal* signal) {
  172. EXPECT_EQ(expected_message, signal->ToString());
  173. }
  174. void SetUpMocksDbus(dbus::MockBus* mock_bus,
  175. dbus::MockExportedObject* mock_exported_object) {
  176. EXPECT_CALL(*mock_bus, GetExportedObject(dbus::ObjectPath("/path")))
  177. .WillOnce(testing::Return(mock_exported_object));
  178. EXPECT_CALL(*mock_exported_object,
  179. ExportMethod(dbus::kDBusObjectManagerInterface,
  180. dbus::kDBusObjectManagerGetManagedObjects,
  181. testing::_, testing::_));
  182. }
  183. void SetupExpectedMockAdvertisementMonitorDbusCalls(
  184. dbus::MockBus* mock_bus,
  185. dbus::MockExportedObject* mock_exported_object,
  186. dbus::ObjectPath monitor_object_path) {
  187. EXPECT_CALL(*mock_bus, GetExportedObject(monitor_object_path))
  188. .WillOnce(testing::Return(mock_exported_object));
  189. EXPECT_CALL(*mock_exported_object,
  190. ExportMethod(bluetooth_advertisement_monitor::
  191. kBluetoothAdvertisementMonitorInterface,
  192. bluetooth_advertisement_monitor::kDeviceLost,
  193. testing::_, testing::_));
  194. EXPECT_CALL(*mock_exported_object,
  195. ExportMethod(bluetooth_advertisement_monitor::
  196. kBluetoothAdvertisementMonitorInterface,
  197. bluetooth_advertisement_monitor::kDeviceFound,
  198. testing::_, testing::_));
  199. EXPECT_CALL(*mock_exported_object,
  200. ExportMethod(bluetooth_advertisement_monitor::
  201. kBluetoothAdvertisementMonitorInterface,
  202. bluetooth_advertisement_monitor::kActivate,
  203. testing::_, testing::_));
  204. EXPECT_CALL(*mock_exported_object,
  205. ExportMethod(bluetooth_advertisement_monitor::
  206. kBluetoothAdvertisementMonitorInterface,
  207. bluetooth_advertisement_monitor::kRelease,
  208. testing::_, testing::_));
  209. }
  210. } // namespace
  211. TEST(BluetoothAdvertisementMonitorApplicationServiceProviderImplTest,
  212. AddMonitorThenRemoveMonitor) {
  213. dbus::Bus::Options options;
  214. options.bus_type = dbus::Bus::SYSTEM;
  215. scoped_refptr<dbus::MockBus> mock_bus = new dbus::MockBus(options);
  216. dbus::ObjectPath application_object_path = dbus::ObjectPath("/path");
  217. scoped_refptr<dbus::MockExportedObject> mock_exported_object =
  218. new dbus::MockExportedObject(/*bus=*/mock_bus.get(),
  219. application_object_path);
  220. SetUpMocksDbus(mock_bus.get(), mock_exported_object.get());
  221. BluetoothAdvertisementMonitorApplicationServiceProviderImpl provider_impl(
  222. /*bus=*/mock_bus.get(),
  223. /*object_path=*/application_object_path);
  224. dbus::ObjectPath monitor_object_path = dbus::ObjectPath("/path/monitor1");
  225. FakeBluetoothLowEnergyScanSessionDelegate delegate;
  226. auto low_energy_scan_session =
  227. std::make_unique<BluetoothLowEnergyScanSessionBlueZ>(
  228. monitor_object_path.value(), nullptr, delegate.GetWeakPtr(),
  229. base::DoNothing());
  230. std::vector<uint8_t> pattern_value(std::begin(kPatternValue),
  231. std::end(kPatternValue));
  232. device::BluetoothLowEnergyScanFilter::Pattern pattern(
  233. /*start_position=*/0,
  234. device::BluetoothLowEnergyScanFilter::AdvertisementDataType::kServiceData,
  235. std::move(pattern_value));
  236. auto filter = device::BluetoothLowEnergyScanFilter::Create(
  237. device::BluetoothLowEnergyScanFilter::Range::kNear, kDeviceFoundTimeout,
  238. kDeviceLostTimeout, {pattern}, /*rssi_sampling_period=*/absl::nullopt);
  239. SetupExpectedMockAdvertisementMonitorDbusCalls(
  240. mock_bus.get(), mock_exported_object.get(), monitor_object_path);
  241. auto advertisement_monitor =
  242. std::make_unique<BluetoothAdvertisementMonitorServiceProviderImpl>(
  243. mock_bus.get(), monitor_object_path, std::move(filter),
  244. low_energy_scan_session->GetWeakPtr());
  245. dbus::MethodCall method_call("com.example.Interface", "SomeMethod");
  246. // Not setting the serial causes a crash.
  247. method_call.SetSerial(123);
  248. provider_impl.GetManagedObjects(
  249. &method_call, base::BindOnce(&ResponseSenderCallback, kExpectedMessage1));
  250. ON_CALL(*mock_exported_object, SendSignal(testing::_))
  251. .WillByDefault(testing::Invoke(
  252. [](dbus::Signal* signal) { SendSignal(kExpectedMessage3, signal); }));
  253. EXPECT_CALL(*mock_exported_object, SendSignal(testing::_));
  254. provider_impl.AddMonitor(std::move(advertisement_monitor));
  255. provider_impl.GetManagedObjects(
  256. &method_call, base::BindOnce(&ResponseSenderCallback, kExpectedMessage2));
  257. ON_CALL(*mock_exported_object, SendSignal(testing::_))
  258. .WillByDefault(testing::Invoke(
  259. [](dbus::Signal* signal) { SendSignal(kExpectedMessage4, signal); }));
  260. EXPECT_CALL(*mock_exported_object, SendSignal(testing::_));
  261. provider_impl.RemoveMonitor(monitor_object_path);
  262. provider_impl.GetManagedObjects(
  263. &method_call, base::BindOnce(&ResponseSenderCallback, kExpectedMessage1));
  264. }
  265. TEST(BluetoothAdvertisementMonitorApplicationServiceProviderImplTest,
  266. RemoveFailure) {
  267. dbus::Bus::Options options;
  268. options.bus_type = dbus::Bus::SYSTEM;
  269. scoped_refptr<dbus::MockBus> mock_bus = new dbus::MockBus(options);
  270. dbus::ObjectPath application_object_path = dbus::ObjectPath("/path");
  271. scoped_refptr<dbus::MockExportedObject> mock_exported_object =
  272. new dbus::MockExportedObject(/*bus=*/mock_bus.get(),
  273. application_object_path);
  274. SetUpMocksDbus(mock_bus.get(), mock_exported_object.get());
  275. BluetoothAdvertisementMonitorApplicationServiceProviderImpl provider_impl(
  276. /*bus=*/mock_bus.get(),
  277. /*object_path=*/application_object_path);
  278. dbus::ObjectPath monitor_object_path = dbus::ObjectPath("/path/monitor1");
  279. EXPECT_CALL(*mock_exported_object, SendSignal(testing::_)).Times(0);
  280. provider_impl.RemoveMonitor(monitor_object_path);
  281. }
  282. } // namespace bluez