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 #include "CarPowerPolicyServer.h"
18
19 #include <aidl/android/automotive/powerpolicy/internal/BnCarPowerPolicyDelegateCallback.h>
20 #include <aidl/android/automotive/powerpolicy/internal/PowerPolicyFailureReason.h>
21 #include <aidl/android/automotive/powerpolicy/internal/PowerPolicyInitData.h>
22 #include <aidl/android/frameworks/automotive/powerpolicy/BnCarPowerPolicyChangeCallback.h>
23 #include <aidl/android/frameworks/automotive/powerpolicy/CarPowerPolicy.h>
24 #include <aidl/android/frameworks/automotive/powerpolicy/CarPowerPolicyFilter.h>
25 #include <aidl/android/frameworks/automotive/powerpolicy/ICarPowerPolicyChangeCallback.h>
26 #include <aidl/android/frameworks/automotive/powerpolicy/ICarPowerPolicyServer.h>
27 #include <aidl/android/frameworks/automotive/powerpolicy/PowerComponent.h>
28 #include <android-base/file.h>
29 #include <android-base/thread_annotations.h>
30 #include <binder/IPCThreadState.h>
31 #include <gmock/gmock.h>
32 #include <private/android_filesystem_config.h>
33 #include <utils/Looper.h>
34 #include <utils/Mutex.h>
35 #include <utils/StrongPointer.h>
36
37 #include <android_car_feature.h>
38 #include <tinyxml2.h>
39
40 #include <chrono> // NOLINT(build/c++11)
41 #include <mutex> // NOLINT(build/c++11)
42 #include <thread> // NOLINT(build/c++11)
43 #include <unordered_set>
44
45 namespace android {
46 namespace frameworks {
47 namespace automotive {
48 namespace powerpolicy {
49
50 using android::IBinder;
51
52 using ::aidl::android::automotive::powerpolicy::internal::BnCarPowerPolicyDelegateCallback;
53 using ::aidl::android::automotive::powerpolicy::internal::ICarPowerPolicyDelegate;
54 using ::aidl::android::automotive::powerpolicy::internal::ICarPowerPolicyDelegateCallback;
55 using ::aidl::android::automotive::powerpolicy::internal::PowerPolicyFailureReason;
56 using ::aidl::android::automotive::powerpolicy::internal::PowerPolicyInitData;
57 using ::aidl::android::frameworks::automotive::powerpolicy::BnCarPowerPolicyChangeCallback;
58 using ::aidl::android::frameworks::automotive::powerpolicy::CarPowerPolicy;
59 using ::aidl::android::frameworks::automotive::powerpolicy::CarPowerPolicyFilter;
60 using ::aidl::android::frameworks::automotive::powerpolicy::ICarPowerPolicyChangeCallback;
61 using ::aidl::android::frameworks::automotive::powerpolicy::ICarPowerPolicyServer;
62 using ::aidl::android::frameworks::automotive::powerpolicy::PowerComponent;
63
64 using ::android::car::feature::car_power_policy_refactoring;
65
66 using ::ndk::ScopedAStatus;
67 using ::ndk::SpAIBinder;
68
69 using ::std::chrono_literals::operator""ms;
70
71 using ::testing::_;
72 using ::testing::Invoke;
73 using ::testing::Return;
74
75 using ::tinyxml2::XML_SUCCESS;
76 using ::tinyxml2::XMLDocument;
77
78 namespace {
79
80 constexpr const char* kDirPrefix = "/tests/data/";
81 constexpr const char* kValidPowerPolicyXmlFile = "valid_power_policy.xml";
82 constexpr const char* kTestLooperThreadName = "LooperThread";
83 constexpr std::chrono::duration kCallbackWaitTime = 5000ms;
84 constexpr std::chrono::duration kGeneralWaitTime = 2000ms;
85
86 class MockPowerPolicyChangeCallback : public BnCarPowerPolicyChangeCallback {
87 public:
onPolicyChanged(const CarPowerPolicy &)88 ScopedAStatus onPolicyChanged(const CarPowerPolicy& /*policy*/) override {
89 return ScopedAStatus::ok();
90 }
91 };
92
93 class MockPowerPolicyDelegateCallback : public BnCarPowerPolicyDelegateCallback {
94 public:
95 MOCK_METHOD(ScopedAStatus, updatePowerComponents, (const CarPowerPolicy&), (override));
96 MOCK_METHOD(ScopedAStatus, onApplyPowerPolicySucceeded, (int32_t, const CarPowerPolicy&, bool),
97 (override));
98 MOCK_METHOD(ScopedAStatus, onApplyPowerPolicyFailed, (int32_t, PowerPolicyFailureReason),
99 (override));
100 MOCK_METHOD(ScopedAStatus, onPowerPolicyChanged, (const CarPowerPolicy&), (override));
101 };
102
getTestDataPath(const char * filename)103 std::string getTestDataPath(const char* filename) {
104 static std::string baseDir = android::base::GetExecutableDirectory();
105 return baseDir + kDirPrefix + filename;
106 }
107
108 class ScopedChangeCallingUid final : public RefBase {
109 public:
ScopedChangeCallingUid(uid_t uid)110 explicit ScopedChangeCallingUid(uid_t uid) {
111 mCallingUid = IPCThreadState::self()->getCallingUid();
112 mCallingPid = IPCThreadState::self()->getCallingPid();
113 if (mCallingUid == uid) {
114 return;
115 }
116 mChangedUid = uid;
117 int64_t token = ((int64_t)mChangedUid << 32) | mCallingPid;
118 IPCThreadState::self()->restoreCallingIdentity(token);
119 }
~ScopedChangeCallingUid()120 ~ScopedChangeCallingUid() {
121 if (mCallingUid == mChangedUid) {
122 return;
123 }
124 int64_t token = ((int64_t)mCallingUid << 32) | mCallingPid;
125 IPCThreadState::self()->restoreCallingIdentity(token);
126 }
127
128 private:
129 uid_t mCallingUid;
130 uid_t mChangedUid;
131 pid_t mCallingPid;
132 };
133
134 } // namespace
135
136 namespace internal {
137
138 class CarPowerPolicyServerPeer : public RefBase {
139 public:
CarPowerPolicyServerPeer()140 CarPowerPolicyServerPeer() {
141 std::unique_ptr<MockLinkUnlinkImpl> impl = std::make_unique<MockLinkUnlinkImpl>();
142 // We know this would be alive as long as server is alive.
143 mLinkUnlinkImpl = impl.get();
144 mServer = ndk::SharedRefBase::make<CarPowerPolicyServer>();
145 mServer->setLinkUnlinkImpl(std::move(impl));
146 mBinder = mServer->asBinder();
147 mServerProxy = ICarPowerPolicyServer::fromBinder(mBinder);
148 }
149
~CarPowerPolicyServerPeer()150 ~CarPowerPolicyServerPeer() {
151 if (mServer->mHandlerLooper != nullptr) {
152 release();
153 }
154 }
155
getCurrentPowerPolicy(CarPowerPolicy * aidlReturn)156 ScopedAStatus getCurrentPowerPolicy(CarPowerPolicy* aidlReturn) {
157 return mServerProxy->getCurrentPowerPolicy(aidlReturn);
158 }
159
registerPowerPolicyChangeCallback(const std::shared_ptr<ICarPowerPolicyChangeCallback> & callback,const CarPowerPolicyFilter & filter)160 ScopedAStatus registerPowerPolicyChangeCallback(
161 const std::shared_ptr<ICarPowerPolicyChangeCallback>& callback,
162 const CarPowerPolicyFilter& filter) {
163 return mServerProxy->registerPowerPolicyChangeCallback(callback, filter);
164 }
165
unregisterPowerPolicyChangeCallback(const std::shared_ptr<ICarPowerPolicyChangeCallback> & callback)166 ScopedAStatus unregisterPowerPolicyChangeCallback(
167 const std::shared_ptr<ICarPowerPolicyChangeCallback>& callback) {
168 return mServerProxy->unregisterPowerPolicyChangeCallback(callback);
169 }
170
applyPowerPolicy(const std::string & policyId)171 ScopedAStatus applyPowerPolicy(const std::string& policyId) {
172 return mServerProxy->applyPowerPolicy(policyId);
173 }
174
notifyCarServiceReady(const std::shared_ptr<ICarPowerPolicyDelegateCallback> & callback,PowerPolicyInitData * aidlReturn)175 ScopedAStatus notifyCarServiceReady(
176 const std::shared_ptr<ICarPowerPolicyDelegateCallback>& callback,
177 PowerPolicyInitData* aidlReturn) {
178 return mServer->notifyCarServiceReadyInternal(callback, aidlReturn);
179 }
180
applyPowerPolicyAsync(int32_t requestId,const std::string & policyId,bool force)181 ScopedAStatus applyPowerPolicyAsync(int32_t requestId, const std::string& policyId,
182 bool force) {
183 return mServer->applyPowerPolicyAsync(requestId, policyId, force);
184 }
185
applyPowerPolicyPerPowerStateChangeAsync(int32_t requestId,ICarPowerPolicyDelegate::PowerState state)186 ScopedAStatus applyPowerPolicyPerPowerStateChangeAsync(
187 int32_t requestId, ICarPowerPolicyDelegate::PowerState state) {
188 return mServer->applyPowerPolicyPerPowerStateChangeAsync(requestId, state);
189 }
190
setPowerPolicyGroup(const std::string & policyGroupId)191 ScopedAStatus setPowerPolicyGroup(const std::string& policyGroupId) {
192 return mServer->setPowerPolicyGroup(policyGroupId);
193 }
194
init()195 void init() {
196 initializeLooper();
197 ASSERT_NO_FATAL_FAILURE(initializePolicyManager());
198 initializePowerComponentHandler();
199 ASSERT_NO_FATAL_FAILURE(applyInitialPolicy());
200 }
201
release()202 void release() { finalizeLooper(); }
203
onClientBinderDied(void * cookie)204 void onClientBinderDied(void* cookie) { mServer->onClientBinderDied(cookie); }
205
onClientDeathRecipientUnlinked(void * cookie)206 void onClientDeathRecipientUnlinked(void* cookie) {
207 mServer->onClientDeathRecipientUnlinked(cookie);
208 }
209
getPolicyChangeCallbacks()210 std::vector<CallbackInfo> getPolicyChangeCallbacks() {
211 return mServer->getPolicyChangeCallbacks();
212 }
213
countOnClientBinderDiedContexts()214 size_t countOnClientBinderDiedContexts() { return mServer->countOnClientBinderDiedContexts(); }
215
getCookies()216 std::unordered_set<void*> getCookies() { return mLinkUnlinkImpl->getCookies(); }
217
expectLinkToDeathStatus(AIBinder * binder,status_t linkToDeathResult)218 void expectLinkToDeathStatus(AIBinder* binder, status_t linkToDeathResult) {
219 mLinkUnlinkImpl->expectLinkToDeathStatus(binder, linkToDeathResult);
220 }
221
222 private:
initializeLooper()223 void initializeLooper() {
224 sp<Looper> looper = Looper::prepare(/*opts=*/0);
225 mServer->mHandlerLooper = looper;
226 std::mutex mutex;
227 std::condition_variable cv;
228 bool looperReady = false;
229 mHandlerLooperThread = std::thread([looper, &cv, &mutex, &looperReady, this]() {
230 Looper::setForThread(looper);
231 if (int result = pthread_setname_np(pthread_self(), kTestLooperThreadName);
232 result != 0) {
233 ALOGE("Failed to set test looper thread name: %s", strerror(result));
234 }
235 mShouldTerminateLooper.store(false);
236 {
237 std::unique_lock lock(mutex);
238 looperReady = true;
239 cv.notify_all();
240 }
241 while (!mShouldTerminateLooper.load()) {
242 looper->pollOnce(/*timeoutMillis=*/-1);
243 }
244 });
245 std::unique_lock lock(mutex);
246 // Wait until thread looper is ready.
247 cv.wait(lock, [&looperReady] { return looperReady; });
248 }
249
finalizeLooper()250 void finalizeLooper() {
251 mShouldTerminateLooper.store(true);
252 mServer->mHandlerLooper->wake();
253 if (mHandlerLooperThread.joinable()) {
254 mHandlerLooperThread.join();
255 }
256 }
257
initializePolicyManager()258 void initializePolicyManager() {
259 PolicyManager& policyManager = mServer->mPolicyManager;
260 policyManager.initRegularPowerPolicy(/*override=*/true);
261 policyManager.initPreemptivePowerPolicy();
262
263 XMLDocument xmlDoc;
264 std::string path = getTestDataPath(kValidPowerPolicyXmlFile);
265 xmlDoc.LoadFile(path.c_str());
266 ASSERT_TRUE(xmlDoc.ErrorID() == XML_SUCCESS);
267 policyManager.readPowerPolicyFromXml(xmlDoc);
268 }
269
initializePowerComponentHandler()270 void initializePowerComponentHandler() {
271 PowerComponentHandler& componentHandler = mServer->mComponentHandler;
272 componentHandler.init();
273 }
274
applyInitialPolicy()275 void applyInitialPolicy() {
276 auto policyMeta = mServer->mPolicyManager.getPowerPolicy(kSystemPolicyIdInitialOn);
277 ASSERT_TRUE(policyMeta.ok());
278 mServer->mCurrentPowerPolicyMeta = *policyMeta;
279 }
280
281 private:
282 class MockLinkUnlinkImpl : public CarPowerPolicyServer::LinkUnlinkImpl {
283 public:
284 MOCK_METHOD(binder_status_t, linkToDeath, (AIBinder*, AIBinder_DeathRecipient*, void*),
285 (override));
286 MOCK_METHOD(binder_status_t, unlinkToDeath, (AIBinder*, AIBinder_DeathRecipient*, void*),
287 (override));
288 MOCK_METHOD(void, setOnUnlinked,
289 (AIBinder_DeathRecipient*, AIBinder_DeathRecipient_onBinderUnlinked),
290 (override));
291 MOCK_METHOD(void, deleteDeathRecipient, (AIBinder_DeathRecipient*), (override));
292
MockLinkUnlinkImpl()293 MockLinkUnlinkImpl() {
294 ON_CALL(*this, setOnUnlinked(_, _))
295 .WillByDefault(
296 Invoke([this](AIBinder_DeathRecipient* recipient,
297 AIBinder_DeathRecipient_onBinderUnlinked onUnlinked) {
298 Mutex::Autolock lock(mMutex);
299 mOnUnlinked[recipient] = onUnlinked;
300 }));
301 ON_CALL(*this, deleteDeathRecipient(_))
302 .WillByDefault(Invoke([this](AIBinder_DeathRecipient* recipient) {
303 // Call onUnlinked for all the death recipients that are still registered.
304 std::unordered_set<void*> cookies;
305 AIBinder_DeathRecipient_onBinderUnlinked onUnlinked;
306 {
307 Mutex::Autolock lock(mMutex);
308 cookies = mCookies[recipient];
309 onUnlinked = *mOnUnlinked[recipient];
310 }
311
312 for (const auto& cookie : cookies) {
313 (*onUnlinked)(cookie);
314 }
315 }));
316 }
317
expectLinkToDeathStatus(AIBinder * binder,binder_status_t linkToDeathResult)318 void expectLinkToDeathStatus(AIBinder* binder, binder_status_t linkToDeathResult) {
319 EXPECT_CALL(*this, linkToDeath(binder, _, _))
320 .WillRepeatedly(Invoke(
321 [this, linkToDeathResult](AIBinder*, AIBinder_DeathRecipient* recipient,
322 void* cookie) {
323 // If success, store the cookie with the death recipient, otherwise,
324 // call onUnlinked.
325 if (linkToDeathResult != STATUS_OK) {
326 (*getOnUnlinked(recipient))(cookie);
327 return linkToDeathResult;
328 }
329 Mutex::Autolock lock(mMutex);
330 mCookies[recipient].insert(cookie);
331 return linkToDeathResult;
332 }));
333 EXPECT_CALL(*this, unlinkToDeath(binder, _, _))
334 .WillRepeatedly(Invoke(
335 [this](AIBinder*, AIBinder_DeathRecipient* recipient, void* cookie) {
336 // Remove the cookie and call onUnlinked.
337 {
338 Mutex::Autolock lock(mMutex);
339 mCookies[recipient].erase(cookie);
340 }
341 (*getOnUnlinked(recipient))(cookie);
342 return STATUS_OK;
343 }));
344 }
345
getCookies()346 std::unordered_set<void*> getCookies() {
347 Mutex::Autolock lock(mMutex);
348 std::unordered_set<void*> allCookies;
349 for (const auto& [recipient, cookies] : mCookies) {
350 for (const auto& cookie : cookies) {
351 allCookies.insert(cookie);
352 }
353 }
354 return allCookies;
355 }
356
357 private:
358 android::Mutex mMutex;
359 std::unordered_map<AIBinder_DeathRecipient*, std::unordered_set<void*>> mCookies
360 GUARDED_BY(mMutex);
361 std::unordered_map<AIBinder_DeathRecipient*, AIBinder_DeathRecipient_onBinderUnlinked>
362 mOnUnlinked GUARDED_BY(mMutex);
363
getOnUnlinked(AIBinder_DeathRecipient * recipient)364 AIBinder_DeathRecipient_onBinderUnlinked getOnUnlinked(AIBinder_DeathRecipient* recipient) {
365 Mutex::Autolock lock(mMutex);
366 return mOnUnlinked[recipient];
367 }
368 };
369
370 MockLinkUnlinkImpl* mLinkUnlinkImpl;
371 std::shared_ptr<CarPowerPolicyServer> mServer;
372 std::shared_ptr<ICarPowerPolicyServer> mServerProxy;
373 std::thread mHandlerLooperThread;
374 SpAIBinder mBinder;
375 std::atomic<bool> mShouldTerminateLooper;
376 };
377
378 } // namespace internal
379
380 class CarPowerPolicyServerTest : public ::testing::Test {
381 public:
getPowerPolicyChangeCallback()382 std::shared_ptr<ICarPowerPolicyChangeCallback> getPowerPolicyChangeCallback() {
383 std::shared_ptr<MockPowerPolicyChangeCallback> callback =
384 ndk::SharedRefBase::make<MockPowerPolicyChangeCallback>();
385 return ICarPowerPolicyChangeCallback::fromBinder(callback->asBinder());
386 }
387
388 // Sets calling UID to imitate System's process.
setSystemCallingUid()389 void setSystemCallingUid() {
390 mScopedChangeCallingUid = sp<ScopedChangeCallingUid>::make(AID_SYSTEM);
391 }
392
testApplyPowerPolicyPerPowerStateChangeAsyncInternal(const std::string & policyGroupId,const std::string & expectedPolicyId)393 void testApplyPowerPolicyPerPowerStateChangeAsyncInternal(const std::string& policyGroupId,
394 const std::string& expectedPolicyId) {
395 sp<internal::CarPowerPolicyServerPeer> server = new internal::CarPowerPolicyServerPeer();
396 std::shared_ptr<MockPowerPolicyDelegateCallback> callback =
397 ndk::SharedRefBase::make<MockPowerPolicyDelegateCallback>();
398 server->expectLinkToDeathStatus(callback->asBinder().get(), STATUS_OK);
399 server->init();
400 setSystemCallingUid();
401
402 int32_t requestId = 9999;
403 int32_t calledRequestId = -1;
404 std::string policyIdForUpdate;
405 std::string policyIdForNotification;
406 std::mutex mutex;
407 std::condition_variable cv;
408 EXPECT_CALL(*callback, updatePowerComponents)
409 .WillRepeatedly(
410 Invoke([&policyIdForUpdate](const CarPowerPolicy& policy) -> ScopedAStatus {
411 policyIdForUpdate = policy.policyId;
412 return ScopedAStatus::ok();
413 }));
414 EXPECT_CALL(*callback, onApplyPowerPolicySucceeded)
415 .WillRepeatedly(
416 Invoke([&calledRequestId, &policyIdForNotification, &cv,
417 &mutex](int32_t requestId, const CarPowerPolicy& accumulatedPolicy,
418 [[maybe_unused]] bool deferred) -> ScopedAStatus {
419 calledRequestId = requestId;
420 policyIdForNotification = accumulatedPolicy.policyId;
421 std::unique_lock lock(mutex);
422 cv.notify_all();
423 return ScopedAStatus::ok();
424 }));
425 PowerPolicyInitData initData;
426 server->notifyCarServiceReady(callback, &initData);
427 server->setPowerPolicyGroup(policyGroupId);
428
429 ScopedAStatus status =
430 server->applyPowerPolicyPerPowerStateChangeAsync(requestId,
431 ICarPowerPolicyDelegate::
432 PowerState::ON);
433
434 ASSERT_TRUE(status.isOk()) << "applyPowerPolicyPerPowerStateChangeAsync should return OK";
435
436 std::unique_lock lock(mutex);
437 bool waitResult =
438 cv.wait_for(lock, kCallbackWaitTime, [&policyIdForNotification, &expectedPolicyId] {
439 return policyIdForNotification.compare(expectedPolicyId) == 0;
440 });
441 EXPECT_TRUE(waitResult)
442 << "onApplyPowerPolicySucceeded() should be called with the same power policy ID";
443 EXPECT_EQ(policyIdForUpdate, expectedPolicyId)
444 << "updatePowerComponents should be called with " << expectedPolicyId;
445 }
446
447 private:
448 sp<ScopedChangeCallingUid> mScopedChangeCallingUid;
449 };
450
TEST_F(CarPowerPolicyServerTest,TestRegisterCallback)451 TEST_F(CarPowerPolicyServerTest, TestRegisterCallback) {
452 sp<internal::CarPowerPolicyServerPeer> server = new internal::CarPowerPolicyServerPeer();
453 std::shared_ptr<ICarPowerPolicyChangeCallback> callbackOne = getPowerPolicyChangeCallback();
454 server->expectLinkToDeathStatus(callbackOne->asBinder().get(), STATUS_OK);
455
456 CarPowerPolicyFilter filter;
457 ScopedAStatus status = server->registerPowerPolicyChangeCallback(callbackOne, filter);
458 ASSERT_TRUE(status.isOk()) << status.getMessage();
459 status = server->registerPowerPolicyChangeCallback(callbackOne, filter);
460 ASSERT_FALSE(status.isOk()) << "Duplicated registration is not allowed";
461 filter.components = {PowerComponent::BLUETOOTH, PowerComponent::AUDIO};
462 status = server->registerPowerPolicyChangeCallback(callbackOne, filter);
463 ASSERT_FALSE(status.isOk()) << "Duplicated registration is not allowed";
464
465 std::shared_ptr<ICarPowerPolicyChangeCallback> callbackTwo = getPowerPolicyChangeCallback();
466 server->expectLinkToDeathStatus(callbackTwo->asBinder().get(), STATUS_OK);
467
468 status = server->registerPowerPolicyChangeCallback(callbackTwo, filter);
469 ASSERT_TRUE(status.isOk()) << status.getMessage();
470 }
471
TEST_F(CarPowerPolicyServerTest,TestRegisterCallback_BinderDied)472 TEST_F(CarPowerPolicyServerTest, TestRegisterCallback_BinderDied) {
473 sp<internal::CarPowerPolicyServerPeer> server = new internal::CarPowerPolicyServerPeer();
474 std::shared_ptr<ICarPowerPolicyChangeCallback> callback = getPowerPolicyChangeCallback();
475 server->expectLinkToDeathStatus(callback->asBinder().get(), STATUS_DEAD_OBJECT);
476 CarPowerPolicyFilter filter;
477
478 ASSERT_FALSE(server->registerPowerPolicyChangeCallback(callback, filter).isOk())
479 << "When linkToDeath fails, registerPowerPolicyChangeCallback should return an error";
480 }
481
TEST_F(CarPowerPolicyServerTest,TestOnBinderDied)482 TEST_F(CarPowerPolicyServerTest, TestOnBinderDied) {
483 sp<internal::CarPowerPolicyServerPeer> server = new internal::CarPowerPolicyServerPeer();
484 std::shared_ptr<ICarPowerPolicyChangeCallback> callbackOne = getPowerPolicyChangeCallback();
485 server->expectLinkToDeathStatus(callbackOne->asBinder().get(), STATUS_OK);
486
487 CarPowerPolicyFilter filter;
488 ScopedAStatus status = server->registerPowerPolicyChangeCallback(callbackOne, filter);
489 ASSERT_TRUE(status.isOk()) << status.getMessage();
490 ASSERT_EQ(server->getPolicyChangeCallbacks().size(), static_cast<size_t>(1));
491 ASSERT_EQ(server->countOnClientBinderDiedContexts(), static_cast<size_t>(1));
492 ASSERT_EQ(server->getCookies().size(), static_cast<size_t>(1));
493
494 void* cookie = *(server->getCookies().begin());
495 server->onClientBinderDied(cookie);
496
497 ASSERT_TRUE(server->getPolicyChangeCallbacks().empty());
498
499 server->onClientDeathRecipientUnlinked(cookie);
500
501 ASSERT_EQ(server->countOnClientBinderDiedContexts(), static_cast<size_t>(0));
502 }
503
TEST_F(CarPowerPolicyServerTest,TestUnregisterCallback)504 TEST_F(CarPowerPolicyServerTest, TestUnregisterCallback) {
505 sp<internal::CarPowerPolicyServerPeer> server = new internal::CarPowerPolicyServerPeer();
506 std::shared_ptr<ICarPowerPolicyChangeCallback> callback = getPowerPolicyChangeCallback();
507 server->expectLinkToDeathStatus(callback->asBinder().get(), STATUS_OK);
508 CarPowerPolicyFilter filter;
509
510 server->registerPowerPolicyChangeCallback(callback, filter);
511 ScopedAStatus status = server->unregisterPowerPolicyChangeCallback(callback);
512 ASSERT_TRUE(status.isOk()) << status.getMessage();
513 ASSERT_FALSE(server->unregisterPowerPolicyChangeCallback(callback).isOk())
514 << "Unregistering an unregistered powerpolicy change callback should return an error";
515 }
516
TEST_F(CarPowerPolicyServerTest,TestGetCurrentPowerPolicy)517 TEST_F(CarPowerPolicyServerTest, TestGetCurrentPowerPolicy) {
518 sp<internal::CarPowerPolicyServerPeer> server = new internal::CarPowerPolicyServerPeer();
519 CarPowerPolicy currentPolicy;
520
521 ScopedAStatus status = server->getCurrentPowerPolicy(¤tPolicy);
522 ASSERT_FALSE(status.isOk()) << "The current policy at creation should be null";
523 // TODO(b/168545262): Add more test cases after VHAL integration is complete.
524 }
525
TEST_F(CarPowerPolicyServerTest,TestApplyPowerPolicyFromNativeClients)526 TEST_F(CarPowerPolicyServerTest, TestApplyPowerPolicyFromNativeClients) {
527 if (!car_power_policy_refactoring()) {
528 GTEST_SKIP() << "car_power_policy_refactoring feature flag is not enabled";
529 }
530
531 sp<internal::CarPowerPolicyServerPeer> server = new internal::CarPowerPolicyServerPeer();
532 std::shared_ptr<MockPowerPolicyDelegateCallback> callback =
533 ndk::SharedRefBase::make<MockPowerPolicyDelegateCallback>();
534 server->expectLinkToDeathStatus(callback->asBinder().get(), STATUS_OK);
535 server->init();
536 PowerPolicyInitData initData;
537 server->notifyCarServiceReady(callback, &initData);
538 const std::string powerPolicyId = "policy_id_other_off";
539
540 ScopedAStatus status = server->applyPowerPolicy(powerPolicyId);
541 ASSERT_TRUE(status.isOk()) << "applyPowerPolicy should return OK";
542 CarPowerPolicy policy;
543 status = server->getCurrentPowerPolicy(&policy);
544 ASSERT_TRUE(status.isOk()) << "getCurrentPowerPolicy should return OK";
545 ASSERT_EQ(policy.policyId, powerPolicyId.c_str())
546 << "The current power policy should be the applied one";
547 }
548
TEST_F(CarPowerPolicyServerTest,TestApplyPowerPolicyFromNativeClients_carServiceNotRegistered)549 TEST_F(CarPowerPolicyServerTest, TestApplyPowerPolicyFromNativeClients_carServiceNotRegistered) {
550 if (!car_power_policy_refactoring()) {
551 GTEST_SKIP() << "car_power_policy_refactoring feature flag is not enabled";
552 }
553
554 sp<internal::CarPowerPolicyServerPeer> server = new internal::CarPowerPolicyServerPeer();
555 server->init();
556 const std::string powerPolicyId = "policy_id_other_off";
557
558 ScopedAStatus status = server->applyPowerPolicy(powerPolicyId);
559 ASSERT_TRUE(status.isOk()) << "applyPowerPolicy should return OK";
560 CarPowerPolicy policy;
561 status = server->getCurrentPowerPolicy(&policy);
562 ASSERT_TRUE(status.isOk()) << "getCurrentPowerPolicy should return OK";
563 ASSERT_EQ(policy.policyId, powerPolicyId.c_str())
564 << "The current power policy should be the applied one";
565 }
566
TEST_F(CarPowerPolicyServerTest,TestApplyPowerPolicyFromNativeClients_invalidPolicyId)567 TEST_F(CarPowerPolicyServerTest, TestApplyPowerPolicyFromNativeClients_invalidPolicyId) {
568 if (!car_power_policy_refactoring()) {
569 GTEST_SKIP() << "car_power_policy_refactoring feature flag is not enabled";
570 }
571
572 sp<internal::CarPowerPolicyServerPeer> server = new internal::CarPowerPolicyServerPeer();
573 server->init();
574
575 ScopedAStatus status = server->applyPowerPolicy("policy_not_exist");
576 ASSERT_FALSE(status.isOk()) << "applyPowerPolicy should return an error";
577 }
578
TEST_F(CarPowerPolicyServerTest,TestApplyPowerPolicyFromCarService)579 TEST_F(CarPowerPolicyServerTest, TestApplyPowerPolicyFromCarService) {
580 if (!car_power_policy_refactoring()) {
581 GTEST_SKIP() << "car_power_policy_refactoring feature flag is not enabled";
582 }
583
584 sp<internal::CarPowerPolicyServerPeer> server = new internal::CarPowerPolicyServerPeer();
585 std::shared_ptr<MockPowerPolicyDelegateCallback> callback =
586 ndk::SharedRefBase::make<MockPowerPolicyDelegateCallback>();
587 server->expectLinkToDeathStatus(callback->asBinder().get(), STATUS_OK);
588 server->init();
589 setSystemCallingUid();
590 PowerPolicyInitData initData;
591 server->notifyCarServiceReady(callback, &initData);
592 std::string policyId;
593 std::mutex mutex;
594 std::condition_variable cv;
595 EXPECT_CALL(*callback, updatePowerComponents)
596 .WillRepeatedly(
597 Invoke([&policyId, &cv, &mutex](const CarPowerPolicy& policy) -> ScopedAStatus {
598 std::unique_lock lock(mutex);
599 policyId = policy.policyId;
600 cv.notify_all();
601 return ScopedAStatus::ok();
602 }));
603 EXPECT_CALL(*callback, onApplyPowerPolicySucceeded)
604 .WillRepeatedly(Invoke([]([[maybe_unused]] int32_t requestId,
605 [[maybe_unused]] const CarPowerPolicy& accumulatedPolicy,
606 [[maybe_unused]] bool deferred) -> ScopedAStatus {
607 return ScopedAStatus::ok();
608 }));
609
610 ScopedAStatus status = server->applyPowerPolicyAsync(/*requestId=*/9999, "policy_id_other_off",
611 /*force=*/false);
612 ASSERT_TRUE(status.isOk()) << "applyPowerPolicyAsync should return OK";
613 std::unique_lock lock(mutex);
614 bool waitResult = cv.wait_for(lock, kCallbackWaitTime, [&policyId] {
615 return policyId.compare("policy_id_other_off") == 0;
616 });
617 ASSERT_TRUE(waitResult)
618 << "updatePowerComponents() should be called with the same power policy ID";
619 }
620
TEST_F(CarPowerPolicyServerTest,TestApplyPowerPolicyFromCarService_nonSystemUid)621 TEST_F(CarPowerPolicyServerTest, TestApplyPowerPolicyFromCarService_nonSystemUid) {
622 if (!car_power_policy_refactoring()) {
623 GTEST_SKIP() << "car_power_policy_refactoring feature flag is not enabled";
624 }
625
626 sp<internal::CarPowerPolicyServerPeer> server = new internal::CarPowerPolicyServerPeer();
627 std::shared_ptr<MockPowerPolicyDelegateCallback> callback =
628 ndk::SharedRefBase::make<MockPowerPolicyDelegateCallback>();
629 server->expectLinkToDeathStatus(callback->asBinder().get(), STATUS_OK);
630 server->init();
631 PowerPolicyInitData initData;
632 server->notifyCarServiceReady(callback, &initData);
633
634 ScopedAStatus status = server->applyPowerPolicyAsync(/*requestId=*/9999, "policy_id_other_off",
635 /*force=*/false);
636 ASSERT_FALSE(status.isOk())
637 << "applyPowerPolicyAsync should fail when the caller doesn't have system UID";
638 }
639
TEST_F(CarPowerPolicyServerTest,TestApplyPowerPolicyFromCarService_invalidPolicyId)640 TEST_F(CarPowerPolicyServerTest, TestApplyPowerPolicyFromCarService_invalidPolicyId) {
641 if (!car_power_policy_refactoring()) {
642 GTEST_SKIP() << "car_power_policy_refactoring feature flag is not enabled";
643 }
644
645 sp<internal::CarPowerPolicyServerPeer> server = new internal::CarPowerPolicyServerPeer();
646 std::shared_ptr<MockPowerPolicyDelegateCallback> callback =
647 ndk::SharedRefBase::make<MockPowerPolicyDelegateCallback>();
648 server->expectLinkToDeathStatus(callback->asBinder().get(), STATUS_OK);
649 server->init();
650 setSystemCallingUid();
651 PowerPolicyInitData initData;
652 server->notifyCarServiceReady(callback, &initData);
653 std::mutex mutex;
654 std::condition_variable cv;
655 int32_t requestIdLocal;
656 bool methodCalled = false;
657 PowerPolicyFailureReason failureReason;
658 EXPECT_CALL(*callback, onApplyPowerPolicyFailed)
659 .WillRepeatedly(Invoke(
660 [&requestIdLocal, &failureReason, &methodCalled, &cv,
661 &mutex](int32_t requestId, PowerPolicyFailureReason reason) -> ScopedAStatus {
662 std::unique_lock lock(mutex);
663 requestIdLocal = requestId;
664 failureReason = reason;
665 methodCalled = true;
666 cv.notify_all();
667 return ScopedAStatus::ok();
668 }));
669
670 ScopedAStatus status = server->applyPowerPolicyAsync(/*requestId=*/9999, "policy_not_exist",
671 /*force=*/false);
672 ASSERT_TRUE(status.isOk());
673 std::unique_lock lock(mutex);
674 bool waitResult =
675 cv.wait_for(lock, kCallbackWaitTime, [&methodCalled] { return methodCalled; });
676 ASSERT_TRUE(waitResult) << "onApplyPowerPolicyFailed should be called";
677 EXPECT_EQ(requestIdLocal, 9999);
678 ASSERT_EQ(failureReason, PowerPolicyFailureReason::POWER_POLICY_FAILURE_NOT_REGISTERED_ID);
679 }
680
TEST_F(CarPowerPolicyServerTest,TestApplyPowerPolicyFromCarService_duplicatedRequestId)681 TEST_F(CarPowerPolicyServerTest, TestApplyPowerPolicyFromCarService_duplicatedRequestId) {
682 if (!car_power_policy_refactoring()) {
683 GTEST_SKIP() << "car_power_policy_refactoring feature flag is not enabled";
684 }
685
686 sp<internal::CarPowerPolicyServerPeer> server = new internal::CarPowerPolicyServerPeer();
687 std::shared_ptr<MockPowerPolicyDelegateCallback> callback =
688 ndk::SharedRefBase::make<MockPowerPolicyDelegateCallback>();
689 server->expectLinkToDeathStatus(callback->asBinder().get(), STATUS_OK);
690 server->init();
691 setSystemCallingUid();
692 EXPECT_CALL(*callback, updatePowerComponents)
693 .WillRepeatedly(
694 Invoke([]([[maybe_unused]] const CarPowerPolicy& policy) -> ScopedAStatus {
695 // To make sure that both requests of applying power policy occur together.
696 std::this_thread::sleep_for(kGeneralWaitTime);
697 return ScopedAStatus::ok();
698 }));
699 EXPECT_CALL(*callback, onApplyPowerPolicySucceeded)
700 .WillRepeatedly(Invoke([]([[maybe_unused]] int32_t requestId,
701 [[maybe_unused]] const CarPowerPolicy& accumulatedPolicy,
702 [[maybe_unused]] bool deferred) -> ScopedAStatus {
703 return ScopedAStatus::ok();
704 }));
705 PowerPolicyInitData initData;
706 server->notifyCarServiceReady(callback, &initData);
707
708 ScopedAStatus status = server->applyPowerPolicyAsync(/*requestId=*/9999, "policy_id_other_off",
709 /*force=*/false);
710 ASSERT_TRUE(status.isOk()) << "applyPowerPolicyAsync should return OK";
711
712 status = server->applyPowerPolicyAsync(/*requestId=*/9999, "policy_id_other_untouched",
713 /*force=*/false);
714 ASSERT_FALSE(status.isOk())
715 << "applyPowerPolicyAsync should return an error when request ID is duplicated";
716 }
717
TEST_F(CarPowerPolicyServerTest,TestApplyPowerPolicyPerPowerStateChangeAsync)718 TEST_F(CarPowerPolicyServerTest, TestApplyPowerPolicyPerPowerStateChangeAsync) {
719 if (!car_power_policy_refactoring()) {
720 GTEST_SKIP() << "car_power_policy_refactoring feature flag is not enabled";
721 }
722
723 testApplyPowerPolicyPerPowerStateChangeAsyncInternal("", "system_power_policy_all_on");
724 }
725
TEST_F(CarPowerPolicyServerTest,TestApplyPowerPolicyPerPowerStateChangeAsync_nonSystemUid)726 TEST_F(CarPowerPolicyServerTest, TestApplyPowerPolicyPerPowerStateChangeAsync_nonSystemUid) {
727 if (!car_power_policy_refactoring()) {
728 GTEST_SKIP() << "car_power_policy_refactoring feature flag is not enabled";
729 }
730
731 sp<internal::CarPowerPolicyServerPeer> server = new internal::CarPowerPolicyServerPeer();
732 std::shared_ptr<MockPowerPolicyDelegateCallback> callback =
733 ndk::SharedRefBase::make<MockPowerPolicyDelegateCallback>();
734 server->expectLinkToDeathStatus(callback->asBinder().get(), STATUS_OK);
735 server->init();
736 PowerPolicyInitData initData;
737 server->notifyCarServiceReady(callback, &initData);
738
739 ScopedAStatus status =
740 server->applyPowerPolicyPerPowerStateChangeAsync(/*requestId=*/9999,
741 ICarPowerPolicyDelegate::PowerState::
742 ON);
743
744 ASSERT_FALSE(status.isOk()) << "applyPowerPolicyPerPowerStateChangeAsync should fail when the "
745 "caller doesn't have system UID";
746 }
747
TEST_F(CarPowerPolicyServerTest,TestApplyPowerPolicyPerPowerStateChangeAsync_notSupportedPowerState)748 TEST_F(CarPowerPolicyServerTest,
749 TestApplyPowerPolicyPerPowerStateChangeAsync_notSupportedPowerState) {
750 if (!car_power_policy_refactoring()) {
751 GTEST_SKIP() << "car_power_policy_refactoring feature flag is not enabled";
752 }
753
754 sp<internal::CarPowerPolicyServerPeer> server = new internal::CarPowerPolicyServerPeer();
755 std::shared_ptr<MockPowerPolicyDelegateCallback> callback =
756 ndk::SharedRefBase::make<MockPowerPolicyDelegateCallback>();
757 server->expectLinkToDeathStatus(callback->asBinder().get(), STATUS_OK);
758 server->init();
759 setSystemCallingUid();
760 EXPECT_CALL(*callback, updatePowerComponents).Times(0);
761 EXPECT_CALL(*callback, onPowerPolicyChanged).Times(0);
762 PowerPolicyInitData initData;
763 server->notifyCarServiceReady(callback, &initData);
764
765 // We don't have default power policy for SHUTDOWN_PREPARE.
766 ScopedAStatus status =
767 server->applyPowerPolicyPerPowerStateChangeAsync(/*requestId=*/9999,
768 ICarPowerPolicyDelegate::PowerState::
769 SHUTDOWN_PREPARE);
770
771 EXPECT_FALSE(status.isOk())
772 << "applyPowerPolicyPerPowerStateChangeAsync should return an error";
773 EXPECT_EQ(status.getServiceSpecificError(), EX_ILLEGAL_ARGUMENT) << "Error code should be set";
774
775 // Wait for some time to verify that no callback is made to CPMS.
776 std::this_thread::sleep_for(kGeneralWaitTime);
777 }
778
TEST_F(CarPowerPolicyServerTest,TestApplyPowerPolicyPerPowerStateChangeAsync_withNewGroup)779 TEST_F(CarPowerPolicyServerTest, TestApplyPowerPolicyPerPowerStateChangeAsync_withNewGroup) {
780 if (!car_power_policy_refactoring()) {
781 GTEST_SKIP() << "car_power_policy_refactoring feature flag is not enabled";
782 }
783
784 testApplyPowerPolicyPerPowerStateChangeAsyncInternal("basic_policy_group",
785 "policy_id_other_untouched");
786 }
787
788 } // namespace powerpolicy
789 } // namespace automotive
790 } // namespace frameworks
791 } // namespace android
792