123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430 |
- // Copyright 2017 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include <memory>
- #include "services/device/generic_sensor/platform_sensor_provider.h"
- #include "base/bind.h"
- #include "base/memory/read_only_shared_memory_region.h"
- #include "base/memory/shared_memory_mapping.h"
- #include "base/test/task_environment.h"
- #include "base/test/test_future.h"
- #include "services/device/generic_sensor/fake_platform_sensor_and_provider.h"
- #include "services/device/generic_sensor/generic_sensor_consts.h"
- #include "services/device/generic_sensor/platform_sensor_util.h"
- #include "services/device/public/cpp/generic_sensor/platform_sensor_configuration.h"
- #include "services/device/public/cpp/generic_sensor/sensor_reading.h"
- #include "testing/gtest/include/gtest/gtest.h"
- using ::testing::_;
- using ::testing::Invoke;
- using ::testing::NiceMock;
- namespace device {
- using mojom::SensorType;
- namespace {
- // Attempts to add a new reading to the sensor owned by |sensor_client|, and
- // asserts that it does not lead to OnSensorReadingChanged() being called (i.e.
- // PlatformSensor's significance check has failed).
- void AddNewReadingAndExpectNoReadingChangedEvent(
- MockPlatformSensorClient* sensor_client,
- const SensorReading& new_reading) {
- scoped_refptr<FakePlatformSensor> fake_sensor =
- static_cast<FakePlatformSensor*>(sensor_client->sensor().get());
- fake_sensor->AddNewReading(new_reading);
- base::RunLoop run_loop;
- EXPECT_CALL(*sensor_client,
- OnSensorReadingChanged(sensor_client->sensor()->GetType()))
- .Times(0);
- run_loop.RunUntilIdle();
- }
- // Add a new reading to the sensor owned by |sensor_client|, and expect reading
- // change event.
- void AddNewReadingAndExpectReadingChangedEvent(
- MockPlatformSensorClient* sensor_client,
- const SensorReading& new_reading) {
- scoped_refptr<FakePlatformSensor> fake_sensor =
- static_cast<FakePlatformSensor*>(sensor_client->sensor().get());
- fake_sensor->AddNewReading(new_reading);
- base::RunLoop run_loop;
- EXPECT_CALL(*sensor_client,
- OnSensorReadingChanged(sensor_client->sensor()->GetType()))
- .WillOnce(Invoke([&](SensorType) { run_loop.Quit(); }));
- run_loop.Run();
- }
- } // namespace
- class PlatformSensorAndProviderTest : public testing::Test {
- public:
- PlatformSensorAndProviderTest() {
- provider_ = std::make_unique<FakePlatformSensorProvider>();
- }
- PlatformSensorAndProviderTest(const PlatformSensorAndProviderTest&) = delete;
- PlatformSensorAndProviderTest& operator=(
- const PlatformSensorAndProviderTest&) = delete;
- protected:
- scoped_refptr<FakePlatformSensor> CreateSensorSync(mojom::SensorType type) {
- base::test::TestFuture<scoped_refptr<PlatformSensor>> future;
- provider_->CreateSensor(type, future.GetCallback());
- scoped_refptr<FakePlatformSensor> fake_sensor =
- static_cast<FakePlatformSensor*>(future.Get().get());
- // Override FakePlatformSensor's default StartSensor() expectation; we
- // do not want to do anything in StartSensor().
- ON_CALL(*fake_sensor, StartSensor(_))
- .WillByDefault(
- Invoke([&](const PlatformSensorConfiguration& configuration) {
- return true;
- }));
- return fake_sensor;
- }
- std::unique_ptr<FakePlatformSensorProvider> provider_;
- private:
- base::test::TaskEnvironment task_environment_;
- };
- TEST_F(PlatformSensorAndProviderTest, ResourcesAreFreed) {
- EXPECT_CALL(*provider_, FreeResources()).Times(2);
- provider_->CreateSensor(
- mojom::SensorType::AMBIENT_LIGHT,
- base::BindOnce([](scoped_refptr<PlatformSensor> s) { EXPECT_TRUE(s); }));
- // Failure.
- EXPECT_CALL(*provider_, DoCreateSensorInternal(_, _, _))
- .WillOnce(
- Invoke([](mojom::SensorType, scoped_refptr<PlatformSensor>,
- PlatformSensorProvider::CreateSensorCallback callback) {
- std::move(callback).Run(nullptr);
- }));
- provider_->CreateSensor(
- mojom::SensorType::AMBIENT_LIGHT,
- base::BindOnce([](scoped_refptr<PlatformSensor> s) { EXPECT_FALSE(s); }));
- }
- TEST_F(PlatformSensorAndProviderTest, ResourcesAreNotFreedOnPendingRequest) {
- EXPECT_CALL(*provider_, FreeResources()).Times(0);
- // Suspend.
- EXPECT_CALL(*provider_, DoCreateSensorInternal(_, _, _))
- .WillOnce(Invoke([](mojom::SensorType, scoped_refptr<PlatformSensor>,
- PlatformSensorProvider::CreateSensorCallback) {}));
- provider_->CreateSensor(
- mojom::SensorType::AMBIENT_LIGHT,
- base::BindOnce([](scoped_refptr<PlatformSensor> s) { NOTREACHED(); }));
- provider_->CreateSensor(
- mojom::SensorType::AMBIENT_LIGHT,
- base::BindOnce([](scoped_refptr<PlatformSensor> s) { NOTREACHED(); }));
- }
- // This test verifies that the shared buffer's default values are 0.
- TEST_F(PlatformSensorAndProviderTest, SharedBufferDefaultValue) {
- base::ReadOnlySharedMemoryRegion region =
- provider_->CloneSharedMemoryRegion();
- base::ReadOnlySharedMemoryMapping mapping = region.MapAt(
- SensorReadingSharedBuffer::GetOffset(mojom::SensorType::AMBIENT_LIGHT),
- sizeof(SensorReadingSharedBuffer));
- const SensorReadingSharedBuffer* buffer =
- static_cast<const SensorReadingSharedBuffer*>(mapping.memory());
- EXPECT_THAT(buffer->reading.als.value, 0);
- }
- // This test verifies that when sensor is stopped, shared buffer contents are
- // filled with default values.
- TEST_F(PlatformSensorAndProviderTest, SharedBufferCleared) {
- provider_->CreateSensor(
- mojom::SensorType::AMBIENT_LIGHT,
- base::BindOnce([](scoped_refptr<PlatformSensor> sensor) {
- auto client =
- std::make_unique<NiceMock<MockPlatformSensorClient>>(sensor);
- auto config = PlatformSensorConfiguration(50);
- EXPECT_TRUE(sensor->StartListening(client.get(), config));
- SensorReading reading;
- EXPECT_TRUE(sensor->GetLatestReading(&reading));
- EXPECT_THAT(reading.als.value, 50);
- EXPECT_TRUE(sensor->StopListening(client.get(), config));
- EXPECT_TRUE(sensor->GetLatestReading(&reading));
- EXPECT_THAT(reading.als.value, 0);
- }));
- }
- // Rounding to nearest 50 (see kAlsRoundingMultiple). 25 (see
- // kAlsSignificanceThreshold) difference in values reported in significance
- // test, if rounded values differs from previous rounded value.
- TEST_F(PlatformSensorAndProviderTest, SensorValueValidityCheckAmbientLight) {
- scoped_refptr<FakePlatformSensor> fake_sensor =
- CreateSensorSync(SensorType::AMBIENT_LIGHT);
- auto client = std::make_unique<MockPlatformSensorClient>(fake_sensor);
- EXPECT_TRUE(fake_sensor->StartListening(client.get(),
- PlatformSensorConfiguration(10)));
- // This checks that illuminance significance check causes the following
- // to happen:
- // 1. Initial value is set to 24. And test checks it is correctly rounded
- // to 0.
- // 2. New reading is attempted to set to 35.
- // 3. Value is read from sensor and compared new reading. But as new
- // reading was not significantly different compared to initial, for
- // privacy reasons, service returns the initial value.
- // 4. New value is set to 49. And test checks it is correctly rounded to 50.
- // New value is allowed as it is significantly different compared to old
- // value (24).
- // 5. New reading is attempted to set to 35.
- // 6. Value is read from sensor and compared new reading. But as new
- // reading was not significantly different compared to initial, for
- // privacy reasons, service returns the initial value.
- // 7. New value is set to 24. And test checks it is correctly rounded to 0.
- // New value is allowed as it is significantly different compared to old
- // value (49).
- // 8. Last two values test that if rounded values are same, new reading event
- // is not triggered.
- const struct {
- const double attempted_als_value;
- const double expected_als_value;
- const bool expect_reading_changed_event;
- } kTestSteps[] = {
- {24, 0, true}, {35, 0, false}, {49, 50, true}, {35, 50, false},
- {24, 0, true}, {50, 50, true}, {25, 50, false},
- };
- for (const auto& test_case : kTestSteps) {
- SensorReading reading;
- reading.raw.timestamp = 1.0;
- reading.als.value = test_case.attempted_als_value;
- if (test_case.expect_reading_changed_event)
- AddNewReadingAndExpectReadingChangedEvent(client.get(), reading);
- else
- AddNewReadingAndExpectNoReadingChangedEvent(client.get(), reading);
- fake_sensor->GetLatestReading(&reading);
- EXPECT_DOUBLE_EQ(reading.als.value, test_case.expected_als_value);
- }
- }
- // No rounding of values. Any change in values reported in significance test.
- TEST_F(PlatformSensorAndProviderTest, SensorValueValidityCheckPressure) {
- const double kTestValue = 10.0; // Made up test value.
- scoped_refptr<FakePlatformSensor> fake_sensor =
- CreateSensorSync(SensorType::PRESSURE);
- auto client = std::make_unique<MockPlatformSensorClient>(fake_sensor);
- EXPECT_TRUE(fake_sensor->StartListening(client.get(),
- PlatformSensorConfiguration(10)));
- // Test cases:
- // 1. Initial value is set to 10.
- // 2. As new reading is exactly same as old new reading event is not
- // triggered.
- // 3. New value set and reading event is triggered as new value is
- // significantly different compared to old.
- const struct {
- const double pressure_value;
- const bool expect_reading_changed_event;
- } kTestSteps[] = {
- {kTestValue, true},
- {kTestValue, false},
- {kTestValue + kEpsilon, true},
- };
- for (const auto& test_case : kTestSteps) {
- SensorReading reading;
- reading.raw.timestamp = 1.0;
- reading.pressure.value = test_case.pressure_value;
- if (test_case.expect_reading_changed_event)
- AddNewReadingAndExpectReadingChangedEvent(client.get(), reading);
- else
- AddNewReadingAndExpectNoReadingChangedEvent(client.get(), reading);
- fake_sensor->GetLatestReading(&reading);
- EXPECT_DOUBLE_EQ(reading.pressure.value, test_case.pressure_value);
- }
- }
- // Rounding to nearest 0.1 (see kAccelerometerRoundingMultiple). New reading
- // event is triggered if rounded values differs from previous rounded value.
- TEST_F(PlatformSensorAndProviderTest, SensorValueValidityCheckAccelerometer) {
- const double kTestValue = 10.0; // Made up test value.
- scoped_refptr<FakePlatformSensor> fake_sensor =
- CreateSensorSync(SensorType::ACCELEROMETER);
- auto client = std::make_unique<MockPlatformSensorClient>(fake_sensor);
- EXPECT_TRUE(fake_sensor->StartListening(client.get(),
- PlatformSensorConfiguration(10)));
- const struct {
- const double attempted_accelerometer_value_x;
- const double expected_accelerometer_value;
- const bool expect_reading_changed_event;
- } kTestSteps[] = {
- {kTestValue, kTestValue, true},
- {kTestValue, kTestValue, false},
- {kTestValue + kEpsilon, kTestValue, false},
- {kTestValue + kAccelerometerRoundingMultiple - kEpsilon,
- kTestValue + kAccelerometerRoundingMultiple, true},
- {kTestValue + kAccelerometerRoundingMultiple + kEpsilon,
- kTestValue + kAccelerometerRoundingMultiple, false},
- };
- for (const auto& test_case : kTestSteps) {
- SensorReading reading;
- reading.raw.timestamp = 1.0;
- reading.accel.x = test_case.attempted_accelerometer_value_x;
- reading.accel.y = reading.accel.z = 0;
- if (test_case.expect_reading_changed_event)
- AddNewReadingAndExpectReadingChangedEvent(client.get(), reading);
- else
- AddNewReadingAndExpectNoReadingChangedEvent(client.get(), reading);
- fake_sensor->GetLatestReading(&reading);
- EXPECT_DOUBLE_EQ(reading.accel.x, test_case.expected_accelerometer_value);
- }
- }
- TEST_F(PlatformSensorAndProviderTest, IsSignificantlyDifferentAmbientLight) {
- // Test for AMBIENT_LIGHT as it has different significance threshold compared
- // to others.
- const double kTestValue = 100.0; // Made up test value.
- scoped_refptr<FakePlatformSensor> fake_sensor =
- CreateSensorSync(SensorType::AMBIENT_LIGHT);
- auto client = std::make_unique<MockPlatformSensorClient>(fake_sensor);
- EXPECT_TRUE(fake_sensor->StartListening(client.get(),
- PlatformSensorConfiguration(10)));
- // Ambient light sensor has threshold points around initial_reading.
- // IsSignificantlyDifferent() returns false when value is located between
- // upper and lower threshold point and true when it is outside of threshold
- // points. Below text shows these threshold points and different areas.
- //
- // Smaller value Large values
- // [--------------X--------------]
- // (1) (2) (3) (4) (5) (6) (7)
- //
- // Selected test values are:
- // 1. just below lower threshold point in significantly different lower area
- // 2. lower threshold point
- // 3. just above lower threshold point in not significantly different area
- // 4. center (new reading is same as initial reading)
- // 5. just below upper threshold point in not significantly different area
- // 6. upper threshold point
- // 7. just above upper threshold point in significantly different upper area
- const struct {
- const bool expectation;
- const double new_reading;
- } kTestSteps[] = {
- {true, kTestValue - kAlsSignificanceThreshold - 1},
- {true, kTestValue - kAlsSignificanceThreshold},
- {false, kTestValue - kAlsSignificanceThreshold + 1},
- {false, kTestValue},
- {false, kTestValue + kAlsSignificanceThreshold - 1},
- {true, kTestValue + kAlsSignificanceThreshold},
- {true, kTestValue + kAlsSignificanceThreshold + 1},
- };
- SensorReading initial_reading;
- initial_reading.als.value = kTestValue;
- for (const auto& test_case : kTestSteps) {
- SensorReading new_reading;
- new_reading.als.value = test_case.new_reading;
- EXPECT_THAT(fake_sensor->IsSignificantlyDifferent(
- initial_reading, new_reading, SensorType::AMBIENT_LIGHT),
- test_case.expectation);
- }
- }
- TEST_F(PlatformSensorAndProviderTest, IsSignificantlyDifferentPressure) {
- // Test for standard sensor with single value.
- scoped_refptr<FakePlatformSensor> fake_sensor =
- CreateSensorSync(SensorType::PRESSURE);
- auto client = std::make_unique<MockPlatformSensorClient>(fake_sensor);
- EXPECT_TRUE(fake_sensor->StartListening(client.get(),
- PlatformSensorConfiguration(10)));
- const double kTestValue = 100.0; // Made up test value.
- SensorReading last_reading;
- SensorReading new_reading;
- // No difference in values does not count as a significant change.
- last_reading.pressure.value = kTestValue;
- EXPECT_FALSE(fake_sensor->IsSignificantlyDifferent(last_reading, last_reading,
- SensorType::PRESSURE));
- // Check that different values are reported as significantly different.
- new_reading.pressure.value = last_reading.pressure.value + kEpsilon;
- EXPECT_TRUE(fake_sensor->IsSignificantlyDifferent(last_reading, new_reading,
- SensorType::PRESSURE));
- // Check that different values are reported as significantly different.
- new_reading.pressure.value = last_reading.pressure.value - kEpsilon;
- EXPECT_TRUE(fake_sensor->IsSignificantlyDifferent(last_reading, new_reading,
- SensorType::PRESSURE));
- }
- TEST_F(PlatformSensorAndProviderTest, IsSignificantlyDifferentMagnetometer) {
- // Test for standard sensor with three values.
- scoped_refptr<FakePlatformSensor> fake_sensor =
- CreateSensorSync(SensorType::MAGNETOMETER);
- auto client = std::make_unique<MockPlatformSensorClient>(fake_sensor);
- EXPECT_TRUE(fake_sensor->StartListening(client.get(),
- PlatformSensorConfiguration(10)));
- const double kTestValue = 100.0; // Made up test value.
- SensorReading last_reading;
- SensorReading new_reading;
- // No difference in values does not count as a significant change.
- last_reading.magn.x = kTestValue;
- last_reading.magn.y = kTestValue;
- last_reading.magn.z = kTestValue;
- EXPECT_FALSE(fake_sensor->IsSignificantlyDifferent(last_reading, last_reading,
- SensorType::MAGNETOMETER));
- // Check that different values on one axis are reported as significantly
- // different.
- new_reading.magn.x = last_reading.magn.x;
- new_reading.magn.y = last_reading.magn.y + kEpsilon;
- new_reading.magn.z = last_reading.magn.z;
- EXPECT_TRUE(fake_sensor->IsSignificantlyDifferent(last_reading, new_reading,
- SensorType::MAGNETOMETER));
- // Check that different values on all axes are reported as significantly
- // different.
- new_reading.magn.x = last_reading.magn.x + kEpsilon;
- new_reading.magn.y = last_reading.magn.y + kEpsilon;
- new_reading.magn.z = last_reading.magn.z + kEpsilon;
- EXPECT_TRUE(fake_sensor->IsSignificantlyDifferent(last_reading, new_reading,
- SensorType::MAGNETOMETER));
- // Check that different values on all axes are reported as significantly
- // different.
- new_reading.magn.x = last_reading.magn.x - kEpsilon;
- new_reading.magn.y = last_reading.magn.y - kEpsilon;
- new_reading.magn.z = last_reading.magn.z - kEpsilon;
- EXPECT_TRUE(fake_sensor->IsSignificantlyDifferent(last_reading, new_reading,
- SensorType::MAGNETOMETER));
- }
- } // namespace device
|