1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "power_hidl_hal_test"
18 #include <android-base/logging.h>
19 
20 #include <cutils/properties.h>
21 
22 #include <android-base/unique_fd.h>
23 #include <android/hardware/power/1.0/IPower.h>
24 #include <gtest/gtest.h>
25 #include <hidl/GtestPrinter.h>
26 #include <hidl/ServiceManagement.h>
27 
28 #include <fcntl.h>
29 #include <algorithm>
30 
31 using ::android::hardware::power::V1_0::IPower;
32 using ::android::hardware::power::V1_0::Feature;
33 using ::android::hardware::power::V1_0::PowerHint;
34 using ::android::hardware::power::V1_0::PowerStatePlatformSleepState;
35 using ::android::hardware::power::V1_0::Status;
36 using ::android::hardware::hidl_vec;
37 using ::android::hardware::Return;
38 using ::android::sp;
39 using ::android::base::unique_fd;
40 
41 using std::vector;
42 
43 #define CPU_GOVERNOR_PATH \
44   "/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor"
45 #define AVAILABLE_GOVERNORS_PATH \
46   "/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors"
47 
48 class PowerHidlTest : public testing::TestWithParam<std::string> {
49  public:
SetUp()50   virtual void SetUp() override {
51       power = IPower::getService(GetParam());
52       ASSERT_NE(power, nullptr);
53   }
54 
TearDown()55   virtual void TearDown() override {}
56 
57   sp<IPower> power;
58 };
59 
60 // Validate Power::setInteractive.
TEST_P(PowerHidlTest,SetInteractive)61 TEST_P(PowerHidlTest, SetInteractive) {
62   Return<void> ret;
63 
64   ret = power->setInteractive(true);
65   ASSERT_TRUE(ret.isOk());
66 
67   ret = power->setInteractive(false);
68   ASSERT_TRUE(ret.isOk());
69 }
70 
71 // Test Power::setInteractive and Power::powerHint(Launch)
72 // with each available CPU governor, if available
TEST_P(PowerHidlTest,TryDifferentGovernors)73 TEST_P(PowerHidlTest, TryDifferentGovernors) {
74   Return<void> ret;
75 
76   unique_fd fd1(open(CPU_GOVERNOR_PATH, O_RDWR));
77   unique_fd fd2(open(AVAILABLE_GOVERNORS_PATH, O_RDONLY));
78   if (fd1 < 0 || fd2 < 0) {
79     // Files don't exist, so skip the rest of the test case
80     SUCCEED();
81     return;
82   }
83 
84   char old_governor[80];
85   ASSERT_LE(0, read(fd1, old_governor, 80));
86 
87   char governors[1024];
88   unsigned len = read(fd2, governors, 1024);
89   ASSERT_LE(0u, len);
90   governors[len] = '\0';
91 
92   char *saveptr;
93   char *name = strtok_r(governors, " \n", &saveptr);
94   while (name) {
95     ASSERT_LE(0, write(fd1, name, strlen(name)));
96     ret = power->setInteractive(true);
97     ASSERT_TRUE(ret.isOk());
98 
99     ret = power->setInteractive(false);
100     ASSERT_TRUE(ret.isOk());
101 
102     ret = power->setInteractive(false);
103     ASSERT_TRUE(ret.isOk());
104 
105     power->powerHint(PowerHint::LAUNCH, 1);
106     power->powerHint(PowerHint::LAUNCH, 0);
107 
108     name = strtok_r(NULL, " \n", &saveptr);
109   }
110 
111   ASSERT_LE(0, write(fd1, old_governor, strlen(old_governor)));
112 }
113 
114 // Validate Power::powerHint on good and bad inputs.
TEST_P(PowerHidlTest,PowerHint)115 TEST_P(PowerHidlTest, PowerHint) {
116   PowerHint badHint = static_cast<PowerHint>(0xA);
117   auto hints = {PowerHint::VSYNC,         PowerHint::INTERACTION,
118                 PowerHint::VIDEO_ENCODE,  PowerHint::VIDEO_DECODE,
119                 PowerHint::LOW_POWER,     PowerHint::SUSTAINED_PERFORMANCE,
120                 PowerHint::VR_MODE,       PowerHint::LAUNCH,
121                 badHint};
122   Return<void> ret;
123   for (auto hint : hints) {
124     ret = power->powerHint(hint, 30000);
125     ASSERT_TRUE(ret.isOk());
126 
127     ret = power->powerHint(hint, 0);
128     ASSERT_TRUE(ret.isOk());
129   }
130 
131   // Turning these hints on in different orders triggers different code paths,
132   // so iterate over possible orderings.
133   std::vector<PowerHint> hints2 = {PowerHint::LAUNCH, PowerHint::VR_MODE,
134                                    PowerHint::SUSTAINED_PERFORMANCE,
135                                    PowerHint::INTERACTION};
136   auto compareHints = [](PowerHint l, PowerHint r) {
137     return static_cast<uint32_t>(l) < static_cast<uint32_t>(r);
138   };
139   std::sort(hints2.begin(), hints2.end(), compareHints);
140   do {
141     for (auto iter = hints2.begin(); iter != hints2.end(); iter++) {
142       ret = power->powerHint(*iter, 0);
143       ASSERT_TRUE(ret.isOk());
144     }
145     for (auto iter = hints2.begin(); iter != hints2.end(); iter++) {
146       ret = power->powerHint(*iter, 30000);
147       ASSERT_TRUE(ret.isOk());
148     }
149   } while (std::next_permutation(hints2.begin(), hints2.end(), compareHints));
150 }
151 
152 // Validate Power::setFeature() on good and bad inputs.
TEST_P(PowerHidlTest,SetFeature)153 TEST_P(PowerHidlTest, SetFeature) {
154   Return<void> ret;
155   ret = power->setFeature(Feature::POWER_FEATURE_DOUBLE_TAP_TO_WAKE, true);
156   ASSERT_TRUE(ret.isOk());
157   ret = power->setFeature(Feature::POWER_FEATURE_DOUBLE_TAP_TO_WAKE, false);
158   ASSERT_TRUE(ret.isOk());
159 
160   Feature badFeature = static_cast<Feature>(0x2);
161   ret = power->setFeature(badFeature, true);
162   ASSERT_TRUE(ret.isOk());
163   ret = power->setFeature(badFeature, false);
164   ASSERT_TRUE(ret.isOk());
165 }
166 
167 // Validate Power::getPlatformLowPowerStats().
TEST_P(PowerHidlTest,GetPlatformLowPowerStats)168 TEST_P(PowerHidlTest, GetPlatformLowPowerStats) {
169   hidl_vec<PowerStatePlatformSleepState> vec;
170   Status s;
171   auto cb = [&vec, &s](hidl_vec<PowerStatePlatformSleepState> states,
172                        Status status) {
173     vec = states;
174     s = status;
175   };
176   Return<void> ret = power->getPlatformLowPowerStats(cb);
177   ASSERT_TRUE(ret.isOk());
178   ASSERT_TRUE(s == Status::SUCCESS || s == Status::FILESYSTEM_ERROR);
179 }
180 
181 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PowerHidlTest);
182 INSTANTIATE_TEST_SUITE_P(
183         PerInstance, PowerHidlTest,
184         testing::ValuesIn(android::hardware::getAllHalInstanceNames(IPower::descriptor)),
185         android::hardware::PrintInstanceNameToString);
186