platform_sensor_and_provider_unittest.cc 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430
  1. // Copyright 2017 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 <memory>
  5. #include "services/device/generic_sensor/platform_sensor_provider.h"
  6. #include "base/bind.h"
  7. #include "base/memory/read_only_shared_memory_region.h"
  8. #include "base/memory/shared_memory_mapping.h"
  9. #include "base/test/task_environment.h"
  10. #include "base/test/test_future.h"
  11. #include "services/device/generic_sensor/fake_platform_sensor_and_provider.h"
  12. #include "services/device/generic_sensor/generic_sensor_consts.h"
  13. #include "services/device/generic_sensor/platform_sensor_util.h"
  14. #include "services/device/public/cpp/generic_sensor/platform_sensor_configuration.h"
  15. #include "services/device/public/cpp/generic_sensor/sensor_reading.h"
  16. #include "testing/gtest/include/gtest/gtest.h"
  17. using ::testing::_;
  18. using ::testing::Invoke;
  19. using ::testing::NiceMock;
  20. namespace device {
  21. using mojom::SensorType;
  22. namespace {
  23. // Attempts to add a new reading to the sensor owned by |sensor_client|, and
  24. // asserts that it does not lead to OnSensorReadingChanged() being called (i.e.
  25. // PlatformSensor's significance check has failed).
  26. void AddNewReadingAndExpectNoReadingChangedEvent(
  27. MockPlatformSensorClient* sensor_client,
  28. const SensorReading& new_reading) {
  29. scoped_refptr<FakePlatformSensor> fake_sensor =
  30. static_cast<FakePlatformSensor*>(sensor_client->sensor().get());
  31. fake_sensor->AddNewReading(new_reading);
  32. base::RunLoop run_loop;
  33. EXPECT_CALL(*sensor_client,
  34. OnSensorReadingChanged(sensor_client->sensor()->GetType()))
  35. .Times(0);
  36. run_loop.RunUntilIdle();
  37. }
  38. // Add a new reading to the sensor owned by |sensor_client|, and expect reading
  39. // change event.
  40. void AddNewReadingAndExpectReadingChangedEvent(
  41. MockPlatformSensorClient* sensor_client,
  42. const SensorReading& new_reading) {
  43. scoped_refptr<FakePlatformSensor> fake_sensor =
  44. static_cast<FakePlatformSensor*>(sensor_client->sensor().get());
  45. fake_sensor->AddNewReading(new_reading);
  46. base::RunLoop run_loop;
  47. EXPECT_CALL(*sensor_client,
  48. OnSensorReadingChanged(sensor_client->sensor()->GetType()))
  49. .WillOnce(Invoke([&](SensorType) { run_loop.Quit(); }));
  50. run_loop.Run();
  51. }
  52. } // namespace
  53. class PlatformSensorAndProviderTest : public testing::Test {
  54. public:
  55. PlatformSensorAndProviderTest() {
  56. provider_ = std::make_unique<FakePlatformSensorProvider>();
  57. }
  58. PlatformSensorAndProviderTest(const PlatformSensorAndProviderTest&) = delete;
  59. PlatformSensorAndProviderTest& operator=(
  60. const PlatformSensorAndProviderTest&) = delete;
  61. protected:
  62. scoped_refptr<FakePlatformSensor> CreateSensorSync(mojom::SensorType type) {
  63. base::test::TestFuture<scoped_refptr<PlatformSensor>> future;
  64. provider_->CreateSensor(type, future.GetCallback());
  65. scoped_refptr<FakePlatformSensor> fake_sensor =
  66. static_cast<FakePlatformSensor*>(future.Get().get());
  67. // Override FakePlatformSensor's default StartSensor() expectation; we
  68. // do not want to do anything in StartSensor().
  69. ON_CALL(*fake_sensor, StartSensor(_))
  70. .WillByDefault(
  71. Invoke([&](const PlatformSensorConfiguration& configuration) {
  72. return true;
  73. }));
  74. return fake_sensor;
  75. }
  76. std::unique_ptr<FakePlatformSensorProvider> provider_;
  77. private:
  78. base::test::TaskEnvironment task_environment_;
  79. };
  80. TEST_F(PlatformSensorAndProviderTest, ResourcesAreFreed) {
  81. EXPECT_CALL(*provider_, FreeResources()).Times(2);
  82. provider_->CreateSensor(
  83. mojom::SensorType::AMBIENT_LIGHT,
  84. base::BindOnce([](scoped_refptr<PlatformSensor> s) { EXPECT_TRUE(s); }));
  85. // Failure.
  86. EXPECT_CALL(*provider_, DoCreateSensorInternal(_, _, _))
  87. .WillOnce(
  88. Invoke([](mojom::SensorType, scoped_refptr<PlatformSensor>,
  89. PlatformSensorProvider::CreateSensorCallback callback) {
  90. std::move(callback).Run(nullptr);
  91. }));
  92. provider_->CreateSensor(
  93. mojom::SensorType::AMBIENT_LIGHT,
  94. base::BindOnce([](scoped_refptr<PlatformSensor> s) { EXPECT_FALSE(s); }));
  95. }
  96. TEST_F(PlatformSensorAndProviderTest, ResourcesAreNotFreedOnPendingRequest) {
  97. EXPECT_CALL(*provider_, FreeResources()).Times(0);
  98. // Suspend.
  99. EXPECT_CALL(*provider_, DoCreateSensorInternal(_, _, _))
  100. .WillOnce(Invoke([](mojom::SensorType, scoped_refptr<PlatformSensor>,
  101. PlatformSensorProvider::CreateSensorCallback) {}));
  102. provider_->CreateSensor(
  103. mojom::SensorType::AMBIENT_LIGHT,
  104. base::BindOnce([](scoped_refptr<PlatformSensor> s) { NOTREACHED(); }));
  105. provider_->CreateSensor(
  106. mojom::SensorType::AMBIENT_LIGHT,
  107. base::BindOnce([](scoped_refptr<PlatformSensor> s) { NOTREACHED(); }));
  108. }
  109. // This test verifies that the shared buffer's default values are 0.
  110. TEST_F(PlatformSensorAndProviderTest, SharedBufferDefaultValue) {
  111. base::ReadOnlySharedMemoryRegion region =
  112. provider_->CloneSharedMemoryRegion();
  113. base::ReadOnlySharedMemoryMapping mapping = region.MapAt(
  114. SensorReadingSharedBuffer::GetOffset(mojom::SensorType::AMBIENT_LIGHT),
  115. sizeof(SensorReadingSharedBuffer));
  116. const SensorReadingSharedBuffer* buffer =
  117. static_cast<const SensorReadingSharedBuffer*>(mapping.memory());
  118. EXPECT_THAT(buffer->reading.als.value, 0);
  119. }
  120. // This test verifies that when sensor is stopped, shared buffer contents are
  121. // filled with default values.
  122. TEST_F(PlatformSensorAndProviderTest, SharedBufferCleared) {
  123. provider_->CreateSensor(
  124. mojom::SensorType::AMBIENT_LIGHT,
  125. base::BindOnce([](scoped_refptr<PlatformSensor> sensor) {
  126. auto client =
  127. std::make_unique<NiceMock<MockPlatformSensorClient>>(sensor);
  128. auto config = PlatformSensorConfiguration(50);
  129. EXPECT_TRUE(sensor->StartListening(client.get(), config));
  130. SensorReading reading;
  131. EXPECT_TRUE(sensor->GetLatestReading(&reading));
  132. EXPECT_THAT(reading.als.value, 50);
  133. EXPECT_TRUE(sensor->StopListening(client.get(), config));
  134. EXPECT_TRUE(sensor->GetLatestReading(&reading));
  135. EXPECT_THAT(reading.als.value, 0);
  136. }));
  137. }
  138. // Rounding to nearest 50 (see kAlsRoundingMultiple). 25 (see
  139. // kAlsSignificanceThreshold) difference in values reported in significance
  140. // test, if rounded values differs from previous rounded value.
  141. TEST_F(PlatformSensorAndProviderTest, SensorValueValidityCheckAmbientLight) {
  142. scoped_refptr<FakePlatformSensor> fake_sensor =
  143. CreateSensorSync(SensorType::AMBIENT_LIGHT);
  144. auto client = std::make_unique<MockPlatformSensorClient>(fake_sensor);
  145. EXPECT_TRUE(fake_sensor->StartListening(client.get(),
  146. PlatformSensorConfiguration(10)));
  147. // This checks that illuminance significance check causes the following
  148. // to happen:
  149. // 1. Initial value is set to 24. And test checks it is correctly rounded
  150. // to 0.
  151. // 2. New reading is attempted to set to 35.
  152. // 3. Value is read from sensor and compared new reading. But as new
  153. // reading was not significantly different compared to initial, for
  154. // privacy reasons, service returns the initial value.
  155. // 4. New value is set to 49. And test checks it is correctly rounded to 50.
  156. // New value is allowed as it is significantly different compared to old
  157. // value (24).
  158. // 5. New reading is attempted to set to 35.
  159. // 6. Value is read from sensor and compared new reading. But as new
  160. // reading was not significantly different compared to initial, for
  161. // privacy reasons, service returns the initial value.
  162. // 7. New value is set to 24. And test checks it is correctly rounded to 0.
  163. // New value is allowed as it is significantly different compared to old
  164. // value (49).
  165. // 8. Last two values test that if rounded values are same, new reading event
  166. // is not triggered.
  167. const struct {
  168. const double attempted_als_value;
  169. const double expected_als_value;
  170. const bool expect_reading_changed_event;
  171. } kTestSteps[] = {
  172. {24, 0, true}, {35, 0, false}, {49, 50, true}, {35, 50, false},
  173. {24, 0, true}, {50, 50, true}, {25, 50, false},
  174. };
  175. for (const auto& test_case : kTestSteps) {
  176. SensorReading reading;
  177. reading.raw.timestamp = 1.0;
  178. reading.als.value = test_case.attempted_als_value;
  179. if (test_case.expect_reading_changed_event)
  180. AddNewReadingAndExpectReadingChangedEvent(client.get(), reading);
  181. else
  182. AddNewReadingAndExpectNoReadingChangedEvent(client.get(), reading);
  183. fake_sensor->GetLatestReading(&reading);
  184. EXPECT_DOUBLE_EQ(reading.als.value, test_case.expected_als_value);
  185. }
  186. }
  187. // No rounding of values. Any change in values reported in significance test.
  188. TEST_F(PlatformSensorAndProviderTest, SensorValueValidityCheckPressure) {
  189. const double kTestValue = 10.0; // Made up test value.
  190. scoped_refptr<FakePlatformSensor> fake_sensor =
  191. CreateSensorSync(SensorType::PRESSURE);
  192. auto client = std::make_unique<MockPlatformSensorClient>(fake_sensor);
  193. EXPECT_TRUE(fake_sensor->StartListening(client.get(),
  194. PlatformSensorConfiguration(10)));
  195. // Test cases:
  196. // 1. Initial value is set to 10.
  197. // 2. As new reading is exactly same as old new reading event is not
  198. // triggered.
  199. // 3. New value set and reading event is triggered as new value is
  200. // significantly different compared to old.
  201. const struct {
  202. const double pressure_value;
  203. const bool expect_reading_changed_event;
  204. } kTestSteps[] = {
  205. {kTestValue, true},
  206. {kTestValue, false},
  207. {kTestValue + kEpsilon, true},
  208. };
  209. for (const auto& test_case : kTestSteps) {
  210. SensorReading reading;
  211. reading.raw.timestamp = 1.0;
  212. reading.pressure.value = test_case.pressure_value;
  213. if (test_case.expect_reading_changed_event)
  214. AddNewReadingAndExpectReadingChangedEvent(client.get(), reading);
  215. else
  216. AddNewReadingAndExpectNoReadingChangedEvent(client.get(), reading);
  217. fake_sensor->GetLatestReading(&reading);
  218. EXPECT_DOUBLE_EQ(reading.pressure.value, test_case.pressure_value);
  219. }
  220. }
  221. // Rounding to nearest 0.1 (see kAccelerometerRoundingMultiple). New reading
  222. // event is triggered if rounded values differs from previous rounded value.
  223. TEST_F(PlatformSensorAndProviderTest, SensorValueValidityCheckAccelerometer) {
  224. const double kTestValue = 10.0; // Made up test value.
  225. scoped_refptr<FakePlatformSensor> fake_sensor =
  226. CreateSensorSync(SensorType::ACCELEROMETER);
  227. auto client = std::make_unique<MockPlatformSensorClient>(fake_sensor);
  228. EXPECT_TRUE(fake_sensor->StartListening(client.get(),
  229. PlatformSensorConfiguration(10)));
  230. const struct {
  231. const double attempted_accelerometer_value_x;
  232. const double expected_accelerometer_value;
  233. const bool expect_reading_changed_event;
  234. } kTestSteps[] = {
  235. {kTestValue, kTestValue, true},
  236. {kTestValue, kTestValue, false},
  237. {kTestValue + kEpsilon, kTestValue, false},
  238. {kTestValue + kAccelerometerRoundingMultiple - kEpsilon,
  239. kTestValue + kAccelerometerRoundingMultiple, true},
  240. {kTestValue + kAccelerometerRoundingMultiple + kEpsilon,
  241. kTestValue + kAccelerometerRoundingMultiple, false},
  242. };
  243. for (const auto& test_case : kTestSteps) {
  244. SensorReading reading;
  245. reading.raw.timestamp = 1.0;
  246. reading.accel.x = test_case.attempted_accelerometer_value_x;
  247. reading.accel.y = reading.accel.z = 0;
  248. if (test_case.expect_reading_changed_event)
  249. AddNewReadingAndExpectReadingChangedEvent(client.get(), reading);
  250. else
  251. AddNewReadingAndExpectNoReadingChangedEvent(client.get(), reading);
  252. fake_sensor->GetLatestReading(&reading);
  253. EXPECT_DOUBLE_EQ(reading.accel.x, test_case.expected_accelerometer_value);
  254. }
  255. }
  256. TEST_F(PlatformSensorAndProviderTest, IsSignificantlyDifferentAmbientLight) {
  257. // Test for AMBIENT_LIGHT as it has different significance threshold compared
  258. // to others.
  259. const double kTestValue = 100.0; // Made up test value.
  260. scoped_refptr<FakePlatformSensor> fake_sensor =
  261. CreateSensorSync(SensorType::AMBIENT_LIGHT);
  262. auto client = std::make_unique<MockPlatformSensorClient>(fake_sensor);
  263. EXPECT_TRUE(fake_sensor->StartListening(client.get(),
  264. PlatformSensorConfiguration(10)));
  265. // Ambient light sensor has threshold points around initial_reading.
  266. // IsSignificantlyDifferent() returns false when value is located between
  267. // upper and lower threshold point and true when it is outside of threshold
  268. // points. Below text shows these threshold points and different areas.
  269. //
  270. // Smaller value Large values
  271. // [--------------X--------------]
  272. // (1) (2) (3) (4) (5) (6) (7)
  273. //
  274. // Selected test values are:
  275. // 1. just below lower threshold point in significantly different lower area
  276. // 2. lower threshold point
  277. // 3. just above lower threshold point in not significantly different area
  278. // 4. center (new reading is same as initial reading)
  279. // 5. just below upper threshold point in not significantly different area
  280. // 6. upper threshold point
  281. // 7. just above upper threshold point in significantly different upper area
  282. const struct {
  283. const bool expectation;
  284. const double new_reading;
  285. } kTestSteps[] = {
  286. {true, kTestValue - kAlsSignificanceThreshold - 1},
  287. {true, kTestValue - kAlsSignificanceThreshold},
  288. {false, kTestValue - kAlsSignificanceThreshold + 1},
  289. {false, kTestValue},
  290. {false, kTestValue + kAlsSignificanceThreshold - 1},
  291. {true, kTestValue + kAlsSignificanceThreshold},
  292. {true, kTestValue + kAlsSignificanceThreshold + 1},
  293. };
  294. SensorReading initial_reading;
  295. initial_reading.als.value = kTestValue;
  296. for (const auto& test_case : kTestSteps) {
  297. SensorReading new_reading;
  298. new_reading.als.value = test_case.new_reading;
  299. EXPECT_THAT(fake_sensor->IsSignificantlyDifferent(
  300. initial_reading, new_reading, SensorType::AMBIENT_LIGHT),
  301. test_case.expectation);
  302. }
  303. }
  304. TEST_F(PlatformSensorAndProviderTest, IsSignificantlyDifferentPressure) {
  305. // Test for standard sensor with single value.
  306. scoped_refptr<FakePlatformSensor> fake_sensor =
  307. CreateSensorSync(SensorType::PRESSURE);
  308. auto client = std::make_unique<MockPlatformSensorClient>(fake_sensor);
  309. EXPECT_TRUE(fake_sensor->StartListening(client.get(),
  310. PlatformSensorConfiguration(10)));
  311. const double kTestValue = 100.0; // Made up test value.
  312. SensorReading last_reading;
  313. SensorReading new_reading;
  314. // No difference in values does not count as a significant change.
  315. last_reading.pressure.value = kTestValue;
  316. EXPECT_FALSE(fake_sensor->IsSignificantlyDifferent(last_reading, last_reading,
  317. SensorType::PRESSURE));
  318. // Check that different values are reported as significantly different.
  319. new_reading.pressure.value = last_reading.pressure.value + kEpsilon;
  320. EXPECT_TRUE(fake_sensor->IsSignificantlyDifferent(last_reading, new_reading,
  321. SensorType::PRESSURE));
  322. // Check that different values are reported as significantly different.
  323. new_reading.pressure.value = last_reading.pressure.value - kEpsilon;
  324. EXPECT_TRUE(fake_sensor->IsSignificantlyDifferent(last_reading, new_reading,
  325. SensorType::PRESSURE));
  326. }
  327. TEST_F(PlatformSensorAndProviderTest, IsSignificantlyDifferentMagnetometer) {
  328. // Test for standard sensor with three values.
  329. scoped_refptr<FakePlatformSensor> fake_sensor =
  330. CreateSensorSync(SensorType::MAGNETOMETER);
  331. auto client = std::make_unique<MockPlatformSensorClient>(fake_sensor);
  332. EXPECT_TRUE(fake_sensor->StartListening(client.get(),
  333. PlatformSensorConfiguration(10)));
  334. const double kTestValue = 100.0; // Made up test value.
  335. SensorReading last_reading;
  336. SensorReading new_reading;
  337. // No difference in values does not count as a significant change.
  338. last_reading.magn.x = kTestValue;
  339. last_reading.magn.y = kTestValue;
  340. last_reading.magn.z = kTestValue;
  341. EXPECT_FALSE(fake_sensor->IsSignificantlyDifferent(last_reading, last_reading,
  342. SensorType::MAGNETOMETER));
  343. // Check that different values on one axis are reported as significantly
  344. // different.
  345. new_reading.magn.x = last_reading.magn.x;
  346. new_reading.magn.y = last_reading.magn.y + kEpsilon;
  347. new_reading.magn.z = last_reading.magn.z;
  348. EXPECT_TRUE(fake_sensor->IsSignificantlyDifferent(last_reading, new_reading,
  349. SensorType::MAGNETOMETER));
  350. // Check that different values on all axes are reported as significantly
  351. // different.
  352. new_reading.magn.x = last_reading.magn.x + kEpsilon;
  353. new_reading.magn.y = last_reading.magn.y + kEpsilon;
  354. new_reading.magn.z = last_reading.magn.z + kEpsilon;
  355. EXPECT_TRUE(fake_sensor->IsSignificantlyDifferent(last_reading, new_reading,
  356. SensorType::MAGNETOMETER));
  357. // Check that different values on all axes are reported as significantly
  358. // different.
  359. new_reading.magn.x = last_reading.magn.x - kEpsilon;
  360. new_reading.magn.y = last_reading.magn.y - kEpsilon;
  361. new_reading.magn.z = last_reading.magn.z - kEpsilon;
  362. EXPECT_TRUE(fake_sensor->IsSignificantlyDifferent(last_reading, new_reading,
  363. SensorType::MAGNETOMETER));
  364. }
  365. } // namespace device