123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612 |
- // 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 "base/bind.h"
- #include "base/callback_helpers.h"
- #include "base/memory/ref_counted.h"
- #include "base/run_loop.h"
- #include "base/test/task_environment.h"
- #include "base/test/test_future.h"
- #include "services/device/generic_sensor/absolute_orientation_euler_angles_fusion_algorithm_using_accelerometer_and_magnetometer.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/linear_acceleration_fusion_algorithm_using_accelerometer.h"
- #include "services/device/generic_sensor/platform_sensor.h"
- #include "services/device/generic_sensor/platform_sensor_fusion.h"
- #include "services/device/generic_sensor/platform_sensor_fusion_algorithm.h"
- #include "services/device/generic_sensor/platform_sensor_provider.h"
- #include "testing/gtest/include/gtest/gtest.h"
- using ::testing::_;
- using ::testing::Invoke;
- using ::testing::Return;
- namespace device {
- using mojom::SensorType;
- namespace {
- void ExpectNoReadingChangedEvent(MockPlatformSensorClient* sensor_client,
- mojom::SensorType sensor_type) {
- base::RunLoop run_loop;
- EXPECT_CALL(*sensor_client, OnSensorReadingChanged(sensor_type)).Times(0);
- run_loop.RunUntilIdle();
- }
- void ExpectReadingChangedEvent(MockPlatformSensorClient* sensor_client,
- mojom::SensorType sensor_type) {
- base::RunLoop run_loop;
- EXPECT_CALL(*sensor_client, OnSensorReadingChanged(sensor_type))
- .WillOnce(Invoke([&](SensorType) { run_loop.Quit(); }));
- run_loop.Run();
- }
- // 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,
- mojom::SensorType sensor_type) {
- scoped_refptr<FakePlatformSensor> fake_sensor =
- static_cast<FakePlatformSensor*>(sensor_client->sensor().get());
- fake_sensor->AddNewReading(new_reading);
- ExpectNoReadingChangedEvent(sensor_client, sensor_type);
- }
- // 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,
- mojom::SensorType sensor_type) {
- scoped_refptr<FakePlatformSensor> fake_sensor =
- static_cast<FakePlatformSensor*>(sensor_client->sensor().get());
- fake_sensor->AddNewReading(new_reading);
- ExpectReadingChangedEvent(sensor_client, sensor_type);
- }
- void FusionAlgorithmCopyLowLevelValues(const SensorReading& low_level_reading,
- SensorReading* fused_reading) {
- fused_reading->raw.values[0] = low_level_reading.raw.values[0];
- fused_reading->raw.values[1] = low_level_reading.raw.values[1];
- fused_reading->raw.values[2] = low_level_reading.raw.values[2];
- }
- void FusionAlgorithmSubtractEpsilonFromX(const SensorReading& low_level_reading,
- SensorReading* fused_reading) {
- fused_reading->raw.values[0] = low_level_reading.raw.values[0] - kEpsilon;
- fused_reading->raw.values[1] = low_level_reading.raw.values[1];
- fused_reading->raw.values[2] = low_level_reading.raw.values[2];
- }
- // A PlatformSensorFusionAlgorithm whose fusion algorithm can be customized
- // at runtime via set_fusion_function().
- class CustomizableFusionAlgorithm : public PlatformSensorFusionAlgorithm {
- public:
- using FusionFunction =
- base::RepeatingCallback<void(const SensorReading& low_level_reading,
- SensorReading* fused_reading)>;
- static constexpr mojom::SensorType kLowLevelSensorType =
- SensorType::ACCELEROMETER;
- static constexpr mojom::SensorType kFusionSensorType = SensorType::GRAVITY;
- CustomizableFusionAlgorithm()
- : PlatformSensorFusionAlgorithm(kFusionSensorType,
- {kLowLevelSensorType}) {}
- ~CustomizableFusionAlgorithm() override = default;
- bool GetFusedDataInternal(mojom::SensorType which_sensor_changed,
- SensorReading* fused_reading) override {
- EXPECT_EQ(which_sensor_changed, kLowLevelSensorType);
- SensorReading low_level_reading;
- EXPECT_TRUE(fusion_sensor_->GetSourceReading(kLowLevelSensorType,
- &low_level_reading));
- fusion_function_.Run(low_level_reading, fused_reading);
- return true;
- }
- void set_fusion_function(FusionFunction fusion_function) {
- fusion_function_ = std::move(fusion_function);
- }
- private:
- FusionFunction fusion_function_;
- };
- } // namespace
- class PlatformSensorFusionTest : public testing::Test {
- public:
- PlatformSensorFusionTest() {
- provider_ = std::make_unique<FakePlatformSensorProvider>();
- }
- PlatformSensorFusionTest(const PlatformSensorFusionTest&) = delete;
- PlatformSensorFusionTest& operator=(const PlatformSensorFusionTest&) = delete;
- protected:
- void CreateAccelerometer() {
- base::test::TestFuture<scoped_refptr<PlatformSensor>> future;
- provider_->CreateSensor(SensorType::ACCELEROMETER, future.GetCallback());
- accelerometer_ = static_cast<FakePlatformSensor*>(future.Get().get());
- EXPECT_TRUE(accelerometer_);
- EXPECT_EQ(SensorType::ACCELEROMETER, accelerometer_->GetType());
- }
- void CreateMagnetometer() {
- base::test::TestFuture<scoped_refptr<PlatformSensor>> future;
- provider_->CreateSensor(SensorType::MAGNETOMETER, future.GetCallback());
- magnetometer_ = static_cast<FakePlatformSensor*>(future.Get().get());
- EXPECT_TRUE(magnetometer_);
- EXPECT_EQ(SensorType::MAGNETOMETER, magnetometer_->GetType());
- }
- void CreateLinearAccelerationFusionSensor() {
- auto fusion_algorithm =
- std::make_unique<LinearAccelerationFusionAlgorithmUsingAccelerometer>();
- CreateFusionSensor(std::move(fusion_algorithm));
- }
- void CreateAbsoluteOrientationEulerAnglesFusionSensor() {
- auto fusion_algorithm = std::make_unique<
- AbsoluteOrientationEulerAnglesFusionAlgorithmUsingAccelerometerAndMagnetometer>();
- CreateFusionSensor(std::move(fusion_algorithm));
- }
- void CreateFusionSensor(
- std::unique_ptr<PlatformSensorFusionAlgorithm> fusion_algorithm) {
- base::test::TestFuture<scoped_refptr<PlatformSensor>> future;
- const SensorType type = fusion_algorithm->fused_type();
- PlatformSensorFusion::Create(provider_->GetSensorReadingBuffer(type),
- provider_.get(), std::move(fusion_algorithm),
- future.GetCallback());
- fusion_sensor_ = static_cast<PlatformSensorFusion*>(future.Get().get());
- }
- base::test::TaskEnvironment task_environment_;
- std::unique_ptr<FakePlatformSensorProvider> provider_;
- scoped_refptr<FakePlatformSensor> accelerometer_;
- scoped_refptr<FakePlatformSensor> magnetometer_;
- scoped_refptr<PlatformSensorFusion> fusion_sensor_;
- };
- // The following code tests creating a fusion sensor that needs one source
- // sensor.
- TEST_F(PlatformSensorFusionTest, SourceSensorAlreadyExists) {
- EXPECT_FALSE(provider_->GetSensor(SensorType::ACCELEROMETER));
- CreateAccelerometer();
- // Now the source sensor already exists.
- EXPECT_TRUE(provider_->GetSensor(SensorType::ACCELEROMETER));
- CreateLinearAccelerationFusionSensor();
- EXPECT_TRUE(fusion_sensor_);
- EXPECT_EQ(SensorType::LINEAR_ACCELERATION, fusion_sensor_->GetType());
- }
- TEST_F(PlatformSensorFusionTest, SourceSensorWorksSeparately) {
- CreateAccelerometer();
- EXPECT_TRUE(accelerometer_);
- EXPECT_FALSE(accelerometer_->IsActiveForTesting());
- auto client = std::make_unique<testing::NiceMock<MockPlatformSensorClient>>();
- accelerometer_->AddClient(client.get());
- accelerometer_->StartListening(client.get(), PlatformSensorConfiguration(10));
- EXPECT_TRUE(accelerometer_->IsActiveForTesting());
- CreateLinearAccelerationFusionSensor();
- EXPECT_TRUE(fusion_sensor_);
- EXPECT_EQ(SensorType::LINEAR_ACCELERATION, fusion_sensor_->GetType());
- EXPECT_FALSE(fusion_sensor_->IsActiveForTesting());
- fusion_sensor_->AddClient(client.get());
- fusion_sensor_->StartListening(client.get(), PlatformSensorConfiguration(10));
- EXPECT_TRUE(fusion_sensor_->IsActiveForTesting());
- fusion_sensor_->StopListening(client.get(), PlatformSensorConfiguration(10));
- EXPECT_FALSE(fusion_sensor_->IsActiveForTesting());
- EXPECT_TRUE(accelerometer_->IsActiveForTesting());
- accelerometer_->RemoveClient(client.get());
- EXPECT_FALSE(accelerometer_->IsActiveForTesting());
- fusion_sensor_->RemoveClient(client.get());
- }
- namespace {
- void CheckConfigsCountForClient(const scoped_refptr<PlatformSensor>& sensor,
- PlatformSensor::Client* client,
- size_t expected_count) {
- auto client_entry = sensor->GetConfigMapForTesting().find(client);
- if (sensor->GetConfigMapForTesting().end() == client_entry) {
- EXPECT_EQ(0u, expected_count);
- return;
- }
- EXPECT_EQ(expected_count, client_entry->second.size());
- }
- } // namespace
- TEST_F(PlatformSensorFusionTest, SourceSensorDoesNotKeepOutdatedConfigs) {
- CreateAccelerometer();
- EXPECT_TRUE(accelerometer_);
- CreateLinearAccelerationFusionSensor();
- EXPECT_TRUE(fusion_sensor_);
- EXPECT_EQ(SensorType::LINEAR_ACCELERATION, fusion_sensor_->GetType());
- auto client = std::make_unique<testing::NiceMock<MockPlatformSensorClient>>(
- fusion_sensor_);
- fusion_sensor_->StartListening(client.get(), PlatformSensorConfiguration(10));
- fusion_sensor_->StartListening(client.get(), PlatformSensorConfiguration(20));
- fusion_sensor_->StartListening(client.get(), PlatformSensorConfiguration(30));
- EXPECT_EQ(1u, fusion_sensor_->GetConfigMapForTesting().size());
- EXPECT_EQ(1u, accelerometer_->GetConfigMapForTesting().size());
- CheckConfigsCountForClient(fusion_sensor_, client.get(), 3u);
- // Fusion sensor is a client for its sources, however it must keep only
- // one active configuration for them at a time.
- CheckConfigsCountForClient(accelerometer_, fusion_sensor_.get(), 1u);
- fusion_sensor_->StopListening(client.get(), PlatformSensorConfiguration(30));
- fusion_sensor_->StopListening(client.get(), PlatformSensorConfiguration(20));
- CheckConfigsCountForClient(fusion_sensor_, client.get(), 1u);
- CheckConfigsCountForClient(accelerometer_, fusion_sensor_.get(), 1u);
- fusion_sensor_->StopListening(client.get(), PlatformSensorConfiguration(10));
- CheckConfigsCountForClient(fusion_sensor_, client.get(), 0u);
- CheckConfigsCountForClient(accelerometer_, fusion_sensor_.get(), 0u);
- }
- TEST_F(PlatformSensorFusionTest, AllSourceSensorsStoppedOnSingleSourceFailure) {
- CreateAccelerometer();
- EXPECT_TRUE(accelerometer_);
- CreateMagnetometer();
- EXPECT_TRUE(magnetometer_);
- // Magnetometer will be started after Accelerometer for the given
- // sensor fusion algorithm.
- ON_CALL(*magnetometer_, StartSensor(_)).WillByDefault(Return(false));
- CreateAbsoluteOrientationEulerAnglesFusionSensor();
- EXPECT_TRUE(fusion_sensor_);
- EXPECT_EQ(SensorType::ABSOLUTE_ORIENTATION_EULER_ANGLES,
- fusion_sensor_->GetType());
- auto client = std::make_unique<testing::NiceMock<MockPlatformSensorClient>>(
- fusion_sensor_);
- fusion_sensor_->StartListening(client.get(), PlatformSensorConfiguration(10));
- EXPECT_FALSE(fusion_sensor_->IsActiveForTesting());
- EXPECT_FALSE(accelerometer_->IsActiveForTesting());
- EXPECT_FALSE(magnetometer_->IsActiveForTesting());
- }
- TEST_F(PlatformSensorFusionTest, SourceSensorNeedsToBeCreated) {
- EXPECT_FALSE(provider_->GetSensor(SensorType::ACCELEROMETER));
- CreateLinearAccelerationFusionSensor();
- EXPECT_TRUE(fusion_sensor_);
- EXPECT_EQ(SensorType::LINEAR_ACCELERATION, fusion_sensor_->GetType());
- }
- TEST_F(PlatformSensorFusionTest, SourceSensorIsNotAvailable) {
- // Accelerometer is not available.
- ON_CALL(*provider_, DoCreateSensorInternal(SensorType::ACCELEROMETER, _, _))
- .WillByDefault(
- Invoke([](mojom::SensorType, scoped_refptr<PlatformSensor>,
- FakePlatformSensorProvider::CreateSensorCallback callback) {
- std::move(callback).Run(nullptr);
- }));
- CreateLinearAccelerationFusionSensor();
- EXPECT_FALSE(fusion_sensor_);
- }
- // The following code tests creating a fusion sensor that needs two source
- // sensors.
- TEST_F(PlatformSensorFusionTest, BothSourceSensorsAlreadyExist) {
- EXPECT_FALSE(provider_->GetSensor(SensorType::ACCELEROMETER));
- CreateAccelerometer();
- EXPECT_TRUE(provider_->GetSensor(SensorType::ACCELEROMETER));
- EXPECT_FALSE(provider_->GetSensor(SensorType::MAGNETOMETER));
- CreateMagnetometer();
- EXPECT_TRUE(provider_->GetSensor(SensorType::MAGNETOMETER));
- CreateAbsoluteOrientationEulerAnglesFusionSensor();
- EXPECT_TRUE(fusion_sensor_);
- EXPECT_EQ(SensorType::ABSOLUTE_ORIENTATION_EULER_ANGLES,
- fusion_sensor_->GetType());
- }
- TEST_F(PlatformSensorFusionTest, BothSourceSensorsNeedToBeCreated) {
- EXPECT_FALSE(provider_->GetSensor(SensorType::ACCELEROMETER));
- EXPECT_FALSE(provider_->GetSensor(SensorType::MAGNETOMETER));
- CreateAbsoluteOrientationEulerAnglesFusionSensor();
- EXPECT_TRUE(fusion_sensor_);
- EXPECT_EQ(SensorType::ABSOLUTE_ORIENTATION_EULER_ANGLES,
- fusion_sensor_->GetType());
- }
- TEST_F(PlatformSensorFusionTest, BothSourceSensorsAreNotAvailable) {
- // Failure.
- ON_CALL(*provider_, DoCreateSensorInternal(_, _, _))
- .WillByDefault(
- Invoke([](mojom::SensorType, scoped_refptr<PlatformSensor>,
- FakePlatformSensorProvider::CreateSensorCallback callback) {
- std::move(callback).Run(nullptr);
- }));
- CreateAbsoluteOrientationEulerAnglesFusionSensor();
- EXPECT_FALSE(fusion_sensor_);
- }
- TEST_F(PlatformSensorFusionTest,
- OneSourceSensorAlreadyExistsTheOtherSourceSensorNeedsToBeCreated) {
- EXPECT_FALSE(provider_->GetSensor(SensorType::ACCELEROMETER));
- CreateAccelerometer();
- EXPECT_TRUE(provider_->GetSensor(SensorType::ACCELEROMETER));
- EXPECT_FALSE(provider_->GetSensor(SensorType::MAGNETOMETER));
- CreateAbsoluteOrientationEulerAnglesFusionSensor();
- EXPECT_TRUE(fusion_sensor_);
- EXPECT_EQ(SensorType::ABSOLUTE_ORIENTATION_EULER_ANGLES,
- fusion_sensor_->GetType());
- }
- TEST_F(PlatformSensorFusionTest,
- OneSourceSensorAlreadyExistsTheOtherSourceSensorIsNotAvailable) {
- EXPECT_FALSE(provider_->GetSensor(SensorType::ACCELEROMETER));
- CreateAccelerometer();
- EXPECT_TRUE(provider_->GetSensor(SensorType::ACCELEROMETER));
- // Magnetometer is not available.
- ON_CALL(*provider_, DoCreateSensorInternal(SensorType::MAGNETOMETER, _, _))
- .WillByDefault(
- Invoke([](mojom::SensorType, scoped_refptr<PlatformSensor>,
- FakePlatformSensorProvider::CreateSensorCallback callback) {
- std::move(callback).Run(nullptr);
- }));
- CreateAbsoluteOrientationEulerAnglesFusionSensor();
- EXPECT_FALSE(fusion_sensor_);
- }
- TEST_F(PlatformSensorFusionTest,
- OneSourceSensorNeedsToBeCreatedTheOtherSourceSensorIsNotAvailable) {
- EXPECT_FALSE(provider_->GetSensor(SensorType::ACCELEROMETER));
- // Magnetometer is not available.
- ON_CALL(*provider_, DoCreateSensorInternal(SensorType::MAGNETOMETER, _, _))
- .WillByDefault(
- Invoke([](mojom::SensorType, scoped_refptr<PlatformSensor>,
- FakePlatformSensorProvider::CreateSensorCallback callback) {
- std::move(callback).Run(nullptr);
- }));
- CreateAbsoluteOrientationEulerAnglesFusionSensor();
- EXPECT_FALSE(fusion_sensor_);
- }
- TEST_F(PlatformSensorFusionTest,
- FusionSensorMaximumSupportedFrequencyIsTheMaximumOfItsSourceSensors) {
- EXPECT_FALSE(provider_->GetSensor(SensorType::ACCELEROMETER));
- CreateAccelerometer();
- scoped_refptr<PlatformSensor> accelerometer =
- provider_->GetSensor(SensorType::ACCELEROMETER);
- EXPECT_TRUE(accelerometer);
- static_cast<FakePlatformSensor*>(accelerometer.get())
- ->set_maximum_supported_frequency(30.0);
- EXPECT_FALSE(provider_->GetSensor(SensorType::MAGNETOMETER));
- CreateMagnetometer();
- scoped_refptr<PlatformSensor> magnetometer =
- provider_->GetSensor(SensorType::MAGNETOMETER);
- EXPECT_TRUE(magnetometer);
- static_cast<FakePlatformSensor*>(magnetometer.get())
- ->set_maximum_supported_frequency(20.0);
- CreateAbsoluteOrientationEulerAnglesFusionSensor();
- EXPECT_TRUE(fusion_sensor_);
- EXPECT_EQ(SensorType::ABSOLUTE_ORIENTATION_EULER_ANGLES,
- fusion_sensor_->GetType());
- EXPECT_EQ(30.0, fusion_sensor_->GetMaximumSupportedFrequency());
- auto client = std::make_unique<testing::NiceMock<MockPlatformSensorClient>>(
- fusion_sensor_);
- EXPECT_TRUE(fusion_sensor_->StartListening(
- client.get(), PlatformSensorConfiguration(30.0)));
- }
- TEST_F(PlatformSensorFusionTest, FusionIsSignificantlyDifferent) {
- // Due to inaccuracy of calculations between doubles, difference between two
- // input values has to be bigger than the threshold value used in
- // significantly different check.
- CreateLinearAccelerationFusionSensor();
- const auto* const fusion_algorithm = fusion_sensor_->fusion_algorithm();
- const double kValueToFlipThreshold = fusion_algorithm->threshold() + kEpsilon;
- const double kValueNotToFlipThreshold =
- fusion_algorithm->threshold() - kEpsilon;
- SensorReading reading1;
- SensorReading reading2;
- // Made up test values.
- reading1.accel.x = reading2.accel.x = 0.1;
- reading1.accel.y = reading2.accel.y = 0.5;
- reading1.accel.z = reading2.accel.z = 10.0;
- // Compared values are same.
- // reading1: 0.1, 0.5, 10.0
- // reading2: 0.1, 0.5, 10.0
- EXPECT_FALSE(fusion_sensor_->IsSignificantlyDifferent(
- reading1, reading2, fusion_sensor_->GetType()));
- // Compared values do not significantly differ from each other.
- // reading1: 0.1, 0.5, 10.0
- // reading2: 0.1, 0.5, 10.00001
- reading2.accel.z = reading2.accel.z + kValueNotToFlipThreshold;
- EXPECT_FALSE(fusion_sensor_->IsSignificantlyDifferent(
- reading1, reading2, fusion_sensor_->GetType()));
- // Compared values significantly differ from each other.
- // reading1: 0.1, 0.5, 10.0
- // reading2: 0.1, 0.5, 10.11001
- reading2.accel.z = reading2.accel.z + kValueToFlipThreshold;
- EXPECT_TRUE(fusion_sensor_->IsSignificantlyDifferent(
- reading1, reading2, fusion_sensor_->GetType()));
- }
- TEST_F(PlatformSensorFusionTest, OnSensorReadingChanged) {
- // Accelerometer is selected as low-level sensor.
- CreateAccelerometer();
- EXPECT_TRUE(accelerometer_);
- auto client_low_level_ =
- std::make_unique<testing::NiceMock<MockPlatformSensorClient>>(
- accelerometer_);
- CreateFusionSensor(std::make_unique<CustomizableFusionAlgorithm>());
- ASSERT_TRUE(fusion_sensor_);
- auto* fusion_algorithm = static_cast<CustomizableFusionAlgorithm*>(
- fusion_sensor_->fusion_algorithm());
- EXPECT_EQ(CustomizableFusionAlgorithm::kFusionSensorType,
- fusion_sensor_->GetType());
- auto client_fusion =
- std::make_unique<testing::NiceMock<MockPlatformSensorClient>>(
- fusion_sensor_);
- fusion_sensor_->StartListening(client_fusion.get(),
- PlatformSensorConfiguration(10));
- // Made up test values.
- const double kTestValueX = 0.6;
- const double kTestValueY = 0.9;
- const double kTestValueZ = 1.1;
- const double kValueToFlipThreshold = fusion_algorithm->threshold() + kEpsilon;
- const double kValueToFlipThresholdRounded = fusion_algorithm->threshold();
- struct TestSensorReading {
- const struct {
- double x;
- double y;
- double z;
- } input, expected;
- const bool expect_reading_changed_event;
- };
- const struct {
- TestSensorReading low_level;
- TestSensorReading fusion;
- CustomizableFusionAlgorithm::FusionFunction fusion_function;
- } kTestSteps[] = {
- // Test set 1
- // Triggers low-level and fusion reading as initial sensor
- // values are zero.
- {// Low-level sensor
- {{kTestValueX, kTestValueY, kTestValueZ},
- {kTestValueX, kTestValueY, kTestValueZ},
- true},
- // Fusion sensor
- {{kTestValueX, kTestValueY, kTestValueZ},
- {kTestValueX, kTestValueY, kTestValueZ},
- true},
- base::BindRepeating(&FusionAlgorithmCopyLowLevelValues)},
- // Test set 2
- // Doesn't trigger low-level reading event as rounded value is same as
- // earlier. Because of that fusion sensor event is not either triggered.
- {// Low-level sensor
- {{kTestValueX + kEpsilon, kTestValueY, kTestValueZ},
- {kTestValueX, kTestValueY, kTestValueZ},
- false},
- // Fusion sensor
- {{kTestValueX, kTestValueY, kTestValueZ},
- {kTestValueX, kTestValueY, kTestValueZ},
- false},
- base::BindRepeating(&FusionAlgorithmSubtractEpsilonFromX)},
- // Test set 3
- // In current code as fusion sensor values are rounded before
- // PlatformSensorFusionAlgorithm::IsReadingSignificantlyDifferent() call
- // the difference between values must much bigger than threshold value.
- {// Low-level sensor
- {{kTestValueX + kValueToFlipThreshold, kTestValueY, kTestValueZ},
- {kTestValueX + kValueToFlipThresholdRounded, kTestValueY, kTestValueZ},
- true},
- // Fusion sensor
- {{kTestValueX + kValueToFlipThreshold, kTestValueY, kTestValueZ},
- {kTestValueX + kValueToFlipThresholdRounded, kTestValueY, kTestValueZ},
- true},
- base::BindRepeating(&FusionAlgorithmCopyLowLevelValues)},
- };
- for (const auto& test_step : kTestSteps) {
- fusion_algorithm->set_fusion_function(test_step.fusion_function);
- // First add low-level sensor readings.
- SensorReading reading;
- reading.accel.x = test_step.low_level.input.x;
- reading.accel.y = test_step.low_level.input.y;
- reading.accel.z = test_step.low_level.input.z;
- // Code checks if PlatformSensor::OnSensorReadingChanged() is called
- // or not called as expected.
- if (test_step.low_level.expect_reading_changed_event) {
- AddNewReadingAndExpectReadingChangedEvent(
- client_low_level_.get(), reading,
- CustomizableFusionAlgorithm::kLowLevelSensorType);
- } else {
- AddNewReadingAndExpectNoReadingChangedEvent(
- client_low_level_.get(), reading,
- CustomizableFusionAlgorithm::kLowLevelSensorType);
- }
- if (test_step.fusion.expect_reading_changed_event) {
- ExpectReadingChangedEvent(client_fusion.get(),
- CustomizableFusionAlgorithm::kFusionSensorType);
- } else {
- ExpectNoReadingChangedEvent(
- client_fusion.get(), CustomizableFusionAlgorithm::kFusionSensorType);
- }
- // Once new values are added, we can check that low-level sensors and
- // fusion sensor have correct values.
- // Check rounded low-level sensor values.
- EXPECT_TRUE(accelerometer_->GetLatestReading(&reading));
- EXPECT_DOUBLE_EQ(test_step.low_level.expected.x, reading.accel.x);
- EXPECT_DOUBLE_EQ(test_step.low_level.expected.y, reading.accel.y);
- EXPECT_DOUBLE_EQ(test_step.low_level.expected.z, reading.accel.z);
- // Check raw low-level sensor values.
- EXPECT_TRUE(accelerometer_->GetLatestRawReading(&reading));
- EXPECT_DOUBLE_EQ(test_step.low_level.input.x, reading.accel.x);
- EXPECT_DOUBLE_EQ(test_step.low_level.input.y, reading.accel.y);
- EXPECT_DOUBLE_EQ(test_step.low_level.input.z, reading.accel.z);
- // Check rounded fusion sensor values.
- EXPECT_TRUE(fusion_sensor_->GetLatestReading(&reading));
- EXPECT_DOUBLE_EQ(test_step.fusion.expected.x, reading.accel.x);
- EXPECT_DOUBLE_EQ(test_step.fusion.expected.y, reading.accel.y);
- EXPECT_DOUBLE_EQ(test_step.fusion.expected.z, reading.accel.z);
- // Check raw fusion sensor values.
- EXPECT_TRUE(fusion_sensor_->GetLatestRawReading(&reading));
- EXPECT_DOUBLE_EQ(test_step.fusion.input.x, reading.accel.x);
- EXPECT_DOUBLE_EQ(test_step.fusion.input.y, reading.accel.y);
- EXPECT_DOUBLE_EQ(test_step.fusion.input.z, reading.accel.z);
- }
- }
- } // namespace device
|