• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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 "PowerHalWrapperAidlTest"
18 
19 #include <aidl/android/hardware/power/Boost.h>
20 #include <aidl/android/hardware/power/IPowerHintSession.h>
21 #include <aidl/android/hardware/power/Mode.h>
22 #include <binder/IServiceManager.h>
23 #include <gmock/gmock.h>
24 #include <gtest/gtest.h>
25 #include <powermanager/PowerHalWrapper.h>
26 #include <utils/Log.h>
27 
28 #include <unistd.h>
29 #include <thread>
30 
31 using aidl::android::hardware::power::Boost;
32 using aidl::android::hardware::power::ChannelConfig;
33 using aidl::android::hardware::power::IPower;
34 using aidl::android::hardware::power::IPowerHintSession;
35 using aidl::android::hardware::power::Mode;
36 using aidl::android::hardware::power::SessionConfig;
37 using aidl::android::hardware::power::SessionTag;
38 using android::binder::Status;
39 
40 using namespace android;
41 using namespace android::power;
42 using namespace std::chrono_literals;
43 using namespace testing;
44 
45 // -------------------------------------------------------------------------------------------------
46 
47 class MockIPower : public IPower {
48 public:
49     MockIPower() = default;
50 
51     MOCK_METHOD(ndk::ScopedAStatus, isBoostSupported, (Boost boost, bool* ret), (override));
52     MOCK_METHOD(ndk::ScopedAStatus, setBoost, (Boost boost, int32_t durationMs), (override));
53     MOCK_METHOD(ndk::ScopedAStatus, isModeSupported, (Mode mode, bool* ret), (override));
54     MOCK_METHOD(ndk::ScopedAStatus, setMode, (Mode mode, bool enabled), (override));
55     MOCK_METHOD(ndk::ScopedAStatus, createHintSession,
56                 (int32_t tgid, int32_t uid, const std::vector<int32_t>& threadIds,
57                  int64_t durationNanos, std::shared_ptr<IPowerHintSession>* session),
58                 (override));
59     MOCK_METHOD(ndk::ScopedAStatus, createHintSessionWithConfig,
60                 (int32_t tgid, int32_t uid, const std::vector<int32_t>& threadIds,
61                  int64_t durationNanos, SessionTag tag, SessionConfig* config,
62                  std::shared_ptr<IPowerHintSession>* _aidl_return),
63                 (override));
64     MOCK_METHOD(ndk::ScopedAStatus, getSessionChannel,
65                 (int32_t tgid, int32_t uid, ChannelConfig* _aidl_return), (override));
66     MOCK_METHOD(ndk::ScopedAStatus, closeSessionChannel, (int32_t tgid, int32_t uid), (override));
67     MOCK_METHOD(ndk::ScopedAStatus, getHintSessionPreferredRate, (int64_t * rate), (override));
68     MOCK_METHOD(ndk::ScopedAStatus, getInterfaceVersion, (int32_t * version), (override));
69     MOCK_METHOD(ndk::ScopedAStatus, getInterfaceHash, (std::string * hash), (override));
70     MOCK_METHOD(ndk::SpAIBinder, asBinder, (), (override));
71     MOCK_METHOD(bool, isRemote, (), (override));
72 };
73 
74 // -------------------------------------------------------------------------------------------------
75 
76 class PowerHalWrapperAidlTest : public Test {
77 public:
78     void SetUp() override;
79 
80 protected:
81     std::unique_ptr<HalWrapper> mWrapper = nullptr;
82     std::shared_ptr<StrictMock<MockIPower>> mMockHal = nullptr;
83 };
84 
85 // -------------------------------------------------------------------------------------------------
86 
SetUp()87 void PowerHalWrapperAidlTest::SetUp() {
88     mMockHal = ndk::SharedRefBase::make<StrictMock<MockIPower>>();
89     EXPECT_CALL(*mMockHal, getInterfaceVersion(_)).WillRepeatedly(([](int32_t* ret) {
90         *ret = 5;
91         return ndk::ScopedAStatus::ok();
92     }));
93     mWrapper = std::make_unique<AidlHalWrapper>(mMockHal);
94     ASSERT_NE(nullptr, mWrapper);
95 }
96 
97 // -------------------------------------------------------------------------------------------------
98 
TEST_F(PowerHalWrapperAidlTest,TestSetBoostSuccessful)99 TEST_F(PowerHalWrapperAidlTest, TestSetBoostSuccessful) {
100     {
101         InSequence seq;
102         EXPECT_CALL(*mMockHal.get(), isBoostSupported(Eq(Boost::DISPLAY_UPDATE_IMMINENT), _))
103                 .Times(Exactly(1))
104                 .WillOnce(DoAll(SetArgPointee<1>(true),
105                                 Return(testing::ByMove(ndk::ScopedAStatus::ok()))));
106         EXPECT_CALL(*mMockHal.get(), setBoost(Eq(Boost::DISPLAY_UPDATE_IMMINENT), Eq(100)))
107                 .Times(Exactly(1))
108                 .WillOnce(Return(testing::ByMove(ndk::ScopedAStatus::ok())));
109     }
110 
111     auto result = mWrapper->setBoost(Boost::DISPLAY_UPDATE_IMMINENT, 100);
112     ASSERT_TRUE(result.isOk());
113 }
114 
TEST_F(PowerHalWrapperAidlTest,TestSetBoostFailed)115 TEST_F(PowerHalWrapperAidlTest, TestSetBoostFailed) {
116     {
117         InSequence seq;
118         EXPECT_CALL(*mMockHal.get(), isBoostSupported(Eq(Boost::INTERACTION), _))
119                 .Times(Exactly(1))
120                 .WillOnce(DoAll(SetArgPointee<1>(true),
121                                 Return(testing::ByMove(ndk::ScopedAStatus::ok()))));
122         EXPECT_CALL(*mMockHal.get(), setBoost(Eq(Boost::INTERACTION), Eq(100)))
123                 .Times(Exactly(1))
124                 .WillOnce(Return(testing::ByMove(ndk::ScopedAStatus::fromExceptionCode(-1))));
125         EXPECT_CALL(*mMockHal.get(), isBoostSupported(Eq(Boost::DISPLAY_UPDATE_IMMINENT), _))
126                 .Times(Exactly(1))
127                 .WillOnce(Return(testing::ByMove(ndk::ScopedAStatus::fromExceptionCode(-1))));
128     }
129 
130     auto result = mWrapper->setBoost(Boost::INTERACTION, 100);
131     ASSERT_TRUE(result.isFailed());
132     result = mWrapper->setBoost(Boost::DISPLAY_UPDATE_IMMINENT, 1000);
133     ASSERT_TRUE(result.isFailed());
134 }
135 
TEST_F(PowerHalWrapperAidlTest,TestSetBoostUnsupported)136 TEST_F(PowerHalWrapperAidlTest, TestSetBoostUnsupported) {
137     EXPECT_CALL(*mMockHal.get(), isBoostSupported(_, _))
138             .Times(Exactly(2))
139             .WillRepeatedly([](Boost, bool* ret) {
140                 *ret = false;
141                 return ndk::ScopedAStatus::ok();
142             });
143 
144     auto result = mWrapper->setBoost(Boost::INTERACTION, 1000);
145     ASSERT_TRUE(result.isUnsupported());
146     result = mWrapper->setBoost(Boost::CAMERA_SHOT, 10);
147     ASSERT_TRUE(result.isUnsupported());
148 }
149 
TEST_F(PowerHalWrapperAidlTest,TestSetBoostMultiThreadCheckSupportedOnlyOnce)150 TEST_F(PowerHalWrapperAidlTest, TestSetBoostMultiThreadCheckSupportedOnlyOnce) {
151     {
152         InSequence seq;
153         EXPECT_CALL(*mMockHal.get(), isBoostSupported(Eq(Boost::INTERACTION), _))
154                 .Times(Exactly(1))
155                 .WillOnce(DoAll(SetArgPointee<1>(true),
156                                 Return(testing::ByMove(ndk::ScopedAStatus::ok()))));
157         auto& exp = EXPECT_CALL(*mMockHal.get(), setBoost(Eq(Boost::INTERACTION), Eq(100)))
158                             .Times(Exactly(10));
159         for (int i = 0; i < 10; i++) {
160             exp.WillOnce(Return(testing::ByMove(ndk::ScopedAStatus::ok())));
161         }
162     }
163 
164     std::vector<std::thread> threads;
165     for (int i = 0; i < 10; i++) {
166         threads.push_back(std::thread([&]() {
167             auto result = mWrapper->setBoost(Boost::INTERACTION, 100);
168             ASSERT_TRUE(result.isOk());
169         }));
170     }
171     std::for_each(threads.begin(), threads.end(), [](std::thread& t) { t.join(); });
172 }
173 
TEST_F(PowerHalWrapperAidlTest,TestSetModeSuccessful)174 TEST_F(PowerHalWrapperAidlTest, TestSetModeSuccessful) {
175     {
176         InSequence seq;
177         EXPECT_CALL(*mMockHal.get(), isModeSupported(Eq(Mode::DISPLAY_INACTIVE), _))
178                 .Times(Exactly(1))
179                 .WillOnce(DoAll(SetArgPointee<1>(true),
180                                 Return(testing::ByMove(ndk::ScopedAStatus::ok()))));
181         EXPECT_CALL(*mMockHal.get(), setMode(Eq(Mode::DISPLAY_INACTIVE), Eq(false)))
182                 .Times(Exactly(1))
183                 .WillOnce(Return(testing::ByMove(ndk::ScopedAStatus::ok())));
184     }
185 
186     auto result = mWrapper->setMode(Mode::DISPLAY_INACTIVE, false);
187     ASSERT_TRUE(result.isOk());
188 }
189 
TEST_F(PowerHalWrapperAidlTest,TestSetModeFailed)190 TEST_F(PowerHalWrapperAidlTest, TestSetModeFailed) {
191     {
192         InSequence seq;
193         EXPECT_CALL(*mMockHal.get(), isModeSupported(Eq(Mode::LAUNCH), _))
194                 .Times(Exactly(1))
195                 .WillOnce(DoAll(SetArgPointee<1>(true),
196                                 Return(testing::ByMove(ndk::ScopedAStatus::ok()))));
197         EXPECT_CALL(*mMockHal.get(), setMode(Eq(Mode::LAUNCH), Eq(true)))
198                 .Times(Exactly(1))
199                 .WillOnce(Return(testing::ByMove(ndk::ScopedAStatus::fromExceptionCode(-1))));
200         EXPECT_CALL(*mMockHal.get(), isModeSupported(Eq(Mode::DISPLAY_INACTIVE), _))
201                 .Times(Exactly(1))
202                 .WillOnce(Return(testing::ByMove(ndk::ScopedAStatus::fromExceptionCode(-1))));
203     }
204 
205     auto result = mWrapper->setMode(Mode::LAUNCH, true);
206     ASSERT_TRUE(result.isFailed());
207     result = mWrapper->setMode(Mode::DISPLAY_INACTIVE, false);
208     ASSERT_TRUE(result.isFailed());
209 }
210 
TEST_F(PowerHalWrapperAidlTest,TestSetModeUnsupported)211 TEST_F(PowerHalWrapperAidlTest, TestSetModeUnsupported) {
212     EXPECT_CALL(*mMockHal.get(), isModeSupported(Eq(Mode::LAUNCH), _))
213             .Times(Exactly(1))
214             .WillOnce(DoAll(SetArgPointee<1>(false),
215                             Return(testing::ByMove(ndk::ScopedAStatus::ok()))));
216 
217     auto result = mWrapper->setMode(Mode::LAUNCH, true);
218     ASSERT_TRUE(result.isUnsupported());
219 
220     EXPECT_CALL(*mMockHal.get(), isModeSupported(Eq(Mode::CAMERA_STREAMING_HIGH), _))
221             .Times(Exactly(1))
222             .WillOnce(DoAll(SetArgPointee<1>(false),
223                             Return(testing::ByMove(ndk::ScopedAStatus::ok()))));
224     result = mWrapper->setMode(Mode::CAMERA_STREAMING_HIGH, true);
225     ASSERT_TRUE(result.isUnsupported());
226 }
227 
TEST_F(PowerHalWrapperAidlTest,TestSetModeMultiThreadCheckSupportedOnlyOnce)228 TEST_F(PowerHalWrapperAidlTest, TestSetModeMultiThreadCheckSupportedOnlyOnce) {
229     {
230         InSequence seq;
231         EXPECT_CALL(*mMockHal.get(), isModeSupported(Eq(Mode::LAUNCH), _))
232                 .Times(Exactly(1))
233                 .WillOnce(DoAll(SetArgPointee<1>(true),
234                                 Return(testing::ByMove(ndk::ScopedAStatus::ok()))));
235         auto& exp = EXPECT_CALL(*mMockHal.get(), setMode(Eq(Mode::LAUNCH), Eq(false)))
236                             .Times(Exactly(10));
237         for (int i = 0; i < 10; i++) {
238             exp.WillOnce(Return(testing::ByMove(ndk::ScopedAStatus::ok())));
239         }
240     }
241 
242     std::vector<std::thread> threads;
243     for (int i = 0; i < 10; i++) {
244         threads.push_back(std::thread([&]() {
245             auto result = mWrapper->setMode(Mode::LAUNCH, false);
246             ASSERT_TRUE(result.isOk());
247         }));
248     }
249     std::for_each(threads.begin(), threads.end(), [](std::thread& t) { t.join(); });
250 }
251 
TEST_F(PowerHalWrapperAidlTest,TestCreateHintSessionSuccessful)252 TEST_F(PowerHalWrapperAidlTest, TestCreateHintSessionSuccessful) {
253     std::vector<int> threadIds{gettid()};
254     int32_t tgid = 999;
255     int32_t uid = 1001;
256     int64_t durationNanos = 16666666L;
257     EXPECT_CALL(*mMockHal.get(),
258                 createHintSession(Eq(tgid), Eq(uid), Eq(threadIds), Eq(durationNanos), _))
259             .Times(Exactly(1))
260             .WillOnce(Return(testing::ByMove(ndk::ScopedAStatus::ok())));
261     auto result = mWrapper->createHintSession(tgid, uid, threadIds, durationNanos);
262     ASSERT_TRUE(result.isOk());
263 }
264 
TEST_F(PowerHalWrapperAidlTest,TestCreateHintSessionWithConfigSuccessful)265 TEST_F(PowerHalWrapperAidlTest, TestCreateHintSessionWithConfigSuccessful) {
266     std::vector<int> threadIds{gettid()};
267     int32_t tgid = 999;
268     int32_t uid = 1001;
269     int64_t durationNanos = 16666666L;
270     SessionTag tag = SessionTag::OTHER;
271     SessionConfig out;
272     EXPECT_CALL(*mMockHal.get(),
273                 createHintSessionWithConfig(Eq(tgid), Eq(uid), Eq(threadIds), Eq(durationNanos),
274                                             Eq(tag), _, _))
275             .Times(Exactly(1))
276             .WillOnce(Return(testing::ByMove(ndk::ScopedAStatus::ok())));
277     auto result =
278             mWrapper->createHintSessionWithConfig(tgid, uid, threadIds, durationNanos, tag, &out);
279     ASSERT_TRUE(result.isOk());
280 }
281 
TEST_F(PowerHalWrapperAidlTest,TestCreateHintSessionFailed)282 TEST_F(PowerHalWrapperAidlTest, TestCreateHintSessionFailed) {
283     int32_t tgid = 999;
284     int32_t uid = 1001;
285     std::vector<int> threadIds{};
286     int64_t durationNanos = 16666666L;
287     EXPECT_CALL(*mMockHal.get(),
288                 createHintSession(Eq(tgid), Eq(uid), Eq(threadIds), Eq(durationNanos), _))
289             .Times(Exactly(1))
290             .WillOnce(Return(testing::ByMove(
291                     ndk::ScopedAStatus::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT))));
292     auto result = mWrapper->createHintSession(tgid, uid, threadIds, durationNanos);
293     ASSERT_TRUE(result.isFailed());
294 }
295 
TEST_F(PowerHalWrapperAidlTest,TestGetHintSessionPreferredRate)296 TEST_F(PowerHalWrapperAidlTest, TestGetHintSessionPreferredRate) {
297     EXPECT_CALL(*mMockHal.get(), getHintSessionPreferredRate(_))
298             .Times(Exactly(1))
299             .WillOnce(Return(testing::ByMove(ndk::ScopedAStatus::ok())));
300     auto result = mWrapper->getHintSessionPreferredRate();
301     ASSERT_TRUE(result.isOk());
302     int64_t rate = result.value();
303     ASSERT_GE(0, rate);
304 }
305 
TEST_F(PowerHalWrapperAidlTest,TestSessionChannel)306 TEST_F(PowerHalWrapperAidlTest, TestSessionChannel) {
307     int32_t tgid = 999;
308     int32_t uid = 1001;
309     EXPECT_CALL(*mMockHal.get(), getSessionChannel(Eq(tgid), Eq(uid), _))
310             .Times(Exactly(1))
311             .WillOnce(Return(testing::ByMove(ndk::ScopedAStatus::ok())));
312     EXPECT_CALL(*mMockHal.get(), closeSessionChannel(Eq(tgid), Eq(uid)))
313             .Times(Exactly(1))
314             .WillOnce(Return(testing::ByMove(ndk::ScopedAStatus::ok())));
315     auto createResult = mWrapper->getSessionChannel(tgid, uid);
316     ASSERT_TRUE(createResult.isOk());
317     auto closeResult = mWrapper->closeSessionChannel(tgid, uid);
318     ASSERT_TRUE(closeResult.isOk());
319 }
320 
TEST_F(PowerHalWrapperAidlTest,TestCreateHintSessionWithConfigUnsupported)321 TEST_F(PowerHalWrapperAidlTest, TestCreateHintSessionWithConfigUnsupported) {
322     std::vector<int> threadIds{gettid()};
323     int32_t tgid = 999;
324     int32_t uid = 1001;
325     int64_t durationNanos = 16666666L;
326     SessionTag tag = SessionTag::OTHER;
327     SessionConfig out;
328     EXPECT_CALL(*mMockHal.get(),
329                 createHintSessionWithConfig(Eq(tgid), Eq(uid), Eq(threadIds), Eq(durationNanos),
330                                             Eq(tag), _, _))
331             .Times(1)
332             .WillOnce(Return(testing::ByMove(
333                     ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION))));
334     auto result =
335             mWrapper->createHintSessionWithConfig(tgid, uid, threadIds, durationNanos, tag, &out);
336     ASSERT_TRUE(result.isUnsupported());
337     Mock::VerifyAndClearExpectations(mMockHal.get());
338     EXPECT_CALL(*mMockHal.get(),
339                 createHintSessionWithConfig(Eq(tgid), Eq(uid), Eq(threadIds), Eq(durationNanos),
340                                             Eq(tag), _, _))
341             .WillOnce(Return(
342                     testing::ByMove(ndk::ScopedAStatus::fromStatus(STATUS_UNKNOWN_TRANSACTION))));
343     result = mWrapper->createHintSessionWithConfig(tgid, uid, threadIds, durationNanos, tag, &out);
344     ASSERT_TRUE(result.isUnsupported());
345 }
346