| // Copyright 2019 The Chromium OS 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 "power_manager/powerd/system/ambient_light_sensor_manager.h" |
| |
| #include <memory> |
| #include <string> |
| |
| #include <base/files/file_path.h> |
| #include <base/files/file_util.h> |
| #include <base/files/scoped_temp_dir.h> |
| #include <base/strings/string_number_conversions.h> |
| #include <brillo/file_utils.h> |
| #include <gtest/gtest.h> |
| |
| #include "power_manager/common/fake_prefs.h" |
| #include "power_manager/common/test_main_loop_runner.h" |
| #include "power_manager/powerd/system/ambient_light_observer.h" |
| |
| namespace power_manager { |
| namespace system { |
| |
| namespace { |
| |
| // Abort if it an expected brightness change hasn't been received after this |
| // many milliseconds. |
| const int kUpdateTimeoutMs = 5000; |
| |
| // Frequency with which the ambient light sensor file is polled. |
| const int kPollIntervalMs = 100; |
| |
| // Simple AmbientLightObserver implementation that runs the event loop |
| // until it receives notification that the ambient light level has changed. |
| class TestObserver : public AmbientLightObserver { |
| public: |
| TestObserver() {} |
| TestObserver(const TestObserver&) = delete; |
| TestObserver& operator=(const TestObserver&) = delete; |
| |
| ~TestObserver() override {} |
| |
| // Runs |loop_| until OnAmbientLightUpdated() is called. |
| bool RunUntilAmbientLightUpdated() { |
| return loop_runner_.StartLoop( |
| base::TimeDelta::FromMilliseconds(kUpdateTimeoutMs)); |
| } |
| |
| // AmbientLightObserver implementation: |
| void OnAmbientLightUpdated(AmbientLightSensorInterface* sensor) override { |
| loop_runner_.StopLoop(); |
| } |
| |
| private: |
| TestMainLoopRunner loop_runner_; |
| }; |
| |
| } // namespace |
| |
| class AmbientLightSensorManagerTest : public ::testing::Test { |
| public: |
| AmbientLightSensorManagerTest() {} |
| AmbientLightSensorManagerTest(const AmbientLightSensorManagerTest&) = delete; |
| AmbientLightSensorManagerTest& operator=( |
| const AmbientLightSensorManagerTest&) = delete; |
| |
| ~AmbientLightSensorManagerTest() override {} |
| |
| void SetUp() override { |
| prefs_.SetInt64(kAllowAmbientEQ, 0); |
| CHECK(temp_dir_.CreateUniqueTempDir()); |
| manager_.reset(new AmbientLightSensorManager()); |
| } |
| |
| void TearDown() override { |
| CHECK(base::DeletePathRecursively(temp_dir_.GetPath())); |
| }; |
| |
| protected: |
| base::FilePath AddSensor(int lux, std::string loc, bool color) { |
| base::FilePath device_dir = temp_dir_.GetPath().Append( |
| "device" + base::NumberToString(num_sensors_++)); |
| CHECK(base::CreateDirectory(device_dir)); |
| base::FilePath data_file = device_dir.Append("illuminance0_input"); |
| CHECK(brillo::WriteStringToFile(data_file, base::NumberToString(lux))); |
| base::FilePath loc_file = device_dir.Append("location"); |
| CHECK(brillo::WriteStringToFile(loc_file, loc)); |
| |
| if (!color) |
| return data_file; |
| |
| base::FilePath color_file = device_dir.Append("in_illuminance_red_raw"); |
| CHECK(brillo::WriteStringToFile(color_file, base::NumberToString(lux))); |
| color_file = device_dir.Append("in_illuminance_blue_raw"); |
| CHECK(brillo::WriteStringToFile(color_file, base::NumberToString(lux))); |
| color_file = device_dir.Append("in_illuminance_green_raw"); |
| CHECK(brillo::WriteStringToFile(color_file, base::NumberToString(lux))); |
| return color_file; |
| } |
| |
| // Temporary directory mimicking a /sys directory containing a set of sensor |
| // devices. |
| base::ScopedTempDir temp_dir_; |
| |
| size_t num_sensors_ = 0; |
| |
| FakePrefs prefs_; |
| |
| std::unique_ptr<AmbientLightSensorManager> manager_; |
| |
| TestObserver internal_backlight_observer_; |
| TestObserver keyboard_backlight_observer_; |
| }; |
| |
| TEST_F(AmbientLightSensorManagerTest, ZeroSensors) { |
| prefs_.SetInt64(kHasAmbientLightSensorPref, 0); |
| |
| manager_->Init(&prefs_); |
| manager_->set_device_list_path_for_testing(temp_dir_.GetPath()); |
| manager_->Run(false /* read_immediately */); |
| |
| EXPECT_EQ(nullptr, manager_->GetSensorForInternalBacklight()); |
| EXPECT_EQ(nullptr, manager_->GetSensorForKeyboardBacklight()); |
| EXPECT_FALSE(manager_->HasColorSensor()); |
| } |
| |
| TEST_F(AmbientLightSensorManagerTest, OneSensor) { |
| prefs_.SetInt64(kHasAmbientLightSensorPref, 1); |
| base::FilePath data_file = AddSensor(0, "lid", false); |
| |
| manager_->Init(&prefs_); |
| manager_->set_device_list_path_for_testing(temp_dir_.GetPath()); |
| manager_->set_poll_interval_ms_for_testing(kPollIntervalMs); |
| manager_->Run(false /* read_immediately */); |
| |
| auto internal_backlight_sensor = manager_->GetSensorForInternalBacklight(); |
| internal_backlight_sensor->AddObserver(&internal_backlight_observer_); |
| ASSERT_TRUE(internal_backlight_observer_.RunUntilAmbientLightUpdated()); |
| EXPECT_EQ(0, internal_backlight_sensor->GetAmbientLightLux()); |
| EXPECT_EQ(data_file, internal_backlight_sensor->GetIlluminancePath()); |
| internal_backlight_sensor->RemoveObserver(&internal_backlight_observer_); |
| |
| auto keyboard_backlight_sensor = manager_->GetSensorForKeyboardBacklight(); |
| keyboard_backlight_sensor->AddObserver(&keyboard_backlight_observer_); |
| ASSERT_TRUE(keyboard_backlight_observer_.RunUntilAmbientLightUpdated()); |
| EXPECT_EQ(0, keyboard_backlight_sensor->GetAmbientLightLux()); |
| EXPECT_EQ(data_file, keyboard_backlight_sensor->GetIlluminancePath()); |
| keyboard_backlight_sensor->RemoveObserver(&keyboard_backlight_observer_); |
| |
| EXPECT_FALSE(manager_->HasColorSensor()); |
| } |
| |
| TEST_F(AmbientLightSensorManagerTest, TwoSensors) { |
| prefs_.SetInt64(kHasAmbientLightSensorPref, 2); |
| base::FilePath data0_file = AddSensor(0, "lid", false); |
| base::FilePath data1_file = AddSensor(1, "base", false); |
| |
| manager_->Init(&prefs_); |
| manager_->set_device_list_path_for_testing(temp_dir_.GetPath()); |
| manager_->set_poll_interval_ms_for_testing(kPollIntervalMs); |
| manager_->Run(false /* read_immediately */); |
| |
| auto internal_backlight_sensor = manager_->GetSensorForInternalBacklight(); |
| internal_backlight_sensor->AddObserver(&internal_backlight_observer_); |
| ASSERT_TRUE(internal_backlight_observer_.RunUntilAmbientLightUpdated()); |
| EXPECT_EQ(0, internal_backlight_sensor->GetAmbientLightLux()); |
| EXPECT_EQ(data0_file, internal_backlight_sensor->GetIlluminancePath()); |
| internal_backlight_sensor->RemoveObserver(&internal_backlight_observer_); |
| |
| auto keyboard_backlight_sensor = manager_->GetSensorForKeyboardBacklight(); |
| keyboard_backlight_sensor->AddObserver(&keyboard_backlight_observer_); |
| ASSERT_TRUE(keyboard_backlight_observer_.RunUntilAmbientLightUpdated()); |
| EXPECT_EQ(1, keyboard_backlight_sensor->GetAmbientLightLux()); |
| EXPECT_EQ(data1_file, keyboard_backlight_sensor->GetIlluminancePath()); |
| keyboard_backlight_sensor->RemoveObserver(&keyboard_backlight_observer_); |
| |
| EXPECT_FALSE(manager_->HasColorSensor()); |
| } |
| |
| TEST_F(AmbientLightSensorManagerTest, HasColorSensor) { |
| prefs_.SetInt64(kHasAmbientLightSensorPref, 2); |
| prefs_.SetInt64(kAllowAmbientEQ, 1); |
| base::FilePath data0_file = AddSensor(0, "lid", true); |
| base::FilePath data1_file = AddSensor(1, "base", false); |
| |
| manager_->Init(&prefs_); |
| manager_->set_device_list_path_for_testing(temp_dir_.GetPath()); |
| manager_->set_poll_interval_ms_for_testing(kPollIntervalMs); |
| manager_->Run(false /* read_immediately */); |
| |
| auto internal_backlight_sensor = manager_->GetSensorForInternalBacklight(); |
| internal_backlight_sensor->AddObserver(&internal_backlight_observer_); |
| ASSERT_TRUE(internal_backlight_observer_.RunUntilAmbientLightUpdated()); |
| EXPECT_EQ(0, internal_backlight_sensor->GetAmbientLightLux()); |
| EXPECT_EQ(data0_file, internal_backlight_sensor->GetIlluminancePath()); |
| internal_backlight_sensor->RemoveObserver(&internal_backlight_observer_); |
| |
| auto keyboard_backlight_sensor = manager_->GetSensorForKeyboardBacklight(); |
| keyboard_backlight_sensor->AddObserver(&keyboard_backlight_observer_); |
| ASSERT_TRUE(keyboard_backlight_observer_.RunUntilAmbientLightUpdated()); |
| EXPECT_EQ(1, keyboard_backlight_sensor->GetAmbientLightLux()); |
| EXPECT_EQ(data1_file, keyboard_backlight_sensor->GetIlluminancePath()); |
| keyboard_backlight_sensor->RemoveObserver(&keyboard_backlight_observer_); |
| |
| EXPECT_TRUE(manager_->HasColorSensor()); |
| } |
| |
| } // namespace system |
| } // namespace power_manager |