• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2020, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "carpowerpolicyd"
18 #define DEBUG false  // STOPSHIP if true.
19 
20 #include "CarPowerPolicyServer.h"
21 
22 #include <aidl/android/hardware/automotive/vehicle/StatusCode.h>
23 #include <aidl/android/hardware/automotive/vehicle/SubscribeOptions.h>
24 #include <aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReport.h>
25 #include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h>
26 #include <android-base/file.h>
27 #include <android-base/stringprintf.h>
28 #include <android/binder_ibinder.h>
29 #include <android/binder_manager.h>
30 #include <android/binder_status.h>
31 #include <binder/IPCThreadState.h>
32 #include <binder/IServiceManager.h>
33 #include <hidl/HidlTransportSupport.h>
34 #include <private/android_filesystem_config.h>
35 #include <utils/String8.h>
36 #include <utils/SystemClock.h>
37 #include <utils/Timers.h>
38 
39 #include <inttypes.h>
40 
41 namespace android {
42 namespace frameworks {
43 namespace automotive {
44 namespace powerpolicy {
45 
46 using ::aidl::android::frameworks::automotive::powerpolicy::CarPowerPolicy;
47 using ::aidl::android::frameworks::automotive::powerpolicy::CarPowerPolicyFilter;
48 using ::aidl::android::frameworks::automotive::powerpolicy::ICarPowerPolicyChangeCallback;
49 using ::aidl::android::frameworks::automotive::powerpolicy::PowerComponent;
50 using ::aidl::android::frameworks::automotive::powerpolicy::internal::PolicyState;
51 using ::aidl::android::hardware::automotive::vehicle::StatusCode;
52 using ::aidl::android::hardware::automotive::vehicle::SubscribeOptions;
53 using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReport;
54 using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
55 
56 using ::android::defaultServiceManager;
57 using ::android::IBinder;
58 using ::android::Looper;
59 using ::android::Mutex;
60 using ::android::status_t;
61 using ::android::String16;
62 using ::android::uptimeMillis;
63 using ::android::Vector;
64 using ::android::wp;
65 using ::android::base::Error;
66 using ::android::base::Result;
67 using ::android::base::StringAppendF;
68 using ::android::base::StringPrintf;
69 using ::android::base::WriteStringToFd;
70 using ::android::frameworks::automotive::vhal::HalPropError;
71 using ::android::frameworks::automotive::vhal::IHalPropValue;
72 using ::android::frameworks::automotive::vhal::ISubscriptionClient;
73 using ::android::frameworks::automotive::vhal::IVhalClient;
74 using ::android::hardware::hidl_vec;
75 using ::android::hardware::interfacesEqual;
76 using ::android::hardware::Return;
77 using ::android::hardware::automotive::vehicle::VhalResult;
78 
79 using ::android::hidl::base::V1_0::IBase;
80 using ::ndk::ScopedAIBinder_DeathRecipient;
81 using ::ndk::ScopedAStatus;
82 using ::ndk::SharedRefBase;
83 using ::ndk::SpAIBinder;
84 
85 namespace {
86 
87 const int32_t MSG_CONNECT_TO_VHAL = 1;  // Message to request of connecting to VHAL.
88 
89 const nsecs_t kConnectionRetryIntervalNs = 200000000;  // 200 milliseconds.
90 const int32_t kMaxConnectionRetry = 25;                // Retry up to 5 seconds.
91 
92 constexpr const char kCarServiceInterface[] = "car_service";
93 constexpr const char kCarPowerPolicyServerInterface[] =
94         "android.frameworks.automotive.powerpolicy.ICarPowerPolicyServer/default";
95 constexpr const char kCarPowerPolicySystemNotificationInterface[] =
96         "android.frameworks.automotive.powerpolicy.internal.ICarPowerPolicySystemNotification/"
97         "default";
98 
lookupPowerPolicyChangeCallback(const std::vector<CallbackInfo> & callbacks,const AIBinder * binder)99 std::vector<CallbackInfo>::const_iterator lookupPowerPolicyChangeCallback(
100         const std::vector<CallbackInfo>& callbacks, const AIBinder* binder) {
101     for (auto it = callbacks.begin(); it != callbacks.end(); it++) {
102         if (it->binder.get() == binder) {
103             return it;
104         }
105     }
106     return callbacks.end();
107 }
108 
checkSystemPermission()109 ScopedAStatus checkSystemPermission() {
110     if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
111         return ScopedAStatus::fromServiceSpecificErrorWithMessage(EX_SECURITY,
112                                                                   "Calling process does not have "
113                                                                   "proper privilege");
114     }
115     return ScopedAStatus::ok();
116 }
117 
118 }  // namespace
119 
120 std::shared_ptr<CarPowerPolicyServer> CarPowerPolicyServer::sCarPowerPolicyServer = nullptr;
121 
PropertyChangeListener(CarPowerPolicyServer * service)122 PropertyChangeListener::PropertyChangeListener(CarPowerPolicyServer* service) : mService(service) {}
123 
onPropertyEvent(const std::vector<std::unique_ptr<IHalPropValue>> & values)124 void PropertyChangeListener::onPropertyEvent(
125         const std::vector<std::unique_ptr<IHalPropValue>>& values) {
126     for (const auto& value : values) {
127         const std::string stringValue = value->getStringValue();
128         int32_t propId = value->getPropId();
129         if (propId == static_cast<int32_t>(VehicleProperty::POWER_POLICY_GROUP_REQ)) {
130             const auto& ret = mService->setPowerPolicyGroup(stringValue);
131             if (!ret.ok()) {
132                 ALOGW("Failed to set power policy group(%s): %s", stringValue.c_str(),
133                       ret.error().message().c_str());
134             }
135         } else if (propId == static_cast<int32_t>(VehicleProperty::POWER_POLICY_REQ)) {
136             const auto& ret = mService->applyPowerPolicy(stringValue,
137                                                          /*carServiceExpected=*/false,
138                                                          /*force=*/false);
139             if (!ret.ok()) {
140                 ALOGW("Failed to apply power policy(%s): %s", stringValue.c_str(),
141                       ret.error().message().c_str());
142             }
143         }
144     }
145 }
146 
onPropertySetError(const std::vector<HalPropError> & errors)147 void PropertyChangeListener::onPropertySetError(
148         [[maybe_unused]] const std::vector<HalPropError>& errors) {
149     return;
150 }
151 
MessageHandlerImpl(CarPowerPolicyServer * service)152 MessageHandlerImpl::MessageHandlerImpl(CarPowerPolicyServer* service) : mService(service) {}
153 
handleMessage(const Message & message)154 void MessageHandlerImpl::handleMessage(const Message& message) {
155     switch (message.what) {
156         case MSG_CONNECT_TO_VHAL:
157             mService->connectToVhalHelper();
158             break;
159         default:
160             ALOGW("Unknown message: %d", message.what);
161     }
162 }
163 
CarServiceNotificationHandler(CarPowerPolicyServer * service)164 CarServiceNotificationHandler::CarServiceNotificationHandler(CarPowerPolicyServer* service) :
165       mService(service) {}
166 
terminate()167 void CarServiceNotificationHandler::terminate() {
168     Mutex::Autolock lock(mMutex);
169     mService = nullptr;
170 }
171 
dump(int fd,const char ** args,uint32_t numArgs)172 binder_status_t CarServiceNotificationHandler::dump(int fd, const char** args, uint32_t numArgs) {
173     Mutex::Autolock lock(mMutex);
174     if (mService == nullptr) {
175         ALOGD("Skip dumping, CarPowerPolicyServer is ending");
176         return STATUS_OK;
177     }
178     return mService->dump(fd, args, numArgs);
179 }
180 
notifyCarServiceReady(PolicyState * policyState)181 ScopedAStatus CarServiceNotificationHandler::notifyCarServiceReady(PolicyState* policyState) {
182     Mutex::Autolock lock(mMutex);
183     if (mService == nullptr) {
184         ALOGD("Skip notifying CarServiceReady, CarPowerPolicyServer is ending");
185         return ScopedAStatus::ok();
186     }
187     return mService->notifyCarServiceReady(policyState);
188 }
189 
notifyPowerPolicyChange(const std::string & policyId,bool force)190 ScopedAStatus CarServiceNotificationHandler::notifyPowerPolicyChange(const std::string& policyId,
191                                                                      bool force) {
192     Mutex::Autolock lock(mMutex);
193     if (mService == nullptr) {
194         ALOGD("Skip notifying PowerPolicyChange, CarPowerPolicyServer is ending");
195         return ScopedAStatus::ok();
196     }
197     return mService->notifyPowerPolicyChange(policyId, force);
198 }
199 
notifyPowerPolicyDefinition(const std::string & policyId,const std::vector<std::string> & enabledComponents,const std::vector<std::string> & disabledComponents)200 ScopedAStatus CarServiceNotificationHandler::notifyPowerPolicyDefinition(
201         const std::string& policyId, const std::vector<std::string>& enabledComponents,
202         const std::vector<std::string>& disabledComponents) {
203     Mutex::Autolock lock(mMutex);
204     if (mService == nullptr) {
205         ALOGD("Skip notifying PowerPolicyDefinition, CarPowerPolicyServer is ending");
206         return ScopedAStatus::ok();
207     }
208     return mService->notifyPowerPolicyDefinition(policyId, enabledComponents, disabledComponents);
209 }
210 
~ISilentModeChangeHandler()211 ISilentModeChangeHandler::~ISilentModeChangeHandler() {}
212 
startService(const sp<Looper> & looper)213 Result<std::shared_ptr<CarPowerPolicyServer>> CarPowerPolicyServer::startService(
214         const sp<Looper>& looper) {
215     if (sCarPowerPolicyServer != nullptr) {
216         return Error(INVALID_OPERATION) << "Cannot start service more than once";
217     }
218     std::shared_ptr<CarPowerPolicyServer> server = SharedRefBase::make<CarPowerPolicyServer>();
219     const auto& ret = server->init(looper);
220     if (!ret.ok()) {
221         return Error(ret.error().code())
222                 << "Failed to start car power policy server: " << ret.error();
223     }
224     sCarPowerPolicyServer = server;
225 
226     return sCarPowerPolicyServer;
227 }
228 
terminateService()229 void CarPowerPolicyServer::terminateService() {
230     if (sCarPowerPolicyServer != nullptr) {
231         sCarPowerPolicyServer->terminate();
232         sCarPowerPolicyServer = nullptr;
233     }
234 }
235 
CarPowerPolicyServer()236 CarPowerPolicyServer::CarPowerPolicyServer() :
237       mSilentModeHandler(this),
238       mIsPowerPolicyLocked(false),
239       mIsCarServiceInOperation(false),
240       mIsFirstConnectionToVhal(true) {
241     mMessageHandler = new MessageHandlerImpl(this);
242     mDeathRecipient = ScopedAIBinder_DeathRecipient(
243             AIBinder_DeathRecipient_new(&CarPowerPolicyServer::onBinderDied));
244     mPropertyChangeListener = std::make_unique<PropertyChangeListener>(this);
245     mLinkUnlinkImpl = std::make_unique<AIBinderLinkUnlinkImpl>();
246 }
247 
248 // For test-only.
setLinkUnlinkImpl(std::unique_ptr<CarPowerPolicyServer::LinkUnlinkImpl> impl)249 void CarPowerPolicyServer::setLinkUnlinkImpl(
250         std::unique_ptr<CarPowerPolicyServer::LinkUnlinkImpl> impl) {
251     mLinkUnlinkImpl = std::move(impl);
252 }
253 
getCurrentPowerPolicy(CarPowerPolicy * aidlReturn)254 ScopedAStatus CarPowerPolicyServer::getCurrentPowerPolicy(CarPowerPolicy* aidlReturn) {
255     Mutex::Autolock lock(mMutex);
256     if (!isPowerPolicyAppliedLocked()) {
257         return ScopedAStatus::
258                 fromServiceSpecificErrorWithMessage(EX_ILLEGAL_STATE,
259                                                     "The current power policy is not set");
260     }
261     *aidlReturn = *mCurrentPowerPolicyMeta.powerPolicy;
262     return ScopedAStatus::ok();
263 }
264 
getPowerComponentState(PowerComponent componentId,bool * aidlReturn)265 ScopedAStatus CarPowerPolicyServer::getPowerComponentState(PowerComponent componentId,
266                                                            bool* aidlReturn) {
267     const auto& ret = mComponentHandler.getPowerComponentState(componentId);
268     if (!ret.ok()) {
269         std::string errorMsg = ret.error().message();
270         ALOGW("getPowerComponentState(%s) failed: %s", toString(componentId).c_str(),
271               errorMsg.c_str());
272         return ScopedAStatus::fromServiceSpecificErrorWithMessage(EX_ILLEGAL_ARGUMENT,
273                                                                   errorMsg.c_str());
274     }
275     *aidlReturn = *ret;
276     return ScopedAStatus::ok();
277 }
278 
registerPowerPolicyChangeCallback(const std::shared_ptr<ICarPowerPolicyChangeCallback> & callback,const CarPowerPolicyFilter & filter)279 ScopedAStatus CarPowerPolicyServer::registerPowerPolicyChangeCallback(
280         const std::shared_ptr<ICarPowerPolicyChangeCallback>& callback,
281         const CarPowerPolicyFilter& filter) {
282     Mutex::Autolock lock(mMutex);
283     pid_t callingPid = IPCThreadState::self()->getCallingPid();
284     uid_t callingUid = IPCThreadState::self()->getCallingUid();
285     SpAIBinder binder = callback->asBinder();
286     AIBinder* clientId = binder.get();
287     if (isRegisteredLocked(clientId)) {
288         std::string errorStr = StringPrintf("The callback(pid: %d, uid: %d) is already registered.",
289                                             callingPid, callingUid);
290         const char* errorCause = errorStr.c_str();
291         ALOGW("Cannot register a callback: %s", errorCause);
292         return ScopedAStatus::fromServiceSpecificErrorWithMessage(EX_ILLEGAL_ARGUMENT, errorCause);
293     }
294 
295     std::unique_ptr<OnBinderDiedContext> context = std::make_unique<OnBinderDiedContext>(
296             OnBinderDiedContext{.server = this, .clientId = clientId});
297     binder_status_t status = mLinkUnlinkImpl->linkToDeath(clientId, mDeathRecipient.get(),
298                                                           static_cast<void*>(context.get()));
299     if (status != STATUS_OK) {
300         std::string errorStr = StringPrintf("The given callback(pid: %d, uid: %d) is dead",
301                                             callingPid, callingUid);
302         const char* errorCause = errorStr.c_str();
303         ALOGW("Cannot register a callback: %s", errorCause);
304         return ScopedAStatus::fromServiceSpecificErrorWithMessage(EX_ILLEGAL_STATE, errorCause);
305     }
306     // Insert into a map to keep the context object alive.
307     mOnBinderDiedContexts[clientId] = std::move(context);
308     mPolicyChangeCallbacks.emplace_back(binder, filter, callingPid);
309 
310     if (DEBUG) {
311         ALOGD("Power policy change callback(pid: %d, filter: %s) is registered", callingPid,
312               toString(filter.components).c_str());
313     }
314     return ScopedAStatus::ok();
315 }
316 
unregisterPowerPolicyChangeCallback(const std::shared_ptr<ICarPowerPolicyChangeCallback> & callback)317 ScopedAStatus CarPowerPolicyServer::unregisterPowerPolicyChangeCallback(
318         const std::shared_ptr<ICarPowerPolicyChangeCallback>& callback) {
319     Mutex::Autolock lock(mMutex);
320     pid_t callingPid = IPCThreadState::self()->getCallingPid();
321     uid_t callingUid = IPCThreadState::self()->getCallingUid();
322     AIBinder* clientId = callback->asBinder().get();
323     auto it = lookupPowerPolicyChangeCallback(mPolicyChangeCallbacks, clientId);
324     if (it == mPolicyChangeCallbacks.end()) {
325         std::string errorStr =
326                 StringPrintf("The callback(pid: %d, uid: %d) has not been registered", callingPid,
327                              callingUid);
328         const char* errorCause = errorStr.c_str();
329         ALOGW("Cannot unregister a callback: %s", errorCause);
330         return ScopedAStatus::fromServiceSpecificErrorWithMessage(EX_ILLEGAL_ARGUMENT, errorCause);
331     }
332     if (mOnBinderDiedContexts.find(clientId) != mOnBinderDiedContexts.end()) {
333         // We don't set a callback for unlinkToDeath but need to call unlinkToDeath to clean up the
334         // registered death recipient.
335         mLinkUnlinkImpl->unlinkToDeath(clientId, mDeathRecipient.get(),
336                                        static_cast<void*>(mOnBinderDiedContexts[clientId].get()));
337         mOnBinderDiedContexts.erase(clientId);
338     }
339     mPolicyChangeCallbacks.erase(it);
340     if (DEBUG) {
341         ALOGD("Power policy change callback(pid: %d, uid: %d) is unregistered", callingPid,
342               callingUid);
343     }
344     return ScopedAStatus::ok();
345 }
346 
notifyCarServiceReady(PolicyState * policyState)347 ScopedAStatus CarPowerPolicyServer::notifyCarServiceReady(PolicyState* policyState) {
348     ScopedAStatus status = checkSystemPermission();
349     if (!status.isOk()) {
350         return status;
351     }
352     mSilentModeHandler.stopMonitoringSilentModeHwState(/*shouldWaitThread=*/false);
353     Mutex::Autolock lock(mMutex);
354     policyState->policyId =
355             isPowerPolicyAppliedLocked() ? mCurrentPowerPolicyMeta.powerPolicy->policyId : "";
356     policyState->policyGroupId = mCurrentPolicyGroupId;
357     mIsCarServiceInOperation = true;
358     ALOGI("CarService is now responsible for power policy management");
359     return ScopedAStatus::ok();
360 }
361 
notifyPowerPolicyChange(const std::string & policyId,bool force)362 ScopedAStatus CarPowerPolicyServer::notifyPowerPolicyChange(const std::string& policyId,
363                                                             bool force) {
364     ScopedAStatus status = checkSystemPermission();
365     if (!status.isOk()) {
366         return status;
367     }
368     const auto& ret = applyPowerPolicy(policyId, /*carServiceExpected=*/true, force);
369     if (!ret.ok()) {
370         return ScopedAStatus::
371                 fromServiceSpecificErrorWithMessage(EX_ILLEGAL_STATE,
372                                                     StringPrintf("Failed to notify power policy "
373                                                                  "change: %s",
374                                                                  ret.error().message().c_str())
375                                                             .c_str());
376     }
377     ALOGD("Policy change(%s) is notified by CarService", policyId.c_str());
378     return ScopedAStatus::ok();
379 }
380 
notifyPowerPolicyDefinition(const std::string & policyId,const std::vector<std::string> & enabledComponents,const std::vector<std::string> & disabledComponents)381 ScopedAStatus CarPowerPolicyServer::notifyPowerPolicyDefinition(
382         const std::string& policyId, const std::vector<std::string>& enabledComponents,
383         const std::vector<std::string>& disabledComponents) {
384     ScopedAStatus status = checkSystemPermission();
385     if (!status.isOk()) {
386         return status;
387     }
388     const auto& ret =
389             mPolicyManager.definePowerPolicy(policyId, enabledComponents, disabledComponents);
390     if (!ret.ok()) {
391         return ScopedAStatus::
392                 fromServiceSpecificErrorWithMessage(EX_ILLEGAL_ARGUMENT,
393                                                     StringPrintf("Failed to notify power policy "
394                                                                  "definition: %s",
395                                                                  ret.error().message().c_str())
396                                                             .c_str());
397     }
398     return ScopedAStatus::ok();
399 }
400 
dump(int fd,const char ** args,uint32_t numArgs)401 status_t CarPowerPolicyServer::dump(int fd, const char** args, uint32_t numArgs) {
402     Vector<String16> argsV;
403     for (size_t i = 0; i < numArgs; i++) {
404         argsV.push(String16(args[i]));
405     }
406 
407     {
408         Mutex::Autolock lock(mMutex);
409         const char* indent = "  ";
410         const char* doubleIndent = "    ";
411         WriteStringToFd("CAR POWER POLICY DAEMON\n", fd);
412         WriteStringToFd(StringPrintf("%sCarService is in operation: %s\n", indent,
413                                      mIsCarServiceInOperation ? "true" : "false"),
414                         fd);
415         WriteStringToFd(StringPrintf("%sConnection to VHAL: %s\n", indent,
416                                      mVhalService.get() ? "connected" : "disconnected"),
417                         fd);
418         WriteStringToFd(StringPrintf("%sCurrent power policy: %s\n", indent,
419                                      isPowerPolicyAppliedLocked()
420                                              ? mCurrentPowerPolicyMeta.powerPolicy->policyId.c_str()
421                                              : "not set"),
422                         fd);
423         WriteStringToFd(StringPrintf("%sLast uptime of applying power policy: %" PRId64 "ms\n",
424                                      indent, mLastApplyPowerPolicyUptimeMs.value_or(-1)),
425                         fd);
426         WriteStringToFd(StringPrintf("%sPending power policy ID: %s\n", indent,
427                                      mPendingPowerPolicyId.c_str()),
428                         fd);
429         WriteStringToFd(StringPrintf("%sCurrent power policy group ID: %s\n", indent,
430                                      mCurrentPolicyGroupId.empty() ? "not set"
431                                                                    : mCurrentPolicyGroupId.c_str()),
432                         fd);
433         WriteStringToFd(StringPrintf("%sLast uptime of setting default power policy group: "
434                                      "%" PRId64 "ms\n",
435                                      indent, mLastSetDefaultPowerPolicyGroupUptimeMs.value_or(-1)),
436                         fd);
437         WriteStringToFd(StringPrintf("%sPolicy change callbacks:%s\n", indent,
438                                      mPolicyChangeCallbacks.size() ? "" : " none"),
439                         fd);
440         for (auto& callback : mPolicyChangeCallbacks) {
441             WriteStringToFd(StringPrintf("%s- %s\n", doubleIndent,
442                                          callbackToString(callback).c_str()),
443                             fd);
444         }
445     }
446     if (const auto& ret = mPolicyManager.dump(fd, argsV); !ret.ok()) {
447         ALOGW("Failed to dump power policy handler: %s", ret.error().message().c_str());
448         return ret.error().code();
449     }
450     if (const auto& ret = mComponentHandler.dump(fd); !ret.ok()) {
451         ALOGW("Failed to dump power component handler: %s", ret.error().message().c_str());
452         return ret.error().code();
453     }
454     if (const auto& ret = mSilentModeHandler.dump(fd, argsV); !ret.ok()) {
455         ALOGW("Failed to dump Silent Mode handler: %s", ret.error().message().c_str());
456         return ret.error().code();
457     }
458     return OK;
459 }
460 
init(const sp<Looper> & looper)461 Result<void> CarPowerPolicyServer::init(const sp<Looper>& looper) {
462     AIBinder* binderCarService = AServiceManager_checkService(kCarServiceInterface);
463 
464     Mutex::Autolock lock(mMutex);
465     // Before initializing power policy daemon, we need to update mIsCarServiceInOperation
466     // according to whether CPMS is running.
467     mIsCarServiceInOperation = binderCarService != nullptr;
468 
469     mHandlerLooper = looper;
470     mPolicyManager.init();
471     mComponentHandler.init();
472     mSilentModeHandler.init();
473     mCarServiceNotificationHandler = SharedRefBase::make<CarServiceNotificationHandler>(this);
474 
475     binder_exception_t err =
476             AServiceManager_addService(this->asBinder().get(), kCarPowerPolicyServerInterface);
477     if (err != EX_NONE) {
478         return Error(err) << "Failed to add carpowerpolicyd to ServiceManager";
479     }
480     err = AServiceManager_addService(mCarServiceNotificationHandler->asBinder().get(),
481                                      kCarPowerPolicySystemNotificationInterface);
482     if (err != EX_NONE) {
483         return Error(err) << "Failed to add car power policy system notification to ServiceManager";
484     }
485 
486     connectToVhal();
487     return {};
488 }
489 
terminate()490 void CarPowerPolicyServer::terminate() {
491     Mutex::Autolock lock(mMutex);
492     mPolicyChangeCallbacks.clear();
493     if (mVhalService != nullptr) {
494         mSubscriptionClient->unsubscribe(
495                 {static_cast<int32_t>(VehicleProperty::POWER_POLICY_REQ),
496                  static_cast<int32_t>(VehicleProperty::POWER_POLICY_GROUP_REQ)});
497     }
498 
499     if (mCarServiceNotificationHandler != nullptr) {
500         mCarServiceNotificationHandler->terminate();
501         mCarServiceNotificationHandler = nullptr;
502     }
503 
504     // Delete the deathRecipient so that all binders would be unlinked.
505     mDeathRecipient = ScopedAIBinder_DeathRecipient();
506     mSilentModeHandler.release();
507     // Remove the messages so that mMessageHandler would no longer be used.
508     mHandlerLooper->removeMessages(mMessageHandler);
509 }
510 
onBinderDied(void * cookie)511 void CarPowerPolicyServer::onBinderDied(void* cookie) {
512     OnBinderDiedContext* context = reinterpret_cast<OnBinderDiedContext*>(cookie);
513     context->server->handleBinderDeath(context->clientId);
514 }
515 
handleBinderDeath(const AIBinder * clientId)516 void CarPowerPolicyServer::handleBinderDeath(const AIBinder* clientId) {
517     Mutex::Autolock lock(mMutex);
518     auto it = lookupPowerPolicyChangeCallback(mPolicyChangeCallbacks, clientId);
519     if (it != mPolicyChangeCallbacks.end()) {
520         ALOGW("Power policy callback(pid: %d) died", it->pid);
521         mPolicyChangeCallbacks.erase(it);
522     }
523     mOnBinderDiedContexts.erase(clientId);
524 }
525 
handleVhalDeath()526 void CarPowerPolicyServer::handleVhalDeath() {
527     {
528         Mutex::Autolock lock(mMutex);
529         ALOGW("VHAL has died.");
530         mVhalService = nullptr;
531     }
532     connectToVhal();
533 }
534 
applyPowerPolicy(const std::string & policyId,const bool carServiceInOperation,const bool force)535 Result<void> CarPowerPolicyServer::applyPowerPolicy(const std::string& policyId,
536                                                     const bool carServiceInOperation,
537                                                     const bool force) {
538     auto policyMeta = mPolicyManager.getPowerPolicy(policyId);
539     if (!policyMeta.ok()) {
540         return Error() << "Failed to apply power policy: " << policyMeta.error().message();
541     }
542 
543     std::vector<CallbackInfo> clients;
544     if (Mutex::Autolock lock(mMutex); mIsCarServiceInOperation != carServiceInOperation) {
545         return Error() << (mIsCarServiceInOperation
546                                    ? "After CarService starts serving, power policy cannot be "
547                                      "managed in car power policy daemon"
548                                    : "Before CarService starts serving, power policy cannot be "
549                                      "applied from CarService");
550     } else {
551         if (mVhalService == nullptr) {
552             ALOGI("%s is queued and will be applied after VHAL gets ready", policyId.c_str());
553             mPendingPowerPolicyId = policyId;
554             return {};
555         }
556         bool isPolicyApplied = isPowerPolicyAppliedLocked();
557         if (isPolicyApplied && mCurrentPowerPolicyMeta.powerPolicy->policyId == policyId) {
558             ALOGI("Applying policy skipped: the given policy(ID: %s) is the current policy",
559                   policyId.c_str());
560             return {};
561         }
562         if (policyMeta->isPreemptive) {
563             if (isPolicyApplied && !mCurrentPowerPolicyMeta.isPreemptive) {
564                 mPendingPowerPolicyId = mCurrentPowerPolicyMeta.powerPolicy->policyId;
565             }
566             mIsPowerPolicyLocked = true;
567         } else {
568             if (force) {
569                 mPendingPowerPolicyId.clear();
570                 mIsPowerPolicyLocked = false;
571             } else if (mIsPowerPolicyLocked) {
572                 ALOGI("%s is queued and will be applied after power policy get unlocked",
573                       policyId.c_str());
574                 mPendingPowerPolicyId = policyId;
575                 return {};
576             }
577         }
578         mCurrentPowerPolicyMeta = *policyMeta;
579         clients = mPolicyChangeCallbacks;
580         mLastApplyPowerPolicyUptimeMs = uptimeMillis();
581     }
582     CarPowerPolicyPtr policy = policyMeta->powerPolicy;
583     mComponentHandler.applyPowerPolicy(policy);
584     if (const auto& ret = notifyVhalNewPowerPolicy(policyId); !ret.ok()) {
585         ALOGW("Failed to tell VHAL the new power policy(%s): %s", policyId.c_str(),
586               ret.error().message().c_str());
587     }
588     for (auto client : clients) {
589         ICarPowerPolicyChangeCallback::fromBinder(client.binder)->onPolicyChanged(*policy);
590     }
591     ALOGI("The current power policy is %s", policyId.c_str());
592     return {};
593 }
594 
setPowerPolicyGroup(const std::string & groupId)595 Result<void> CarPowerPolicyServer::setPowerPolicyGroup(const std::string& groupId) {
596     if (!mPolicyManager.isPowerPolicyGroupAvailable(groupId)) {
597         return Error() << StringPrintf("Power policy group(%s) is not available", groupId.c_str());
598     }
599     Mutex::Autolock lock(mMutex);
600     if (mIsCarServiceInOperation) {
601         return Error() << "After CarService starts serving, power policy group cannot be set in "
602                           "car power policy daemon";
603     }
604     mCurrentPolicyGroupId = groupId;
605     ALOGI("The current power policy group is |%s|", groupId.c_str());
606     return {};
607 }
608 
notifySilentModeChange(const bool isSilent)609 void CarPowerPolicyServer::notifySilentModeChange(const bool isSilent) {
610     std::string pendingPowerPolicyId;
611     if (Mutex::Autolock lock(mMutex); mIsCarServiceInOperation) {
612         return;
613     } else {
614         pendingPowerPolicyId = mPendingPowerPolicyId;
615     }
616     ALOGI("Silent Mode is set to %s", isSilent ? "silent" : "non-silent");
617     Result<void> ret;
618     if (isSilent) {
619         ret = applyPowerPolicy(kSystemPolicyIdNoUserInteraction,
620                                /*carServiceExpected=*/false, /*force=*/false);
621     } else {
622         ret = applyPowerPolicy(pendingPowerPolicyId,
623                                /*carServiceExpected=*/false, /*force=*/true);
624     }
625     if (!ret.ok()) {
626         ALOGW("Failed to apply power policy: %s", ret.error().message().c_str());
627     }
628 }
629 
isRegisteredLocked(const AIBinder * binder)630 bool CarPowerPolicyServer::isRegisteredLocked(const AIBinder* binder) {
631     return lookupPowerPolicyChangeCallback(mPolicyChangeCallbacks, binder) !=
632             mPolicyChangeCallbacks.end();
633 }
634 
635 // This method ensures that the attempt to connect to VHAL occurs in the main thread.
connectToVhal()636 void CarPowerPolicyServer::connectToVhal() {
637     mRemainingConnectionRetryCount = kMaxConnectionRetry;
638     mHandlerLooper->sendMessage(mMessageHandler, MSG_CONNECT_TO_VHAL);
639 }
640 
641 // connectToVhalHelper is always executed in the main thread.
connectToVhalHelper()642 void CarPowerPolicyServer::connectToVhalHelper() {
643     {
644         Mutex::Autolock lock(mMutex);
645         if (mVhalService != nullptr) {
646             return;
647         }
648     }
649     std::shared_ptr<IVhalClient> vhalService = IVhalClient::tryCreate();
650     if (vhalService == nullptr) {
651         ALOGW("Failed to connect to VHAL. Retrying in %" PRId64 " ms.",
652               nanoseconds_to_milliseconds(kConnectionRetryIntervalNs));
653         mRemainingConnectionRetryCount--;
654         if (mRemainingConnectionRetryCount <= 0) {
655             ALOGE("Failed to connect to VHAL after %d attempt%s. Gave up.", kMaxConnectionRetry,
656                   kMaxConnectionRetry > 1 ? "s" : "");
657             return;
658         }
659         mHandlerLooper->sendMessageDelayed(kConnectionRetryIntervalNs, mMessageHandler,
660                                            MSG_CONNECT_TO_VHAL);
661         return;
662     }
663     vhalService->addOnBinderDiedCallback(
664             std::make_shared<IVhalClient::OnBinderDiedCallbackFunc>([this] { handleVhalDeath(); }));
665     std::string currentPolicyId;
666     {
667         Mutex::Autolock lock(mMutex);
668         mVhalService = vhalService;
669         mSubscriptionClient = mVhalService->getSubscriptionClient(mPropertyChangeListener);
670         if (isPowerPolicyAppliedLocked()) {
671             currentPolicyId = mCurrentPowerPolicyMeta.powerPolicy->policyId;
672         }
673     }
674     /*
675      * When VHAL is first executed, a normal power management goes on. When VHAL is restarted due to
676      * some reasons, the current policy is notified to VHAL.
677      */
678     if (mIsFirstConnectionToVhal) {
679         applyInitialPowerPolicy();
680         mIsFirstConnectionToVhal = false;
681     } else if (!currentPolicyId.empty()) {
682         notifyVhalNewPowerPolicy(currentPolicyId);
683     }
684     subscribeToVhal();
685     ALOGI("Connected to VHAL");
686     return;
687 }
688 
applyInitialPowerPolicy()689 void CarPowerPolicyServer::applyInitialPowerPolicy() {
690     std::string policyId;
691     std::string currentPolicyGroupId;
692     CarPowerPolicyPtr powerPolicy;
693     {
694         Mutex::Autolock lock(mMutex);
695         if (mIsCarServiceInOperation) {
696             ALOGI("Skipping initial power policy application because CarService is running");
697             return;
698         }
699         policyId = mPendingPowerPolicyId;
700         currentPolicyGroupId = mCurrentPolicyGroupId;
701     }
702     if (policyId.empty()) {
703         if (auto policy = mPolicyManager.getDefaultPowerPolicyForState(currentPolicyGroupId,
704                                                                        VehicleApPowerStateReport::
705                                                                                WAIT_FOR_VHAL);
706             policy.ok()) {
707             policyId = (*policy)->policyId;
708         } else {
709             policyId = kSystemPolicyIdInitialOn;
710         }
711     }
712     if (const auto& ret = applyPowerPolicy(policyId, /*carServiceExpected=*/false, /*force=*/false);
713         !ret.ok()) {
714         ALOGW("Cannot apply the initial power policy(%s): %s", policyId.c_str(),
715               ret.error().message().c_str());
716         return;
717     }
718     ALOGD("Policy(%s) is applied as the initial one", policyId.c_str());
719 }
720 
subscribeToVhal()721 void CarPowerPolicyServer::subscribeToVhal() {
722     subscribeToProperty(static_cast<int32_t>(VehicleProperty::POWER_POLICY_REQ),
723                         [this](const IHalPropValue& value) {
724                             std::string stringValue = value.getStringValue();
725                             if (stringValue.size() > 0) {
726                                 const auto& ret = applyPowerPolicy(stringValue,
727                                                                    /*carServiceExpected=*/false,
728                                                                    /*force=*/false);
729                                 if (!ret.ok()) {
730                                     ALOGW("Failed to apply power policy(%s): %s",
731                                           stringValue.c_str(), ret.error().message().c_str());
732                                 }
733                             }
734                         });
735     subscribeToProperty(static_cast<int32_t>(VehicleProperty::POWER_POLICY_GROUP_REQ),
736                         [this](const IHalPropValue& value) {
737                             std::string stringValue = value.getStringValue();
738                             if (stringValue.size() > 0) {
739                                 const auto& ret = setPowerPolicyGroup(stringValue);
740                                 if (ret.ok()) {
741                                     Mutex::Autolock lock(mMutex);
742                                     mLastSetDefaultPowerPolicyGroupUptimeMs = value.getTimestamp();
743                                 } else {
744                                     ALOGW("Failed to set power policy group(%s): %s",
745                                           stringValue.c_str(), ret.error().message().c_str());
746                                 }
747                             }
748                         });
749 }
750 
subscribeToProperty(int32_t prop,std::function<void (const IHalPropValue &)> processor)751 void CarPowerPolicyServer::subscribeToProperty(
752         int32_t prop, std::function<void(const IHalPropValue&)> processor) {
753     if (!isPropertySupported(prop)) {
754         ALOGW("Vehicle property(%d) is not supported by VHAL.", prop);
755         return;
756     }
757     std::shared_ptr<IVhalClient> vhalService;
758     {
759         Mutex::Autolock lock(mMutex);
760         if (mVhalService == nullptr) {
761             ALOGW("Failed to subscribe to property(%d): VHAL is not ready", prop);
762             return;
763         }
764         vhalService = mVhalService;
765     }
766 
767     VhalResult<std::unique_ptr<IHalPropValue>> result =
768             vhalService->getValueSync(*vhalService->createHalPropValue(prop));
769 
770     if (!result.ok()) {
771         ALOGW("Failed to get vehicle property(%d) value, error: %s.", prop,
772               result.error().message().c_str());
773         return;
774     }
775     processor(*result.value());
776     std::vector<SubscribeOptions> options = {
777             {.propId = prop, .areaIds = {}},
778     };
779 
780     if (auto result = mSubscriptionClient->subscribe(options); !result.ok()) {
781         ALOGW("Failed to subscribe to vehicle property(%d), error: %s", prop,
782               result.error().message().c_str());
783     }
784 }
785 
notifyVhalNewPowerPolicy(const std::string & policyId)786 Result<void> CarPowerPolicyServer::notifyVhalNewPowerPolicy(const std::string& policyId) {
787     int32_t prop = static_cast<int32_t>(VehicleProperty::CURRENT_POWER_POLICY);
788     if (!isPropertySupported(prop)) {
789         return Error() << StringPrintf("Vehicle property(%d) is not supported by VHAL.", prop);
790     }
791     std::shared_ptr<IVhalClient> vhalService;
792     {
793         Mutex::Autolock lock(mMutex);
794         if (mVhalService == nullptr) {
795             return Error() << "VHAL is not ready";
796         }
797         vhalService = mVhalService;
798     }
799     std::unique_ptr<IHalPropValue> propValue = vhalService->createHalPropValue(prop);
800     propValue->setStringValue(policyId);
801 
802     VhalResult<void> result = vhalService->setValueSync(*propValue);
803     if (!result.ok()) {
804         return Error() << "Failed to set CURRENT_POWER_POLICY property";
805     }
806     ALOGD("Policy(%s) is notified to VHAL", policyId.c_str());
807     return {};
808 }
809 
isPropertySupported(const int32_t prop)810 bool CarPowerPolicyServer::isPropertySupported(const int32_t prop) {
811     if (mSupportedProperties.count(prop) > 0) {
812         return mSupportedProperties[prop];
813     }
814     StatusCode status;
815     hidl_vec<int32_t> props = {prop};
816     std::shared_ptr<IVhalClient> vhalService;
817     {
818         Mutex::Autolock lock(mMutex);
819         if (mVhalService == nullptr) {
820             ALOGW("Failed to check if property(%d) is supported: VHAL is not ready", prop);
821             return false;
822         }
823         vhalService = mVhalService;
824     }
825     auto result = vhalService->getPropConfigs(props);
826     mSupportedProperties[prop] = result.ok();
827     return mSupportedProperties[prop];
828 }
829 
isPowerPolicyAppliedLocked() const830 bool CarPowerPolicyServer::isPowerPolicyAppliedLocked() const {
831     return mCurrentPowerPolicyMeta.powerPolicy != nullptr;
832 }
833 
callbackToString(const CallbackInfo & callback)834 std::string CarPowerPolicyServer::callbackToString(const CallbackInfo& callback) {
835     const std::vector<PowerComponent>& components = callback.filter.components;
836     return StringPrintf("callback(pid %d, filter: %s)", callback.pid, toString(components).c_str());
837 }
838 
getPolicyChangeCallbacks()839 std::vector<CallbackInfo> CarPowerPolicyServer::getPolicyChangeCallbacks() {
840     Mutex::Autolock lock(mMutex);
841     return mPolicyChangeCallbacks;
842 }
843 
countOnBinderDiedContexts()844 size_t CarPowerPolicyServer::countOnBinderDiedContexts() {
845     Mutex::Autolock lock(mMutex);
846     return mOnBinderDiedContexts.size();
847 }
848 
linkToDeath(AIBinder * binder,AIBinder_DeathRecipient * recipient,void * cookie)849 binder_status_t CarPowerPolicyServer::AIBinderLinkUnlinkImpl::linkToDeath(
850         AIBinder* binder, AIBinder_DeathRecipient* recipient, void* cookie) {
851     return AIBinder_linkToDeath(binder, recipient, cookie);
852 }
853 
unlinkToDeath(AIBinder * binder,AIBinder_DeathRecipient * recipient,void * cookie)854 binder_status_t CarPowerPolicyServer::AIBinderLinkUnlinkImpl::unlinkToDeath(
855         AIBinder* binder, AIBinder_DeathRecipient* recipient, void* cookie) {
856     return AIBinder_unlinkToDeath(binder, recipient, cookie);
857 }
858 
859 }  // namespace powerpolicy
860 }  // namespace automotive
861 }  // namespace frameworks
862 }  // namespace android
863