| Index: device/generic_sensor/platform_sensor_provider_unittest.cc
|
| diff --git a/device/generic_sensor/platform_sensor_provider_unittest.cc b/device/generic_sensor/platform_sensor_provider_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..4b20c2eadffc769f9cbb255752b404ec3c518ebf
|
| --- /dev/null
|
| +++ b/device/generic_sensor/platform_sensor_provider_unittest.cc
|
| @@ -0,0 +1,410 @@
|
| +// Copyright 2016 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 "base/bind.h"
|
| +#include "base/message_loop/message_loop.h"
|
| +#include "base/run_loop.h"
|
| +
|
| +#include "device/generic_sensor/fake_platform_sensor.h"
|
| +#include "device/generic_sensor/fake_platform_sensor_provider.h"
|
| +#include "device/generic_sensor/public/interfaces/sensor_provider.mojom.h"
|
| +
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +namespace device {
|
| +
|
| +using mojom::SensorInitParams;
|
| +using mojom::SensorType;
|
| +
|
| +class TestSensorCreateCallback {
|
| + public:
|
| + TestSensorCreateCallback()
|
| + : callback_(base::Bind(&TestSensorCreateCallback::SetResult,
|
| + base::Unretained(this))) {}
|
| +
|
| + scoped_refptr<PlatformSensor> WaitForResult() {
|
| + run_loop_.Run();
|
| + scoped_refptr<PlatformSensor> sensor = sensor_;
|
| + sensor_ = nullptr;
|
| + return sensor;
|
| + }
|
| +
|
| + const PlatformSensorProvider::CreateSensorCallback& callback() const {
|
| + return callback_;
|
| + }
|
| +
|
| + private:
|
| + void SetResult(scoped_refptr<PlatformSensor> sensor) {
|
| + sensor_ = sensor;
|
| + run_loop_.Quit();
|
| + }
|
| +
|
| + const PlatformSensorProvider::CreateSensorCallback callback_;
|
| + base::RunLoop run_loop_;
|
| + scoped_refptr<PlatformSensor> sensor_;
|
| +};
|
| +
|
| +class PlatformSensorTestClient : public PlatformSensor::Client {
|
| + public:
|
| + PlatformSensorTestClient()
|
| + : notification_suspended_(false),
|
| + sensor_reading_changed_(false),
|
| + sensor_error_(false) {}
|
| +
|
| + ~PlatformSensorTestClient() override {
|
| + if (sensor_)
|
| + sensor_->RemoveClient(this);
|
| + }
|
| +
|
| + // PlatformSensor::Client override.
|
| + void OnSensorReadingChanged() override { sensor_reading_changed_ = true; }
|
| +
|
| + void OnSensorError() override { sensor_error_ = true; }
|
| +
|
| + bool IsNotificationSuspended() override { return notification_suspended_; }
|
| +
|
| + void set_notification_suspended(bool value) {
|
| + notification_suspended_ = value;
|
| + }
|
| +
|
| + void SetSensor(scoped_refptr<PlatformSensor> sensor) {
|
| + sensor_ = sensor;
|
| + sensor_->AddClient(this);
|
| + }
|
| +
|
| + bool sensor_reading_changed() const { return sensor_reading_changed_; }
|
| +
|
| + bool sensor_error() const { return sensor_error_; }
|
| +
|
| + private:
|
| + scoped_refptr<PlatformSensor> sensor_;
|
| + bool notification_suspended_;
|
| + bool sensor_reading_changed_;
|
| + bool sensor_error_;
|
| +};
|
| +
|
| +class PlatformSensorProviderTest : public ::testing::Test {
|
| + public:
|
| + PlatformSensorProviderTest()
|
| + : provider_(new FakePlatformSensorProvider()),
|
| + sensor_client_(new PlatformSensorTestClient()),
|
| + message_loop_(new base::MessageLoopForIO) {}
|
| +
|
| + protected:
|
| + scoped_refptr<PlatformSensor> CreateSensor(
|
| + mojom::SensorType type,
|
| + TestSensorCreateCallback* callback) {
|
| + provider_->CreateSensor(type, callback->callback());
|
| + return callback->WaitForResult();
|
| + }
|
| +
|
| + std::unique_ptr<FakePlatformSensorProvider> provider_;
|
| + std::unique_ptr<PlatformSensorTestClient> sensor_client_;
|
| + std::unique_ptr<base::MessageLoop> message_loop_;
|
| +};
|
| +
|
| +TEST_F(PlatformSensorProviderTest, CreateSensorsAndCheckType) {
|
| + {
|
| + TestSensorCreateCallback callback;
|
| + scoped_refptr<PlatformSensor> sensor =
|
| + CreateSensor(SensorType::AMBIENT_LIGHT, &callback);
|
| + EXPECT_TRUE(sensor);
|
| + EXPECT_EQ(SensorType::AMBIENT_LIGHT, sensor->GetType());
|
| + }
|
| +
|
| + {
|
| + TestSensorCreateCallback callback;
|
| + scoped_refptr<PlatformSensor> sensor =
|
| + CreateSensor(SensorType::PROXIMITY, &callback);
|
| + EXPECT_TRUE(sensor);
|
| + EXPECT_EQ(SensorType::PROXIMITY, sensor->GetType());
|
| + }
|
| +
|
| + {
|
| + TestSensorCreateCallback callback;
|
| + scoped_refptr<PlatformSensor> sensor =
|
| + CreateSensor(SensorType::ACCELEROMETER, &callback);
|
| + EXPECT_TRUE(sensor);
|
| + EXPECT_EQ(SensorType::ACCELEROMETER, sensor->GetType());
|
| + }
|
| +
|
| + {
|
| + TestSensorCreateCallback callback;
|
| + scoped_refptr<PlatformSensor> sensor =
|
| + CreateSensor(SensorType::LINEAR_ACCELERATION, &callback);
|
| + EXPECT_TRUE(sensor);
|
| + EXPECT_EQ(SensorType::LINEAR_ACCELERATION, sensor->GetType());
|
| + }
|
| +
|
| + {
|
| + TestSensorCreateCallback callback;
|
| + scoped_refptr<PlatformSensor> sensor =
|
| + CreateSensor(SensorType::GYROSCOPE, &callback);
|
| + EXPECT_TRUE(sensor);
|
| + EXPECT_EQ(SensorType::GYROSCOPE, sensor->GetType());
|
| + }
|
| +
|
| + {
|
| + TestSensorCreateCallback callback;
|
| + scoped_refptr<PlatformSensor> sensor =
|
| + CreateSensor(SensorType::MAGNETOMETER, &callback);
|
| + EXPECT_TRUE(sensor);
|
| + EXPECT_EQ(SensorType::MAGNETOMETER, sensor->GetType());
|
| + }
|
| +
|
| + {
|
| + TestSensorCreateCallback callback;
|
| + scoped_refptr<PlatformSensor> sensor =
|
| + CreateSensor(SensorType::PRESSURE, &callback);
|
| + EXPECT_TRUE(sensor);
|
| + EXPECT_EQ(SensorType::PRESSURE, sensor->GetType());
|
| + }
|
| +
|
| + {
|
| + TestSensorCreateCallback callback;
|
| + scoped_refptr<PlatformSensor> sensor =
|
| + CreateSensor(SensorType::ABSOLUTE_ORIENTATION, &callback);
|
| + EXPECT_TRUE(sensor);
|
| + EXPECT_EQ(SensorType::ABSOLUTE_ORIENTATION, sensor->GetType());
|
| + }
|
| +
|
| + {
|
| + TestSensorCreateCallback callback;
|
| + scoped_refptr<PlatformSensor> sensor =
|
| + CreateSensor(SensorType::RELATIVE_ORIENTATION, &callback);
|
| + EXPECT_TRUE(sensor);
|
| + EXPECT_EQ(SensorType::RELATIVE_ORIENTATION, sensor->GetType());
|
| + }
|
| +}
|
| +
|
| +TEST_F(PlatformSensorProviderTest, CreateAndGetSensor) {
|
| + // Create Ambient Light sensor.
|
| + TestSensorCreateCallback callback1;
|
| + scoped_refptr<PlatformSensor> sensor1 =
|
| + CreateSensor(SensorType::AMBIENT_LIGHT, &callback1);
|
| + EXPECT_TRUE(sensor1);
|
| + EXPECT_EQ(SensorType::AMBIENT_LIGHT, sensor1->GetType());
|
| +
|
| + // Try to get Gyroscope sensor, which has not been created yet.
|
| + scoped_refptr<PlatformSensor> sensor2 =
|
| + provider_->GetSensor(SensorType::GYROSCOPE);
|
| + EXPECT_FALSE(sensor2);
|
| +
|
| + // Get Ambient Light sensor.
|
| + scoped_refptr<PlatformSensor> sensor3 =
|
| + provider_->GetSensor(SensorType::AMBIENT_LIGHT);
|
| + EXPECT_TRUE(sensor3);
|
| +
|
| + EXPECT_EQ(sensor1->GetType(), sensor3->GetType());
|
| +}
|
| +
|
| +TEST_F(PlatformSensorProviderTest, CreateAndRemoveSensors) {
|
| + TestSensorCreateCallback callback1;
|
| + scoped_refptr<PlatformSensor> sensor1 =
|
| + CreateSensor(SensorType::AMBIENT_LIGHT, &callback1);
|
| + EXPECT_TRUE(sensor1);
|
| +
|
| + TestSensorCreateCallback callback2;
|
| + scoped_refptr<PlatformSensor> sensor2 =
|
| + CreateSensor(SensorType::PROXIMITY, &callback2);
|
| + EXPECT_TRUE(sensor2);
|
| +
|
| + EXPECT_TRUE(provider_->HasSensors());
|
| +
|
| + EXPECT_CALL(*provider_, AllSensorsRemoved()).Times(1);
|
| +
|
| + sensor1 = nullptr;
|
| + sensor2 = nullptr;
|
| +
|
| + EXPECT_FALSE(provider_->HasSensors());
|
| +}
|
| +
|
| +TEST_F(PlatformSensorProviderTest, TestSensorLeaks) {
|
| + // Create Ambient Light sensor.
|
| + TestSensorCreateCallback callback1;
|
| + scoped_refptr<PlatformSensor> sensor1 =
|
| + CreateSensor(SensorType::AMBIENT_LIGHT, &callback1);
|
| + EXPECT_TRUE(sensor1);
|
| + EXPECT_EQ(SensorType::AMBIENT_LIGHT, sensor1->GetType());
|
| +
|
| + // Sensor should be automatically destroyed.
|
| + sensor1 = nullptr;
|
| + scoped_refptr<PlatformSensor> sensor2 =
|
| + provider_->GetSensor(SensorType::AMBIENT_LIGHT);
|
| + EXPECT_FALSE(sensor2);
|
| +}
|
| +
|
| +// This test assumes that a mock sensor has a constant maximum frequency value
|
| +// of 50 hz (different from the base sensor class that has a range from 0 to
|
| +// 60) and tests whether a mock sensor can be started with a value range from 0
|
| +// to 60.
|
| +TEST_F(PlatformSensorProviderTest, StartListeningWithDifferentParameters) {
|
| + const double too_high_frequency = 60;
|
| + const double normal_frequency = 39;
|
| + TestSensorCreateCallback callback;
|
| + scoped_refptr<PlatformSensor> sensor =
|
| + CreateSensor(SensorType::AMBIENT_LIGHT, &callback);
|
| + FakePlatformSensor* fake_sensor =
|
| + static_cast<FakePlatformSensor*>(sensor.get());
|
| + EXPECT_TRUE(fake_sensor);
|
| + sensor_client_->SetSensor(sensor);
|
| +
|
| + PlatformSensorConfiguration config(too_high_frequency);
|
| + EXPECT_EQ(too_high_frequency, config.frequency());
|
| + EXPECT_FALSE(fake_sensor->StartListening(sensor_client_.get(), config));
|
| + EXPECT_FALSE(fake_sensor->started());
|
| +
|
| + config.set_frequency(normal_frequency);
|
| + EXPECT_EQ(normal_frequency, config.frequency());
|
| + EXPECT_TRUE(fake_sensor->StartListening(sensor_client_.get(), config));
|
| + EXPECT_TRUE(fake_sensor->started());
|
| +
|
| + EXPECT_TRUE(fake_sensor->StopListening(sensor_client_.get(), config));
|
| + EXPECT_FALSE(fake_sensor->started());
|
| +}
|
| +
|
| +// If a client is in a suspended mode, a NotifySensorReadingChanged()
|
| +// notification must not be sent to the client but NotifySensorError() must be.
|
| +TEST_F(PlatformSensorProviderTest, TestNotificationSuspended) {
|
| + const int num = 5;
|
| + TestSensorCreateCallback callback;
|
| + scoped_refptr<PlatformSensor> sensor =
|
| + CreateSensor(SensorType::GYROSCOPE, &callback);
|
| + FakePlatformSensor* fake_sensor =
|
| + static_cast<FakePlatformSensor*>(sensor.get());
|
| +
|
| + std::vector<std::unique_ptr<PlatformSensorTestClient>> clients;
|
| + for (int i = 0; i < num; i++) {
|
| + std::unique_ptr<PlatformSensorTestClient> client(
|
| + new PlatformSensorTestClient());
|
| + client->SetSensor(fake_sensor);
|
| + clients.push_back(std::move(client));
|
| + }
|
| +
|
| + clients.front()->set_notification_suspended(true);
|
| + fake_sensor->NotifySensorReadingChanged();
|
| + fake_sensor->NotifySensorError();
|
| + for (auto const& client : clients) {
|
| + if (client == clients.front()) {
|
| + EXPECT_FALSE(client->sensor_reading_changed());
|
| + EXPECT_TRUE(client->sensor_error());
|
| + continue;
|
| + }
|
| + EXPECT_TRUE(client->sensor_reading_changed());
|
| + EXPECT_TRUE(client->sensor_error());
|
| + }
|
| +
|
| + clients.front()->set_notification_suspended(false);
|
| + fake_sensor->NotifySensorReadingChanged();
|
| + fake_sensor->NotifySensorError();
|
| + for (auto const& client : clients) {
|
| + EXPECT_TRUE(client->sensor_reading_changed());
|
| + EXPECT_TRUE(client->sensor_error());
|
| + }
|
| +}
|
| +
|
| +// Tests that when all clients are removed, config maps are removed as well.
|
| +TEST_F(PlatformSensorProviderTest, TestAddRemoveClients) {
|
| + const int num = 5;
|
| +
|
| + TestSensorCreateCallback callback;
|
| + scoped_refptr<PlatformSensor> sensor =
|
| + CreateSensor(SensorType::AMBIENT_LIGHT, &callback);
|
| + FakePlatformSensor* fake_sensor =
|
| + static_cast<FakePlatformSensor*>(sensor.get());
|
| + EXPECT_TRUE(fake_sensor->config_map().empty());
|
| +
|
| + std::vector<std::unique_ptr<PlatformSensorTestClient>> clients;
|
| + PlatformSensorConfiguration config(30);
|
| + for (int i = 0; i < num; i++) {
|
| + std::unique_ptr<PlatformSensorTestClient> client(
|
| + new PlatformSensorTestClient());
|
| + client->SetSensor(fake_sensor);
|
| + EXPECT_TRUE(fake_sensor->StartListening(client.get(), config));
|
| + EXPECT_TRUE(fake_sensor->started());
|
| +
|
| + clients.push_back(std::move(client));
|
| + }
|
| + EXPECT_FALSE(fake_sensor->config_map().empty());
|
| +
|
| + for (const auto& client : clients)
|
| + fake_sensor->RemoveClient(client.get());
|
| +
|
| + EXPECT_TRUE(fake_sensor->config_map().empty());
|
| +}
|
| +
|
| +// Tests a sensor cannot be updated if it has one suspended client.
|
| +TEST_F(PlatformSensorProviderTest, TestUpdateSensorOneClient) {
|
| + TestSensorCreateCallback callback;
|
| + scoped_refptr<PlatformSensor> sensor =
|
| + CreateSensor(SensorType::AMBIENT_LIGHT, &callback);
|
| + FakePlatformSensor* fake_sensor =
|
| + static_cast<FakePlatformSensor*>(sensor.get());
|
| + EXPECT_TRUE(fake_sensor->config_map().empty());
|
| +
|
| + sensor_client_->SetSensor(fake_sensor);
|
| +
|
| + PlatformSensorConfiguration config(30);
|
| + fake_sensor->StartListening(sensor_client_.get(), config);
|
| +
|
| + sensor_client_->set_notification_suspended(true);
|
| + EXPECT_TRUE(sensor_client_->IsNotificationSuspended());
|
| +
|
| + fake_sensor->UpdateSensor();
|
| + EXPECT_FALSE(fake_sensor->started());
|
| +
|
| + sensor_client_->set_notification_suspended(false);
|
| + EXPECT_FALSE(sensor_client_->IsNotificationSuspended());
|
| +
|
| + fake_sensor->UpdateSensor();
|
| + EXPECT_TRUE(fake_sensor->started());
|
| +}
|
| +
|
| +// Tests a sensor can be updated if it has one suspended client and other
|
| +// clients are not suspended.
|
| +TEST_F(PlatformSensorProviderTest, TestUpdateSensorManyClients) {
|
| + const int num = 5;
|
| +
|
| + TestSensorCreateCallback callback;
|
| + scoped_refptr<PlatformSensor> sensor =
|
| + CreateSensor(SensorType::AMBIENT_LIGHT, &callback);
|
| + FakePlatformSensor* fake_sensor =
|
| + static_cast<FakePlatformSensor*>(sensor.get());
|
| + EXPECT_TRUE(fake_sensor->config_map().empty());
|
| +
|
| + sensor_client_->SetSensor(fake_sensor);
|
| + std::vector<std::unique_ptr<PlatformSensorTestClient>> clients;
|
| + for (int i = 0; i < num; i++) {
|
| + std::unique_ptr<PlatformSensorTestClient> client(
|
| + new PlatformSensorTestClient());
|
| + client->SetSensor(fake_sensor);
|
| + clients.push_back(std::move(client));
|
| + }
|
| +
|
| + double sensor_frequency = 30;
|
| + PlatformSensorConfiguration config(sensor_frequency++);
|
| + fake_sensor->StartListening(sensor_client_.get(), config);
|
| + for (const auto& client : clients) {
|
| + PlatformSensorConfiguration config(sensor_frequency++);
|
| + fake_sensor->StartListening(client.get(), config);
|
| + }
|
| +
|
| + sensor_client_->set_notification_suspended(true);
|
| + EXPECT_TRUE(sensor_client_->IsNotificationSuspended());
|
| + for (const auto& client : clients)
|
| + EXPECT_FALSE(client->IsNotificationSuspended());
|
| +
|
| + fake_sensor->UpdateSensor();
|
| + EXPECT_TRUE(fake_sensor->started());
|
| +
|
| + sensor_client_->set_notification_suspended(false);
|
| + EXPECT_FALSE(sensor_client_->IsNotificationSuspended());
|
| + for (const auto& client : clients)
|
| + EXPECT_FALSE(client->IsNotificationSuspended());
|
| +
|
| + fake_sensor->UpdateSensor();
|
| + EXPECT_TRUE(fake_sensor->started());
|
| +}
|
| +
|
| +} // namespace device
|
|
|