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