• 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 #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 
getPolicyChangeCallbacks()206     std::vector<CallbackInfo> getPolicyChangeCallbacks() {
207         return mServer->getPolicyChangeCallbacks();
208     }
209 
countOnClientBinderDiedContexts()210     size_t countOnClientBinderDiedContexts() { return mServer->countOnClientBinderDiedContexts(); }
211 
getCookies()212     std::unordered_set<void*> getCookies() { return mLinkUnlinkImpl->getCookies(); }
213 
expectLinkToDeathStatus(AIBinder * binder,status_t linkToDeathResult)214     void expectLinkToDeathStatus(AIBinder* binder, status_t linkToDeathResult) {
215         mLinkUnlinkImpl->expectLinkToDeathStatus(binder, linkToDeathResult);
216     }
217 
218 private:
initializeLooper()219     void initializeLooper() {
220         sp<Looper> looper = Looper::prepare(/*opts=*/0);
221         mServer->mHandlerLooper = looper;
222         std::mutex mutex;
223         std::condition_variable cv;
224         bool looperReady = false;
225         mHandlerLooperThread = std::thread([looper, &cv, &mutex, &looperReady, this]() {
226             Looper::setForThread(looper);
227             if (int result = pthread_setname_np(pthread_self(), kTestLooperThreadName);
228                 result != 0) {
229                 ALOGE("Failed to set test looper thread name: %s", strerror(result));
230             }
231             mShouldTerminateLooper.store(false);
232             {
233                 std::unique_lock lock(mutex);
234                 looperReady = true;
235                 cv.notify_all();
236             }
237             while (!mShouldTerminateLooper.load()) {
238                 looper->pollOnce(/*timeoutMillis=*/-1);
239             }
240         });
241         std::unique_lock lock(mutex);
242         // Wait until thread looper is ready.
243         cv.wait(lock, [&looperReady] { return looperReady; });
244     }
245 
finalizeLooper()246     void finalizeLooper() {
247         mShouldTerminateLooper.store(true);
248         mServer->mHandlerLooper->wake();
249         if (mHandlerLooperThread.joinable()) {
250             mHandlerLooperThread.join();
251         }
252     }
253 
initializePolicyManager()254     void initializePolicyManager() {
255         PolicyManager& policyManager = mServer->mPolicyManager;
256         policyManager.initRegularPowerPolicy(/*override=*/true);
257         policyManager.initPreemptivePowerPolicy();
258 
259         XMLDocument xmlDoc;
260         std::string path = getTestDataPath(kValidPowerPolicyXmlFile);
261         xmlDoc.LoadFile(path.c_str());
262         ASSERT_TRUE(xmlDoc.ErrorID() == XML_SUCCESS);
263         policyManager.readPowerPolicyFromXml(xmlDoc);
264     }
265 
initializePowerComponentHandler()266     void initializePowerComponentHandler() {
267         PowerComponentHandler& componentHandler = mServer->mComponentHandler;
268         componentHandler.init();
269     }
270 
applyInitialPolicy()271     void applyInitialPolicy() {
272         auto policyMeta = mServer->mPolicyManager.getPowerPolicy(kSystemPolicyIdInitialOn);
273         ASSERT_TRUE(policyMeta.ok());
274         mServer->mCurrentPowerPolicyMeta = *policyMeta;
275     }
276 
277 private:
278     class MockLinkUnlinkImpl : public CarPowerPolicyServer::LinkUnlinkImpl {
279     public:
280         MOCK_METHOD(binder_status_t, linkToDeath, (AIBinder*, AIBinder_DeathRecipient*, void*),
281                     (override));
282         MOCK_METHOD(binder_status_t, unlinkToDeath, (AIBinder*, AIBinder_DeathRecipient*, void*),
283                     (override));
284 
expectLinkToDeathStatus(AIBinder * binder,binder_status_t linkToDeathResult)285         void expectLinkToDeathStatus(AIBinder* binder, binder_status_t linkToDeathResult) {
286             EXPECT_CALL(*this, linkToDeath(binder, _, _))
287                     .WillRepeatedly(
288                             Invoke([this, linkToDeathResult](AIBinder*, AIBinder_DeathRecipient*,
289                                                              void* cookie) {
290                                 Mutex::Autolock lock(mMutex);
291                                 mCookies.insert(cookie);
292                                 return linkToDeathResult;
293                             }));
294             EXPECT_CALL(*this, unlinkToDeath(binder, _, _))
295                     .WillRepeatedly(
296                             Invoke([this](AIBinder*, AIBinder_DeathRecipient*, void* cookie) {
297                                 Mutex::Autolock lock(mMutex);
298                                 mCookies.erase(cookie);
299                                 return STATUS_OK;
300                             }));
301         }
302 
getCookies()303         std::unordered_set<void*> getCookies() {
304             Mutex::Autolock lock(mMutex);
305             return mCookies;
306         }
307 
308     private:
309         android::Mutex mMutex;
310         std::unordered_set<void*> mCookies GUARDED_BY(mMutex);
311     };
312 
313     MockLinkUnlinkImpl* mLinkUnlinkImpl;
314     std::shared_ptr<CarPowerPolicyServer> mServer;
315     std::shared_ptr<ICarPowerPolicyServer> mServerProxy;
316     std::thread mHandlerLooperThread;
317     SpAIBinder mBinder;
318     std::atomic<bool> mShouldTerminateLooper;
319 };
320 
321 }  // namespace internal
322 
323 class CarPowerPolicyServerTest : public ::testing::Test {
324 public:
getPowerPolicyChangeCallback()325     std::shared_ptr<ICarPowerPolicyChangeCallback> getPowerPolicyChangeCallback() {
326         std::shared_ptr<MockPowerPolicyChangeCallback> callback =
327                 ndk::SharedRefBase::make<MockPowerPolicyChangeCallback>();
328         return ICarPowerPolicyChangeCallback::fromBinder(callback->asBinder());
329     }
330 
331     // Sets calling UID to imitate System's process.
setSystemCallingUid()332     void setSystemCallingUid() {
333         mScopedChangeCallingUid = sp<ScopedChangeCallingUid>::make(AID_SYSTEM);
334     }
335 
testApplyPowerPolicyPerPowerStateChangeAsyncInternal(const std::string & policyGroupId,const std::string & expectedPolicyId)336     void testApplyPowerPolicyPerPowerStateChangeAsyncInternal(const std::string& policyGroupId,
337                                                               const std::string& expectedPolicyId) {
338         sp<internal::CarPowerPolicyServerPeer> server = new internal::CarPowerPolicyServerPeer();
339         std::shared_ptr<MockPowerPolicyDelegateCallback> callback =
340                 ndk::SharedRefBase::make<MockPowerPolicyDelegateCallback>();
341         server->expectLinkToDeathStatus(callback->asBinder().get(), STATUS_OK);
342         server->init();
343         setSystemCallingUid();
344 
345         int32_t requestId = 9999;
346         int32_t calledRequestId = -1;
347         std::string policyIdForUpdate;
348         std::string policyIdForNotification;
349         std::mutex mutex;
350         std::condition_variable cv;
351         EXPECT_CALL(*callback, updatePowerComponents)
352                 .WillRepeatedly(
353                         Invoke([&policyIdForUpdate](const CarPowerPolicy& policy) -> ScopedAStatus {
354                             policyIdForUpdate = policy.policyId;
355                             return ScopedAStatus::ok();
356                         }));
357         EXPECT_CALL(*callback, onApplyPowerPolicySucceeded)
358                 .WillRepeatedly(
359                         Invoke([&calledRequestId, &policyIdForNotification, &cv,
360                                 &mutex](int32_t requestId, const CarPowerPolicy& accumulatedPolicy,
361                                         [[maybe_unused]] bool deferred) -> ScopedAStatus {
362                             calledRequestId = requestId;
363                             policyIdForNotification = accumulatedPolicy.policyId;
364                             std::unique_lock lock(mutex);
365                             cv.notify_all();
366                             return ScopedAStatus::ok();
367                         }));
368         PowerPolicyInitData initData;
369         server->notifyCarServiceReady(callback, &initData);
370         server->setPowerPolicyGroup(policyGroupId);
371 
372         ScopedAStatus status =
373                 server->applyPowerPolicyPerPowerStateChangeAsync(requestId,
374                                                                  ICarPowerPolicyDelegate::
375                                                                          PowerState::ON);
376 
377         ASSERT_TRUE(status.isOk()) << "applyPowerPolicyPerPowerStateChangeAsync should return OK";
378 
379         std::unique_lock lock(mutex);
380         bool waitResult =
381                 cv.wait_for(lock, kCallbackWaitTime, [&policyIdForNotification, &expectedPolicyId] {
382                     return policyIdForNotification.compare(expectedPolicyId) == 0;
383                 });
384         EXPECT_TRUE(waitResult)
385                 << "onApplyPowerPolicySucceeded() should be called with the same power policy ID";
386         EXPECT_EQ(policyIdForUpdate, expectedPolicyId)
387                 << "updatePowerComponents should be called with " << expectedPolicyId;
388     }
389 
390 private:
391     sp<ScopedChangeCallingUid> mScopedChangeCallingUid;
392 };
393 
TEST_F(CarPowerPolicyServerTest,TestRegisterCallback)394 TEST_F(CarPowerPolicyServerTest, TestRegisterCallback) {
395     sp<internal::CarPowerPolicyServerPeer> server = new internal::CarPowerPolicyServerPeer();
396     std::shared_ptr<ICarPowerPolicyChangeCallback> callbackOne = getPowerPolicyChangeCallback();
397     server->expectLinkToDeathStatus(callbackOne->asBinder().get(), STATUS_OK);
398 
399     CarPowerPolicyFilter filter;
400     ScopedAStatus status = server->registerPowerPolicyChangeCallback(callbackOne, filter);
401     ASSERT_TRUE(status.isOk()) << status.getMessage();
402     status = server->registerPowerPolicyChangeCallback(callbackOne, filter);
403     ASSERT_FALSE(status.isOk()) << "Duplicated registration is not allowed";
404     filter.components = {PowerComponent::BLUETOOTH, PowerComponent::AUDIO};
405     status = server->registerPowerPolicyChangeCallback(callbackOne, filter);
406     ASSERT_FALSE(status.isOk()) << "Duplicated registration is not allowed";
407 
408     std::shared_ptr<ICarPowerPolicyChangeCallback> callbackTwo = getPowerPolicyChangeCallback();
409     server->expectLinkToDeathStatus(callbackTwo->asBinder().get(), STATUS_OK);
410 
411     status = server->registerPowerPolicyChangeCallback(callbackTwo, filter);
412     ASSERT_TRUE(status.isOk()) << status.getMessage();
413 }
414 
TEST_F(CarPowerPolicyServerTest,TestRegisterCallback_BinderDied)415 TEST_F(CarPowerPolicyServerTest, TestRegisterCallback_BinderDied) {
416     sp<internal::CarPowerPolicyServerPeer> server = new internal::CarPowerPolicyServerPeer();
417     std::shared_ptr<ICarPowerPolicyChangeCallback> callback = getPowerPolicyChangeCallback();
418     server->expectLinkToDeathStatus(callback->asBinder().get(), STATUS_DEAD_OBJECT);
419     CarPowerPolicyFilter filter;
420 
421     ASSERT_FALSE(server->registerPowerPolicyChangeCallback(callback, filter).isOk())
422             << "When linkToDeath fails, registerPowerPolicyChangeCallback should return an error";
423 }
424 
TEST_F(CarPowerPolicyServerTest,TestOnBinderDied)425 TEST_F(CarPowerPolicyServerTest, TestOnBinderDied) {
426     sp<internal::CarPowerPolicyServerPeer> server = new internal::CarPowerPolicyServerPeer();
427     std::shared_ptr<ICarPowerPolicyChangeCallback> callbackOne = getPowerPolicyChangeCallback();
428     server->expectLinkToDeathStatus(callbackOne->asBinder().get(), STATUS_OK);
429 
430     CarPowerPolicyFilter filter;
431     ScopedAStatus status = server->registerPowerPolicyChangeCallback(callbackOne, filter);
432     ASSERT_TRUE(status.isOk()) << status.getMessage();
433     ASSERT_EQ(server->getPolicyChangeCallbacks().size(), static_cast<size_t>(1));
434     ASSERT_EQ(server->countOnClientBinderDiedContexts(), static_cast<size_t>(1));
435     ASSERT_EQ(server->getCookies().size(), static_cast<size_t>(1));
436 
437     void* cookie = *(server->getCookies().begin());
438     server->onClientBinderDied(cookie);
439 
440     ASSERT_TRUE(server->getPolicyChangeCallbacks().empty());
441 
442     ASSERT_EQ(server->countOnClientBinderDiedContexts(), static_cast<size_t>(0));
443 }
444 
TEST_F(CarPowerPolicyServerTest,TestUnregisterCallback)445 TEST_F(CarPowerPolicyServerTest, TestUnregisterCallback) {
446     sp<internal::CarPowerPolicyServerPeer> server = new internal::CarPowerPolicyServerPeer();
447     std::shared_ptr<ICarPowerPolicyChangeCallback> callback = getPowerPolicyChangeCallback();
448     server->expectLinkToDeathStatus(callback->asBinder().get(), STATUS_OK);
449     CarPowerPolicyFilter filter;
450 
451     server->registerPowerPolicyChangeCallback(callback, filter);
452     ScopedAStatus status = server->unregisterPowerPolicyChangeCallback(callback);
453     ASSERT_TRUE(status.isOk()) << status.getMessage();
454     ASSERT_FALSE(server->unregisterPowerPolicyChangeCallback(callback).isOk())
455             << "Unregistering an unregistered powerpolicy change callback should return an error";
456 }
457 
TEST_F(CarPowerPolicyServerTest,TestGetCurrentPowerPolicy)458 TEST_F(CarPowerPolicyServerTest, TestGetCurrentPowerPolicy) {
459     sp<internal::CarPowerPolicyServerPeer> server = new internal::CarPowerPolicyServerPeer();
460     CarPowerPolicy currentPolicy;
461 
462     ScopedAStatus status = server->getCurrentPowerPolicy(&currentPolicy);
463     ASSERT_FALSE(status.isOk()) << "The current policy at creation should be null";
464     // TODO(b/168545262): Add more test cases after VHAL integration is complete.
465 }
466 
TEST_F(CarPowerPolicyServerTest,TestApplyPowerPolicyFromNativeClients)467 TEST_F(CarPowerPolicyServerTest, TestApplyPowerPolicyFromNativeClients) {
468     if (!car_power_policy_refactoring()) {
469         GTEST_SKIP() << "car_power_policy_refactoring feature flag is not enabled";
470     }
471 
472     sp<internal::CarPowerPolicyServerPeer> server = new internal::CarPowerPolicyServerPeer();
473     std::shared_ptr<MockPowerPolicyDelegateCallback> callback =
474             ndk::SharedRefBase::make<MockPowerPolicyDelegateCallback>();
475     server->expectLinkToDeathStatus(callback->asBinder().get(), STATUS_OK);
476     server->init();
477     PowerPolicyInitData initData;
478     server->notifyCarServiceReady(callback, &initData);
479     const std::string powerPolicyId = "policy_id_other_off";
480 
481     ScopedAStatus status = server->applyPowerPolicy(powerPolicyId);
482     ASSERT_TRUE(status.isOk()) << "applyPowerPolicy should return OK";
483     CarPowerPolicy policy;
484     status = server->getCurrentPowerPolicy(&policy);
485     ASSERT_TRUE(status.isOk()) << "getCurrentPowerPolicy should return OK";
486     ASSERT_EQ(policy.policyId, powerPolicyId.c_str())
487             << "The current power policy should be the applied one";
488 }
489 
TEST_F(CarPowerPolicyServerTest,TestApplyPowerPolicyFromNativeClients_carServiceNotRegistered)490 TEST_F(CarPowerPolicyServerTest, TestApplyPowerPolicyFromNativeClients_carServiceNotRegistered) {
491     if (!car_power_policy_refactoring()) {
492         GTEST_SKIP() << "car_power_policy_refactoring feature flag is not enabled";
493     }
494 
495     sp<internal::CarPowerPolicyServerPeer> server = new internal::CarPowerPolicyServerPeer();
496     server->init();
497     const std::string powerPolicyId = "policy_id_other_off";
498 
499     ScopedAStatus status = server->applyPowerPolicy(powerPolicyId);
500     ASSERT_TRUE(status.isOk()) << "applyPowerPolicy should return OK";
501     CarPowerPolicy policy;
502     status = server->getCurrentPowerPolicy(&policy);
503     ASSERT_TRUE(status.isOk()) << "getCurrentPowerPolicy should return OK";
504     ASSERT_EQ(policy.policyId, powerPolicyId.c_str())
505             << "The current power policy should be the applied one";
506 }
507 
TEST_F(CarPowerPolicyServerTest,TestApplyPowerPolicyFromNativeClients_invalidPolicyId)508 TEST_F(CarPowerPolicyServerTest, TestApplyPowerPolicyFromNativeClients_invalidPolicyId) {
509     if (!car_power_policy_refactoring()) {
510         GTEST_SKIP() << "car_power_policy_refactoring feature flag is not enabled";
511     }
512 
513     sp<internal::CarPowerPolicyServerPeer> server = new internal::CarPowerPolicyServerPeer();
514     server->init();
515 
516     ScopedAStatus status = server->applyPowerPolicy("policy_not_exist");
517     ASSERT_FALSE(status.isOk()) << "applyPowerPolicy should return an error";
518 }
519 
TEST_F(CarPowerPolicyServerTest,TestApplyPowerPolicyFromCarService)520 TEST_F(CarPowerPolicyServerTest, TestApplyPowerPolicyFromCarService) {
521     if (!car_power_policy_refactoring()) {
522         GTEST_SKIP() << "car_power_policy_refactoring feature flag is not enabled";
523     }
524 
525     sp<internal::CarPowerPolicyServerPeer> server = new internal::CarPowerPolicyServerPeer();
526     std::shared_ptr<MockPowerPolicyDelegateCallback> callback =
527             ndk::SharedRefBase::make<MockPowerPolicyDelegateCallback>();
528     server->expectLinkToDeathStatus(callback->asBinder().get(), STATUS_OK);
529     server->init();
530     setSystemCallingUid();
531     PowerPolicyInitData initData;
532     server->notifyCarServiceReady(callback, &initData);
533     std::string policyId;
534     std::mutex mutex;
535     std::condition_variable cv;
536     EXPECT_CALL(*callback, updatePowerComponents)
537             .WillRepeatedly(
538                     Invoke([&policyId, &cv, &mutex](const CarPowerPolicy& policy) -> ScopedAStatus {
539                         std::unique_lock lock(mutex);
540                         policyId = policy.policyId;
541                         cv.notify_all();
542                         return ScopedAStatus::ok();
543                     }));
544     EXPECT_CALL(*callback, onApplyPowerPolicySucceeded)
545             .WillRepeatedly(Invoke([]([[maybe_unused]] int32_t requestId,
546                                       [[maybe_unused]] const CarPowerPolicy& accumulatedPolicy,
547                                       [[maybe_unused]] bool deferred) -> ScopedAStatus {
548                 return ScopedAStatus::ok();
549             }));
550 
551     ScopedAStatus status = server->applyPowerPolicyAsync(/*requestId=*/9999, "policy_id_other_off",
552                                                          /*force=*/false);
553     ASSERT_TRUE(status.isOk()) << "applyPowerPolicyAsync should return OK";
554     std::unique_lock lock(mutex);
555     bool waitResult = cv.wait_for(lock, kCallbackWaitTime, [&policyId] {
556         return policyId.compare("policy_id_other_off") == 0;
557     });
558     ASSERT_TRUE(waitResult)
559             << "updatePowerComponents() should be called with the same power policy ID";
560 }
561 
TEST_F(CarPowerPolicyServerTest,TestApplyPowerPolicyFromCarService_nonSystemUid)562 TEST_F(CarPowerPolicyServerTest, TestApplyPowerPolicyFromCarService_nonSystemUid) {
563     if (!car_power_policy_refactoring()) {
564         GTEST_SKIP() << "car_power_policy_refactoring feature flag is not enabled";
565     }
566 
567     sp<internal::CarPowerPolicyServerPeer> server = new internal::CarPowerPolicyServerPeer();
568     std::shared_ptr<MockPowerPolicyDelegateCallback> callback =
569             ndk::SharedRefBase::make<MockPowerPolicyDelegateCallback>();
570     server->expectLinkToDeathStatus(callback->asBinder().get(), STATUS_OK);
571     server->init();
572     PowerPolicyInitData initData;
573     server->notifyCarServiceReady(callback, &initData);
574 
575     ScopedAStatus status = server->applyPowerPolicyAsync(/*requestId=*/9999, "policy_id_other_off",
576                                                          /*force=*/false);
577     ASSERT_FALSE(status.isOk())
578             << "applyPowerPolicyAsync should fail when the caller doesn't have system UID";
579 }
580 
TEST_F(CarPowerPolicyServerTest,TestApplyPowerPolicyFromCarService_invalidPolicyId)581 TEST_F(CarPowerPolicyServerTest, TestApplyPowerPolicyFromCarService_invalidPolicyId) {
582     if (!car_power_policy_refactoring()) {
583         GTEST_SKIP() << "car_power_policy_refactoring feature flag is not enabled";
584     }
585 
586     sp<internal::CarPowerPolicyServerPeer> server = new internal::CarPowerPolicyServerPeer();
587     std::shared_ptr<MockPowerPolicyDelegateCallback> callback =
588             ndk::SharedRefBase::make<MockPowerPolicyDelegateCallback>();
589     server->expectLinkToDeathStatus(callback->asBinder().get(), STATUS_OK);
590     server->init();
591     setSystemCallingUid();
592     PowerPolicyInitData initData;
593     server->notifyCarServiceReady(callback, &initData);
594     std::mutex mutex;
595     std::condition_variable cv;
596     int32_t requestIdLocal;
597     bool methodCalled = false;
598     PowerPolicyFailureReason failureReason;
599     EXPECT_CALL(*callback, onApplyPowerPolicyFailed)
600             .WillRepeatedly(Invoke(
601                     [&requestIdLocal, &failureReason, &methodCalled, &cv,
602                      &mutex](int32_t requestId, PowerPolicyFailureReason reason) -> ScopedAStatus {
603                         std::unique_lock lock(mutex);
604                         requestIdLocal = requestId;
605                         failureReason = reason;
606                         methodCalled = true;
607                         cv.notify_all();
608                         return ScopedAStatus::ok();
609                     }));
610 
611     ScopedAStatus status = server->applyPowerPolicyAsync(/*requestId=*/9999, "policy_not_exist",
612                                                          /*force=*/false);
613     ASSERT_TRUE(status.isOk());
614     std::unique_lock lock(mutex);
615     bool waitResult =
616             cv.wait_for(lock, kCallbackWaitTime, [&methodCalled] { return methodCalled; });
617     ASSERT_TRUE(waitResult) << "onApplyPowerPolicyFailed should be called";
618     EXPECT_EQ(requestIdLocal, 9999);
619     ASSERT_EQ(failureReason, PowerPolicyFailureReason::POWER_POLICY_FAILURE_NOT_REGISTERED_ID);
620 }
621 
TEST_F(CarPowerPolicyServerTest,TestApplyPowerPolicyFromCarService_duplicatedRequestId)622 TEST_F(CarPowerPolicyServerTest, TestApplyPowerPolicyFromCarService_duplicatedRequestId) {
623     if (!car_power_policy_refactoring()) {
624         GTEST_SKIP() << "car_power_policy_refactoring feature flag is not enabled";
625     }
626 
627     sp<internal::CarPowerPolicyServerPeer> server = new internal::CarPowerPolicyServerPeer();
628     std::shared_ptr<MockPowerPolicyDelegateCallback> callback =
629             ndk::SharedRefBase::make<MockPowerPolicyDelegateCallback>();
630     server->expectLinkToDeathStatus(callback->asBinder().get(), STATUS_OK);
631     server->init();
632     setSystemCallingUid();
633     EXPECT_CALL(*callback, updatePowerComponents)
634             .WillRepeatedly(
635                     Invoke([]([[maybe_unused]] const CarPowerPolicy& policy) -> ScopedAStatus {
636                         // To make sure that both requests of applying power policy occur together.
637                         std::this_thread::sleep_for(kGeneralWaitTime);
638                         return ScopedAStatus::ok();
639                     }));
640     EXPECT_CALL(*callback, onApplyPowerPolicySucceeded)
641             .WillRepeatedly(Invoke([]([[maybe_unused]] int32_t requestId,
642                                       [[maybe_unused]] const CarPowerPolicy& accumulatedPolicy,
643                                       [[maybe_unused]] bool deferred) -> ScopedAStatus {
644                 return ScopedAStatus::ok();
645             }));
646     PowerPolicyInitData initData;
647     server->notifyCarServiceReady(callback, &initData);
648 
649     ScopedAStatus status = server->applyPowerPolicyAsync(/*requestId=*/9999, "policy_id_other_off",
650                                                          /*force=*/false);
651     ASSERT_TRUE(status.isOk()) << "applyPowerPolicyAsync should return OK";
652 
653     status = server->applyPowerPolicyAsync(/*requestId=*/9999, "policy_id_other_untouched",
654                                            /*force=*/false);
655     ASSERT_FALSE(status.isOk())
656             << "applyPowerPolicyAsync should return an error when request ID is duplicated";
657 }
658 
TEST_F(CarPowerPolicyServerTest,TestApplyPowerPolicyPerPowerStateChangeAsync)659 TEST_F(CarPowerPolicyServerTest, TestApplyPowerPolicyPerPowerStateChangeAsync) {
660     if (!car_power_policy_refactoring()) {
661         GTEST_SKIP() << "car_power_policy_refactoring feature flag is not enabled";
662     }
663 
664     testApplyPowerPolicyPerPowerStateChangeAsyncInternal("", "system_power_policy_all_on");
665 }
666 
TEST_F(CarPowerPolicyServerTest,TestApplyPowerPolicyPerPowerStateChangeAsync_nonSystemUid)667 TEST_F(CarPowerPolicyServerTest, TestApplyPowerPolicyPerPowerStateChangeAsync_nonSystemUid) {
668     if (!car_power_policy_refactoring()) {
669         GTEST_SKIP() << "car_power_policy_refactoring feature flag is not enabled";
670     }
671 
672     sp<internal::CarPowerPolicyServerPeer> server = new internal::CarPowerPolicyServerPeer();
673     std::shared_ptr<MockPowerPolicyDelegateCallback> callback =
674             ndk::SharedRefBase::make<MockPowerPolicyDelegateCallback>();
675     server->expectLinkToDeathStatus(callback->asBinder().get(), STATUS_OK);
676     server->init();
677     PowerPolicyInitData initData;
678     server->notifyCarServiceReady(callback, &initData);
679 
680     ScopedAStatus status =
681             server->applyPowerPolicyPerPowerStateChangeAsync(/*requestId=*/9999,
682                                                              ICarPowerPolicyDelegate::PowerState::
683                                                                      ON);
684 
685     ASSERT_FALSE(status.isOk()) << "applyPowerPolicyPerPowerStateChangeAsync should fail when the "
686                                    "caller doesn't have system UID";
687 }
688 
TEST_F(CarPowerPolicyServerTest,TestApplyPowerPolicyPerPowerStateChangeAsync_notSupportedPowerState)689 TEST_F(CarPowerPolicyServerTest,
690        TestApplyPowerPolicyPerPowerStateChangeAsync_notSupportedPowerState) {
691     if (!car_power_policy_refactoring()) {
692         GTEST_SKIP() << "car_power_policy_refactoring feature flag is not enabled";
693     }
694 
695     sp<internal::CarPowerPolicyServerPeer> server = new internal::CarPowerPolicyServerPeer();
696     std::shared_ptr<MockPowerPolicyDelegateCallback> callback =
697             ndk::SharedRefBase::make<MockPowerPolicyDelegateCallback>();
698     server->expectLinkToDeathStatus(callback->asBinder().get(), STATUS_OK);
699     server->init();
700     setSystemCallingUid();
701     EXPECT_CALL(*callback, updatePowerComponents).Times(0);
702     EXPECT_CALL(*callback, onPowerPolicyChanged).Times(0);
703     PowerPolicyInitData initData;
704     server->notifyCarServiceReady(callback, &initData);
705 
706     // We don't have default power policy for SHUTDOWN_PREPARE.
707     ScopedAStatus status =
708             server->applyPowerPolicyPerPowerStateChangeAsync(/*requestId=*/9999,
709                                                              ICarPowerPolicyDelegate::PowerState::
710                                                                      SHUTDOWN_PREPARE);
711 
712     EXPECT_FALSE(status.isOk())
713             << "applyPowerPolicyPerPowerStateChangeAsync should return an error";
714     EXPECT_EQ(status.getServiceSpecificError(), EX_ILLEGAL_ARGUMENT) << "Error code should be set";
715 
716     // Wait for some time to verify that no callback is made to CPMS.
717     std::this_thread::sleep_for(kGeneralWaitTime);
718 }
719 
TEST_F(CarPowerPolicyServerTest,TestApplyPowerPolicyPerPowerStateChangeAsync_withNewGroup)720 TEST_F(CarPowerPolicyServerTest, TestApplyPowerPolicyPerPowerStateChangeAsync_withNewGroup) {
721     if (!car_power_policy_refactoring()) {
722         GTEST_SKIP() << "car_power_policy_refactoring feature flag is not enabled";
723     }
724 
725     testApplyPowerPolicyPerPowerStateChangeAsyncInternal("basic_policy_group",
726                                                          "policy_id_other_untouched");
727 }
728 
729 }  // namespace powerpolicy
730 }  // namespace automotive
731 }  // namespace frameworks
732 }  // namespace android
733