/*
* 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