/* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <base/files/file_util.h> #include <base/files/scoped_temp_dir.h> #include <base/macros.h> #include <base/sys_info.h> #include <binder/IBinder.h> #include <binder/IInterface.h> #include <binderwrapper/binder_test_base.h> #include <binderwrapper/stub_binder_wrapper.h> #include <cutils/android_reboot.h> #include <nativepower/constants.h> #include <powermanager/PowerManager.h> #include "power_manager.h" #include "system_property_setter_stub.h" #include "wake_lock_manager_stub.h" namespace android { class PowerManagerTest : public BinderTestBase { public: PowerManagerTest() : power_manager_(new PowerManager()), interface_(interface_cast<IPowerManager>(power_manager_)), property_setter_(new SystemPropertySetterStub()), wake_lock_manager_(new WakeLockManagerStub()) { CHECK(temp_dir_.CreateUniqueTempDir()); power_state_path_ = temp_dir_.path().Append("power_state"); power_manager_->set_power_state_path_for_testing(power_state_path_); ClearPowerState(); power_manager_->set_property_setter_for_testing( std::unique_ptr<SystemPropertySetterInterface>(property_setter_)); power_manager_->set_wake_lock_manager_for_testing( std::unique_ptr<WakeLockManagerInterface>(wake_lock_manager_)); CHECK(power_manager_->Init()); } ~PowerManagerTest() override = default; protected: // Returns the value in |power_state_path_|. std::string ReadPowerState() { std::string state; PCHECK(base::ReadFileToString(power_state_path_, &state)) << "Failed to read " << power_state_path_.value(); return state; } // Clears |power_state_path_|. void ClearPowerState() { PCHECK(base::WriteFile(power_state_path_, "", 0) == 0) << "Failed to write " << power_state_path_.value(); } base::ScopedTempDir temp_dir_; sp<PowerManager> power_manager_; sp<IPowerManager> interface_; SystemPropertySetterStub* property_setter_; // Owned by |power_manager_|. WakeLockManagerStub* wake_lock_manager_; // Owned by |power_manager_|. // File under |temp_dir_| used in place of /sys/power/state. base::FilePath power_state_path_; private: DISALLOW_COPY_AND_ASSIGN(PowerManagerTest); }; TEST_F(PowerManagerTest, RegisterService) { EXPECT_EQ(power_manager_, binder_wrapper()->GetRegisteredService(kPowerManagerServiceName)); } TEST_F(PowerManagerTest, AcquireAndReleaseWakeLock) { const char kTag[] = "foo"; const char kPackage[] = "bar"; sp<BBinder> binder = binder_wrapper()->CreateLocalBinder(); // Check that PowerManager looks up the calling UID when necessary. const uid_t kCallingUid = 100; binder_wrapper()->set_calling_uid(kCallingUid); EXPECT_EQ(OK, interface_->acquireWakeLock(0, binder, String16(kTag), String16(kPackage))); EXPECT_EQ(1, wake_lock_manager_->num_requests()); EXPECT_EQ( WakeLockManagerStub::ConstructRequestString(kTag, kPackage, kCallingUid), wake_lock_manager_->GetRequestString( binder_wrapper()->local_binders()[0])); EXPECT_EQ(OK, interface_->releaseWakeLock(binder, 0)); EXPECT_EQ(0, wake_lock_manager_->num_requests()); // If a UID is passed, it should be used instead. const uid_t kPassedUid = 200; EXPECT_EQ(OK, interface_->acquireWakeLockWithUid( 0, binder, String16(kTag), String16(kPackage), kPassedUid)); EXPECT_EQ(1, wake_lock_manager_->num_requests()); EXPECT_EQ( WakeLockManagerStub::ConstructRequestString(kTag, kPackage, kPassedUid), wake_lock_manager_->GetRequestString( binder_wrapper()->local_binders()[0])); } TEST_F(PowerManagerTest, GoToSleep) { EXPECT_EQ("", ReadPowerState()); const int64_t kStartTime = base::SysInfo::Uptime().InMilliseconds(); EXPECT_EQ(OK, interface_->goToSleep(kStartTime, 0 /* reason */, 0 /* flags */)); EXPECT_EQ(PowerManager::kPowerStateSuspend, ReadPowerState()); // A request with a timestamp preceding the last resume should be ignored. ClearPowerState(); EXPECT_EQ(BAD_VALUE, interface_->goToSleep(kStartTime - 1, 0, 0)); EXPECT_EQ("", ReadPowerState()); // A second attempt with a timestamp occurring after the last // resume should be honored. ClearPowerState(); EXPECT_EQ( OK, interface_->goToSleep(base::SysInfo::Uptime().InMilliseconds(), 0, 0)); EXPECT_EQ(PowerManager::kPowerStateSuspend, ReadPowerState()); } TEST_F(PowerManagerTest, Reboot) { EXPECT_EQ(OK, interface_->reboot(false, String16(), false)); EXPECT_EQ(PowerManager::kRebootPrefix, property_setter_->GetProperty(ANDROID_RB_PROPERTY)); EXPECT_EQ(OK, interface_->reboot(false, String16(kRebootReasonRecovery), false)); EXPECT_EQ(std::string(PowerManager::kRebootPrefix) + kRebootReasonRecovery, property_setter_->GetProperty(ANDROID_RB_PROPERTY)); // Invalid values should be rejected. ASSERT_TRUE(property_setter_->SetProperty(ANDROID_RB_PROPERTY, "")); EXPECT_EQ(BAD_VALUE, interface_->reboot(false, String16("foo"), false)); EXPECT_EQ("", property_setter_->GetProperty(ANDROID_RB_PROPERTY)); } TEST_F(PowerManagerTest, Shutdown) { EXPECT_EQ(OK, interface_->shutdown(false, String16(), false)); EXPECT_EQ(PowerManager::kShutdownPrefix, property_setter_->GetProperty(ANDROID_RB_PROPERTY)); EXPECT_EQ(OK, interface_->shutdown(false, String16(kShutdownReasonUserRequested), false)); EXPECT_EQ(std::string(PowerManager::kShutdownPrefix) + kShutdownReasonUserRequested, property_setter_->GetProperty(ANDROID_RB_PROPERTY)); // Invalid values should be rejected. ASSERT_TRUE(property_setter_->SetProperty(ANDROID_RB_PROPERTY, "")); EXPECT_EQ(BAD_VALUE, interface_->shutdown(false, String16("foo"), false)); EXPECT_EQ("", property_setter_->GetProperty(ANDROID_RB_PROPERTY)); } } // namespace android