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(&currentPolicy);
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