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(¤tPolicy);
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