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 <android_car_feature.h>
40 #include <inttypes.h>
41
42 namespace android {
43 namespace frameworks {
44 namespace automotive {
45 namespace powerpolicy {
46
47 using ::aidl::android::automotive::powerpolicy::internal::ICarPowerPolicyDelegate;
48 using ::aidl::android::automotive::powerpolicy::internal::ICarPowerPolicyDelegateCallback;
49 using ::aidl::android::automotive::powerpolicy::internal::PowerPolicyFailureReason;
50 using ::aidl::android::automotive::powerpolicy::internal::PowerPolicyInitData;
51 using ::aidl::android::frameworks::automotive::powerpolicy::CarPowerPolicy;
52 using ::aidl::android::frameworks::automotive::powerpolicy::CarPowerPolicyFilter;
53 using ::aidl::android::frameworks::automotive::powerpolicy::ICarPowerPolicyChangeCallback;
54 using ::aidl::android::frameworks::automotive::powerpolicy::PowerComponent;
55 using ::aidl::android::frameworks::automotive::powerpolicy::internal::PolicyState;
56 using ::aidl::android::hardware::automotive::vehicle::StatusCode;
57 using ::aidl::android::hardware::automotive::vehicle::SubscribeOptions;
58 using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReport;
59 using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
60
61 using ::android::defaultServiceManager;
62 using ::android::IBinder;
63 using ::android::Looper;
64 using ::android::Mutex;
65 using ::android::status_t;
66 using ::android::String16;
67 using ::android::uptimeMillis;
68 using ::android::Vector;
69 using ::android::wp;
70 using ::android::base::Error;
71 using ::android::base::Result;
72 using ::android::base::StringAppendF;
73 using ::android::base::StringPrintf;
74 using ::android::base::WriteStringToFd;
75 using ::android::car::feature::car_power_policy_refactoring;
76 using ::android::frameworks::automotive::vhal::HalPropError;
77 using ::android::frameworks::automotive::vhal::IHalPropValue;
78 using ::android::frameworks::automotive::vhal::ISubscriptionClient;
79 using ::android::frameworks::automotive::vhal::IVhalClient;
80 using ::android::frameworks::automotive::vhal::VhalClientResult;
81
82 using ::android::hardware::hidl_vec;
83 using ::android::hardware::interfacesEqual;
84 using ::android::hardware::Return;
85
86 using ::android::hidl::base::V1_0::IBase;
87 using ::ndk::ScopedAIBinder_DeathRecipient;
88 using ::ndk::ScopedAStatus;
89 using ::ndk::SharedRefBase;
90 using ::ndk::SpAIBinder;
91
92 namespace {
93
94 const int32_t MSG_CONNECT_TO_VHAL = 1; // Message to request of connecting to VHAL.
95
96 const nsecs_t kConnectionRetryIntervalNs = 200000000; // 200 milliseconds.
97 const int32_t kMaxConnectionRetry = 25; // Retry up to 5 seconds.
98
99 constexpr const char kCarServiceInterface[] = "car_service";
100 constexpr const char kCarPowerPolicyServerInterface[] =
101 "android.frameworks.automotive.powerpolicy.ICarPowerPolicyServer/default";
102 constexpr const char kCarPowerPolicySystemNotificationInterface[] =
103 "android.frameworks.automotive.powerpolicy.internal.ICarPowerPolicySystemNotification/"
104 "default";
105 constexpr const char kCarPowerPolicyDelegateInterface[] =
106 "android.automotive.powerpolicy.internal.ICarPowerPolicyDelegate/default";
107
lookupPowerPolicyChangeCallback(const std::vector<CallbackInfo> & callbacks,const AIBinder * binder)108 std::vector<CallbackInfo>::const_iterator lookupPowerPolicyChangeCallback(
109 const std::vector<CallbackInfo>& callbacks, const AIBinder* binder) {
110 for (auto it = callbacks.begin(); it != callbacks.end(); it++) {
111 if (it->binder.get() == binder) {
112 return it;
113 }
114 }
115 return callbacks.end();
116 }
117
checkSystemPermission()118 ScopedAStatus checkSystemPermission() {
119 if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
120 return ScopedAStatus::fromServiceSpecificErrorWithMessage(EX_SECURITY,
121 "Calling process does not have "
122 "proper privilege");
123 }
124 return ScopedAStatus::ok();
125 }
126
convertErrorToFailureReason(int errorCode)127 PowerPolicyFailureReason convertErrorToFailureReason(int errorCode) {
128 switch (errorCode) {
129 case EX_ILLEGAL_ARGUMENT:
130 return PowerPolicyFailureReason::POWER_POLICY_FAILURE_NOT_REGISTERED_ID;
131 default:
132 return PowerPolicyFailureReason::POWER_POLICY_FAILURE_UNKNOWN;
133 }
134 }
135
136 } // namespace
137
138 std::shared_ptr<CarPowerPolicyServer> CarPowerPolicyServer::sCarPowerPolicyServer = nullptr;
139
PropertyChangeListener(CarPowerPolicyServer * service)140 PropertyChangeListener::PropertyChangeListener(CarPowerPolicyServer* service) : mService(service) {}
141
onPropertyEvent(const std::vector<std::unique_ptr<IHalPropValue>> & values)142 void PropertyChangeListener::onPropertyEvent(
143 const std::vector<std::unique_ptr<IHalPropValue>>& values) {
144 for (const auto& value : values) {
145 const std::string stringValue = value->getStringValue();
146 int32_t propId = value->getPropId();
147 if (propId == static_cast<int32_t>(VehicleProperty::POWER_POLICY_GROUP_REQ)) {
148 const auto& ret = mService->setPowerPolicyGroupInternal(stringValue);
149 if (!ret.ok()) {
150 ALOGW("Failed to set power policy group(%s): %s", stringValue.c_str(),
151 ret.error().message().c_str());
152 }
153 } else if (propId == static_cast<int32_t>(VehicleProperty::POWER_POLICY_REQ)) {
154 const auto& ret = mService->applyPowerPolicy(stringValue,
155 /*carServiceExpected=*/false,
156 /*force=*/false);
157 if (!ret.ok()) {
158 ALOGW("Failed to apply power policy(%s): %s", stringValue.c_str(),
159 ret.error().message().c_str());
160 }
161 }
162 }
163 }
164
onPropertySetError(const std::vector<HalPropError> & errors)165 void PropertyChangeListener::onPropertySetError(
166 [[maybe_unused]] const std::vector<HalPropError>& errors) {
167 return;
168 }
169
EventHandler(CarPowerPolicyServer * service)170 EventHandler::EventHandler(CarPowerPolicyServer* service) : mService(service) {}
171
handleMessage(const Message & message)172 void EventHandler::handleMessage(const Message& message) {
173 switch (message.what) {
174 case MSG_CONNECT_TO_VHAL:
175 mService->connectToVhalHelper();
176 break;
177 default:
178 ALOGW("Unknown message: %d", message.what);
179 }
180 }
181
RequestIdHandler(CarPowerPolicyServer * service)182 RequestIdHandler::RequestIdHandler(CarPowerPolicyServer* service) : mService(service) {}
183
handleMessage(const Message & message)184 void RequestIdHandler::handleMessage(const Message& message) {
185 mService->handleApplyPowerPolicyRequest(message.what);
186 }
187
CarServiceNotificationHandler(CarPowerPolicyServer * service)188 CarServiceNotificationHandler::CarServiceNotificationHandler(CarPowerPolicyServer* service) :
189 mService(service) {}
190
terminate()191 void CarServiceNotificationHandler::terminate() {
192 Mutex::Autolock lock(mMutex);
193 mService = nullptr;
194 }
195
dump(int fd,const char ** args,uint32_t numArgs)196 binder_status_t CarServiceNotificationHandler::dump(int fd, const char** args, uint32_t numArgs) {
197 Mutex::Autolock lock(mMutex);
198 if (mService == nullptr) {
199 ALOGD("Skip dumping, CarPowerPolicyServer is ending");
200 return STATUS_OK;
201 }
202 return mService->dump(fd, args, numArgs);
203 }
204
notifyCarServiceReady(PolicyState * policyState)205 ScopedAStatus CarServiceNotificationHandler::notifyCarServiceReady(PolicyState* policyState) {
206 Mutex::Autolock lock(mMutex);
207 if (mService == nullptr) {
208 ALOGD("Skip notifying CarServiceReady, CarPowerPolicyServer is ending");
209 return ScopedAStatus::ok();
210 }
211 return mService->notifyCarServiceReady(policyState);
212 }
213
notifyPowerPolicyChange(const std::string & policyId,bool force)214 ScopedAStatus CarServiceNotificationHandler::notifyPowerPolicyChange(const std::string& policyId,
215 bool force) {
216 Mutex::Autolock lock(mMutex);
217 if (mService == nullptr) {
218 ALOGD("Skip notifying PowerPolicyChange, CarPowerPolicyServer is ending");
219 return ScopedAStatus::ok();
220 }
221 return mService->notifyPowerPolicyChange(policyId, force);
222 }
223
notifyPowerPolicyDefinition(const std::string & policyId,const std::vector<std::string> & enabledComponents,const std::vector<std::string> & disabledComponents)224 ScopedAStatus CarServiceNotificationHandler::notifyPowerPolicyDefinition(
225 const std::string& policyId, const std::vector<std::string>& enabledComponents,
226 const std::vector<std::string>& disabledComponents) {
227 Mutex::Autolock lock(mMutex);
228 if (mService == nullptr) {
229 ALOGD("Skip notifying PowerPolicyDefinition, CarPowerPolicyServer is ending");
230 return ScopedAStatus::ok();
231 }
232 return mService->notifyPowerPolicyDefinition(policyId, enabledComponents, disabledComponents);
233 }
234
CarPowerPolicyDelegate(CarPowerPolicyServer * service)235 CarPowerPolicyDelegate::CarPowerPolicyDelegate(CarPowerPolicyServer* service) : mService(service) {}
236
terminate()237 void CarPowerPolicyDelegate::terminate() {
238 Mutex::Autolock lock(mMutex);
239 mService = nullptr;
240 }
241
dump(int fd,const char ** args,uint32_t numArgs)242 binder_status_t CarPowerPolicyDelegate::dump(int fd, const char** args, uint32_t numArgs) {
243 Mutex::Autolock lock(mMutex);
244 if (mService == nullptr) {
245 ALOGD("Skip dumping, CarPowerPolicyServer is ending");
246 return STATUS_OK;
247 }
248 return mService->dump(fd, args, numArgs);
249 }
250
notifyCarServiceReady(const std::shared_ptr<ICarPowerPolicyDelegateCallback> & callback,PowerPolicyInitData * aidlReturn)251 ScopedAStatus CarPowerPolicyDelegate::notifyCarServiceReady(
252 const std::shared_ptr<ICarPowerPolicyDelegateCallback>& callback,
253 PowerPolicyInitData* aidlReturn) {
254 return runWithService(
255 [callback, aidlReturn](CarPowerPolicyServer* service) -> ScopedAStatus {
256 return service->notifyCarServiceReadyInternal(callback, aidlReturn);
257 },
258 "notifyCarServiceReady");
259 }
260
applyPowerPolicyAsync(int32_t requestId,const std::string & policyId,bool force)261 ScopedAStatus CarPowerPolicyDelegate::applyPowerPolicyAsync(int32_t requestId,
262 const std::string& policyId,
263 bool force) {
264 return runWithService(
265 [requestId, policyId, force](CarPowerPolicyServer* service) -> ScopedAStatus {
266 return service->applyPowerPolicyAsync(requestId, policyId, force);
267 },
268 "applyPowerPolicyAsync");
269 }
270
setPowerPolicyGroup(const std::string & policyGroupId)271 ScopedAStatus CarPowerPolicyDelegate::setPowerPolicyGroup(const std::string& policyGroupId) {
272 Mutex::Autolock lock(mMutex);
273 if (mService == nullptr) {
274 ALOGD("Skip setting power policy group, CarPowerPolicyServer is ending");
275 return ScopedAStatus::ok();
276 }
277 if (const auto& ret = mService->setPowerPolicyGroupInternal(policyGroupId); !ret.ok()) {
278 return ScopedAStatus::fromExceptionCodeWithMessage(ret.error().code(),
279 ret.error().message().c_str());
280 }
281 return ScopedAStatus::ok();
282 }
283
notifyPowerPolicyDefinition(const std::string & policyId,const std::vector<std::string> & enabledComponents,const std::vector<std::string> & disabledComponents)284 ScopedAStatus CarPowerPolicyDelegate::notifyPowerPolicyDefinition(
285 const std::string& policyId, const std::vector<std::string>& enabledComponents,
286 const std::vector<std::string>& disabledComponents) {
287 return runWithService(
288 [policyId, enabledComponents,
289 disabledComponents](CarPowerPolicyServer* service) -> ScopedAStatus {
290 return service->notifyPowerPolicyDefinition(policyId, enabledComponents,
291 disabledComponents);
292 },
293 "notifyPowerPolicyDefinition");
294 }
295
notifyPowerPolicyGroupDefinition(const std::string & policyGroupId,const std::vector<std::string> & powerPolicyPerState)296 ScopedAStatus CarPowerPolicyDelegate::notifyPowerPolicyGroupDefinition(
297 const std::string& policyGroupId, const std::vector<std::string>& powerPolicyPerState) {
298 return runWithService(
299 [policyGroupId, powerPolicyPerState](CarPowerPolicyServer* service) -> ScopedAStatus {
300 return service->notifyPowerPolicyGroupDefinition(policyGroupId,
301 powerPolicyPerState);
302 },
303 "notifyPowerPolicyGroupDefinition");
304 }
305
applyPowerPolicyPerPowerStateChangeAsync(int32_t requestId,ICarPowerPolicyDelegate::PowerState state)306 ScopedAStatus CarPowerPolicyDelegate::applyPowerPolicyPerPowerStateChangeAsync(
307 int32_t requestId, ICarPowerPolicyDelegate::PowerState state) {
308 return runWithService(
309 [requestId, state](CarPowerPolicyServer* service) -> ScopedAStatus {
310 return service->applyPowerPolicyPerPowerStateChangeAsync(requestId, state);
311 },
312 "applyPowerPolicyPerPowerStateChangeAsync");
313 }
314
setSilentMode(const std::string & silentMode)315 ScopedAStatus CarPowerPolicyDelegate::setSilentMode(const std::string& silentMode) {
316 return runWithService([silentMode](CarPowerPolicyServer* service)
317 -> ScopedAStatus { return service->setSilentMode(silentMode); },
318 "setSilentMode");
319 }
320
runWithService(const std::function<ScopedAStatus (CarPowerPolicyServer *)> & action,const std::string & actionTitle)321 ScopedAStatus CarPowerPolicyDelegate::runWithService(
322 const std::function<ScopedAStatus(CarPowerPolicyServer*)>& action,
323 const std::string& actionTitle) {
324 Mutex::Autolock lock(mMutex);
325 if (mService == nullptr) {
326 ALOGD("Skip %s, CarPowerPolicyServer is ending", actionTitle.c_str());
327 return ScopedAStatus::ok();
328 }
329 return action(mService);
330 }
331
~ISilentModeChangeHandler()332 ISilentModeChangeHandler::~ISilentModeChangeHandler() {}
333
startService(const sp<Looper> & looper)334 Result<std::shared_ptr<CarPowerPolicyServer>> CarPowerPolicyServer::startService(
335 const sp<Looper>& looper) {
336 if (sCarPowerPolicyServer != nullptr) {
337 return Error(INVALID_OPERATION) << "Cannot start service more than once";
338 }
339 std::shared_ptr<CarPowerPolicyServer> server = SharedRefBase::make<CarPowerPolicyServer>();
340 const auto& ret = server->init(looper);
341 if (!ret.ok()) {
342 return Error(ret.error().code())
343 << "Failed to start car power policy server: " << ret.error();
344 }
345 sCarPowerPolicyServer = server;
346
347 return sCarPowerPolicyServer;
348 }
349
terminateService()350 void CarPowerPolicyServer::terminateService() {
351 if (sCarPowerPolicyServer != nullptr) {
352 sCarPowerPolicyServer->terminate();
353 sCarPowerPolicyServer = nullptr;
354 }
355 }
356
CarPowerPolicyServer()357 CarPowerPolicyServer::CarPowerPolicyServer() :
358 mSilentModeHandler(this),
359 mIsPowerPolicyLocked(false),
360 mIsCarServiceInOperation(false),
361 mIsFirstConnectionToVhal(true) {
362 mEventHandler = new EventHandler(this);
363 mRequestIdHandler = new RequestIdHandler(this);
364 mClientDeathRecipient = ScopedAIBinder_DeathRecipient(
365 AIBinder_DeathRecipient_new(&CarPowerPolicyServer::onClientBinderDied));
366 mCarServiceDeathRecipient = ScopedAIBinder_DeathRecipient(
367 AIBinder_DeathRecipient_new(&CarPowerPolicyServer::onCarServiceBinderDied));
368 mPropertyChangeListener = std::make_unique<PropertyChangeListener>(this);
369 mLinkUnlinkImpl = std::make_unique<AIBinderLinkUnlinkImpl>();
370 }
371
372 // For test-only.
setLinkUnlinkImpl(std::unique_ptr<CarPowerPolicyServer::LinkUnlinkImpl> impl)373 void CarPowerPolicyServer::setLinkUnlinkImpl(
374 std::unique_ptr<CarPowerPolicyServer::LinkUnlinkImpl> impl) {
375 mLinkUnlinkImpl = std::move(impl);
376 }
377
getCurrentPowerPolicy(CarPowerPolicy * aidlReturn)378 ScopedAStatus CarPowerPolicyServer::getCurrentPowerPolicy(CarPowerPolicy* aidlReturn) {
379 Mutex::Autolock lock(mMutex);
380 if (!isPowerPolicyAppliedLocked()) {
381 return ScopedAStatus::
382 fromServiceSpecificErrorWithMessage(EX_ILLEGAL_STATE,
383 "The current power policy is not set");
384 }
385 *aidlReturn = *mCurrentPowerPolicyMeta.powerPolicy;
386 return ScopedAStatus::ok();
387 }
388
getPowerComponentState(PowerComponent componentId,bool * aidlReturn)389 ScopedAStatus CarPowerPolicyServer::getPowerComponentState(PowerComponent componentId,
390 bool* aidlReturn) {
391 const auto& ret = mComponentHandler.getPowerComponentState(componentId);
392 if (!ret.ok()) {
393 std::string errorMsg = ret.error().message();
394 ALOGW("getPowerComponentState(%s) failed: %s", toString(componentId).c_str(),
395 errorMsg.c_str());
396 return ScopedAStatus::fromServiceSpecificErrorWithMessage(EX_ILLEGAL_ARGUMENT,
397 errorMsg.c_str());
398 }
399 *aidlReturn = *ret;
400 return ScopedAStatus::ok();
401 }
402
registerPowerPolicyChangeCallback(const std::shared_ptr<ICarPowerPolicyChangeCallback> & callback,const CarPowerPolicyFilter & filter)403 ScopedAStatus CarPowerPolicyServer::registerPowerPolicyChangeCallback(
404 const std::shared_ptr<ICarPowerPolicyChangeCallback>& callback,
405 const CarPowerPolicyFilter& filter) {
406 if (callback == nullptr) {
407 std::string errorMsg = "Cannot register a null callback";
408 ALOGW("%s", errorMsg.c_str());
409 return ScopedAStatus::fromServiceSpecificErrorWithMessage(EX_ILLEGAL_ARGUMENT,
410 errorMsg.c_str());
411 }
412 Mutex::Autolock lock(mMutex);
413 pid_t callingPid = IPCThreadState::self()->getCallingPid();
414 uid_t callingUid = IPCThreadState::self()->getCallingUid();
415 SpAIBinder binder = callback->asBinder();
416 AIBinder* clientId = binder.get();
417 if (isRegisteredLocked(clientId)) {
418 std::string errorStr = StringPrintf("The callback(pid: %d, uid: %d) is already registered.",
419 callingPid, callingUid);
420 const char* errorCause = errorStr.c_str();
421 ALOGW("Cannot register a callback: %s", errorCause);
422 return ScopedAStatus::fromServiceSpecificErrorWithMessage(EX_ILLEGAL_ARGUMENT, errorCause);
423 }
424
425 std::unique_ptr<OnClientBinderDiedContext> context =
426 std::make_unique<OnClientBinderDiedContext>(
427 OnClientBinderDiedContext{.server = this, .clientId = clientId});
428 binder_status_t status = mLinkUnlinkImpl->linkToDeath(clientId, mClientDeathRecipient.get(),
429 static_cast<void*>(context.get()));
430 if (status != STATUS_OK) {
431 std::string errorStr = StringPrintf("The given callback(pid: %d, uid: %d) is dead",
432 callingPid, callingUid);
433 const char* errorCause = errorStr.c_str();
434 ALOGW("Cannot register a callback: %s", errorCause);
435 return ScopedAStatus::fromServiceSpecificErrorWithMessage(EX_ILLEGAL_STATE, errorCause);
436 }
437 // Insert into a map to keep the context object alive.
438 mOnClientBinderDiedContexts[clientId] = std::move(context);
439 mPolicyChangeCallbacks.emplace_back(binder, filter, callingPid);
440
441 if (DEBUG) {
442 ALOGD("Power policy change callback(pid: %d, filter: %s) is registered", callingPid,
443 toString(filter.components).c_str());
444 }
445 return ScopedAStatus::ok();
446 }
447
unregisterPowerPolicyChangeCallback(const std::shared_ptr<ICarPowerPolicyChangeCallback> & callback)448 ScopedAStatus CarPowerPolicyServer::unregisterPowerPolicyChangeCallback(
449 const std::shared_ptr<ICarPowerPolicyChangeCallback>& callback) {
450 Mutex::Autolock lock(mMutex);
451 pid_t callingPid = IPCThreadState::self()->getCallingPid();
452 uid_t callingUid = IPCThreadState::self()->getCallingUid();
453 if (callback == nullptr) {
454 std::string errorMsg = "Cannot unregister a null callback";
455 ALOGW("%s", errorMsg.c_str());
456 return ScopedAStatus::fromServiceSpecificErrorWithMessage(EX_ILLEGAL_ARGUMENT,
457 errorMsg.c_str());
458 }
459 AIBinder* clientId = callback->asBinder().get();
460 auto it = lookupPowerPolicyChangeCallback(mPolicyChangeCallbacks, clientId);
461 if (it == mPolicyChangeCallbacks.end()) {
462 std::string errorStr =
463 StringPrintf("The callback(pid: %d, uid: %d) has not been registered", callingPid,
464 callingUid);
465 const char* errorCause = errorStr.c_str();
466 ALOGW("Cannot unregister a callback: %s", errorCause);
467 return ScopedAStatus::fromServiceSpecificErrorWithMessage(EX_ILLEGAL_ARGUMENT, errorCause);
468 }
469 if (mOnClientBinderDiedContexts.find(clientId) != mOnClientBinderDiedContexts.end()) {
470 // We don't set a callback for unlinkToDeath but need to call unlinkToDeath to clean up the
471 // registered death recipient.
472 mLinkUnlinkImpl->unlinkToDeath(clientId, mClientDeathRecipient.get(),
473 static_cast<void*>(
474 mOnClientBinderDiedContexts[clientId].get()));
475 mOnClientBinderDiedContexts.erase(clientId);
476 }
477 mPolicyChangeCallbacks.erase(it);
478 if (DEBUG) {
479 ALOGD("Power policy change callback(pid: %d, uid: %d) is unregistered", callingPid,
480 callingUid);
481 }
482 return ScopedAStatus::ok();
483 }
484
applyPowerPolicy(const std::string & policyId)485 ScopedAStatus CarPowerPolicyServer::applyPowerPolicy(const std::string& policyId) {
486 if (!car_power_policy_refactoring()) {
487 ALOGE("Cannot execute applyPowerPolicy: car_power_policy_refactoring flag is not enabled");
488 return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
489 }
490 if (const auto& ret =
491 applyPowerPolicyInternal(policyId, /*force=*/false, /*notifyCarService=*/true);
492 !ret.ok()) {
493 return ScopedAStatus::fromExceptionCodeWithMessage(ret.error().code(),
494 ret.error().message().c_str());
495 }
496 return ScopedAStatus::ok();
497 }
498
setPowerPolicyGroup(const std::string & policyGroupId)499 ScopedAStatus CarPowerPolicyServer::setPowerPolicyGroup(const std::string& policyGroupId) {
500 if (!car_power_policy_refactoring()) {
501 ALOGE("Cannot execute setPowerPolicyGroup: car_power_policy_refactoring flag is not "
502 "enabled");
503 return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
504 }
505 if (const auto& ret = setPowerPolicyGroupInternal(policyGroupId); !ret.ok()) {
506 return ScopedAStatus::fromExceptionCodeWithMessage(ret.error().code(),
507 ret.error().message().c_str());
508 }
509 return ScopedAStatus::ok();
510 }
511
notifyCarServiceReady(PolicyState * policyState)512 ScopedAStatus CarPowerPolicyServer::notifyCarServiceReady(PolicyState* policyState) {
513 ScopedAStatus status = checkSystemPermission();
514 if (!status.isOk()) {
515 return status;
516 }
517 mSilentModeHandler.stopMonitoringSilentModeHwState();
518 Mutex::Autolock lock(mMutex);
519 policyState->policyId =
520 isPowerPolicyAppliedLocked() ? mCurrentPowerPolicyMeta.powerPolicy->policyId : "";
521 policyState->policyGroupId = mCurrentPolicyGroupId;
522 mIsCarServiceInOperation = true;
523 ALOGI("CarService is now responsible for power policy management");
524 return ScopedAStatus::ok();
525 }
526
notifyPowerPolicyChange(const std::string & policyId,bool force)527 ScopedAStatus CarPowerPolicyServer::notifyPowerPolicyChange(const std::string& policyId,
528 bool force) {
529 ScopedAStatus status = checkSystemPermission();
530 if (!status.isOk()) {
531 return status;
532 }
533 const auto& ret = applyPowerPolicy(policyId, /*carServiceExpected=*/true, force);
534 if (!ret.ok()) {
535 return ScopedAStatus::
536 fromServiceSpecificErrorWithMessage(EX_ILLEGAL_STATE,
537 StringPrintf("Failed to notify power policy "
538 "change: %s",
539 ret.error().message().c_str())
540 .c_str());
541 }
542 ALOGD("Policy change(%s) is notified by CarService", policyId.c_str());
543 return ScopedAStatus::ok();
544 }
545
notifyPowerPolicyDefinition(const std::string & policyId,const std::vector<std::string> & enabledComponents,const std::vector<std::string> & disabledComponents)546 ScopedAStatus CarPowerPolicyServer::notifyPowerPolicyDefinition(
547 const std::string& policyId, const std::vector<std::string>& enabledComponents,
548 const std::vector<std::string>& disabledComponents) {
549 ScopedAStatus status = checkSystemPermission();
550 if (!status.isOk()) {
551 return status;
552 }
553 const auto& ret =
554 mPolicyManager.definePowerPolicy(policyId, enabledComponents, disabledComponents);
555 if (!ret.ok()) {
556 return ScopedAStatus::
557 fromServiceSpecificErrorWithMessage(EX_ILLEGAL_ARGUMENT,
558 StringPrintf("Failed to notify power policy "
559 "definition: %s",
560 ret.error().message().c_str())
561 .c_str());
562 }
563 return ScopedAStatus::ok();
564 }
565
notifyPowerPolicyGroupDefinition(const std::string & policyGroupId,const std::vector<std::string> & powerPolicyPerState)566 ScopedAStatus CarPowerPolicyServer::notifyPowerPolicyGroupDefinition(
567 const std::string& policyGroupId, const std::vector<std::string>& powerPolicyPerState) {
568 ScopedAStatus status = checkSystemPermission();
569 if (!status.isOk()) {
570 return status;
571 }
572 const auto& ret = mPolicyManager.definePowerPolicyGroup(policyGroupId, powerPolicyPerState);
573 if (!ret.ok()) {
574 return ScopedAStatus::
575 fromServiceSpecificErrorWithMessage(EX_ILLEGAL_ARGUMENT,
576 StringPrintf("Failed to notify power policy "
577 "group definition: %s",
578 ret.error().message().c_str())
579 .c_str());
580 }
581 return ScopedAStatus::ok();
582 }
583
applyPowerPolicyPerPowerStateChangeAsync(int32_t requestId,ICarPowerPolicyDelegate::PowerState state)584 ScopedAStatus CarPowerPolicyServer::applyPowerPolicyPerPowerStateChangeAsync(
585 int32_t requestId, ICarPowerPolicyDelegate::PowerState state) {
586 ScopedAStatus status = checkSystemPermission();
587 if (!status.isOk()) {
588 return status;
589 }
590 VehicleApPowerStateReport apPowerState;
591 std::string defaultPowerPolicyId;
592 // TODO(b/318520417): Power policy should be updated according to SilentMode.
593 // TODO(b/321319532): Create a map for default power policy in PolicyManager.
594 switch (state) {
595 case ICarPowerPolicyDelegate::PowerState::WAIT_FOR_VHAL:
596 apPowerState = VehicleApPowerStateReport::WAIT_FOR_VHAL;
597 defaultPowerPolicyId = kSystemPolicyIdInitialOn;
598 break;
599 case ICarPowerPolicyDelegate::PowerState::ON:
600 apPowerState = VehicleApPowerStateReport::ON;
601 defaultPowerPolicyId = kSystemPolicyIdAllOn;
602 break;
603 default:
604 return ScopedAStatus::
605 fromServiceSpecificErrorWithMessage(EX_ILLEGAL_ARGUMENT,
606 StringPrintf("Power policy cannot be "
607 "changed for power state(%d)",
608 static_cast<int32_t>(state))
609 .c_str());
610 }
611 std::string powerStateName = toString(apPowerState);
612 ALOGI("Power policy change for new power state(%s) is requested", powerStateName.c_str());
613 std::string currentPolicyGroupId;
614 {
615 Mutex::Autolock lock(mMutex);
616 currentPolicyGroupId = mCurrentPolicyGroupId;
617 }
618 const auto& policy =
619 mPolicyManager.getDefaultPowerPolicyForState(currentPolicyGroupId, apPowerState);
620 std::string policyId;
621 if (policy.ok()) {
622 policyId = (*policy)->policyId;
623 ALOGI("Vendor-configured policy(%s) is about to be applied for power state(%s)",
624 policyId.c_str(), powerStateName.c_str());
625 } else {
626 policyId = defaultPowerPolicyId;
627 ALOGI("Default policy(%s) is about to be applied for power state(%s)", policyId.c_str(),
628 powerStateName.c_str());
629 }
630
631 const bool useForce = !mSilentModeHandler.isSilentMode();
632
633 if (auto ret = enqueuePowerPolicyRequest(requestId, policyId, useForce); !ret.isOk()) {
634 ALOGW("Failed to apply power policy(%s) for power state(%s) with request ID(%d)",
635 policyId.c_str(), powerStateName.c_str(), requestId);
636 return ret;
637 }
638 return ScopedAStatus::ok();
639 }
640
setSilentMode(const std::string & silentMode)641 ScopedAStatus CarPowerPolicyServer::setSilentMode(const std::string& silentMode) {
642 ScopedAStatus status = checkSystemPermission();
643 if (!status.isOk()) {
644 return status;
645 }
646 if (auto ret = mSilentModeHandler.setSilentMode(silentMode); !ret.isOk()) {
647 ALOGW("Failed to set Silent Mode(%s)", silentMode.c_str());
648 return ret;
649 }
650 return ScopedAStatus::ok();
651 }
652
applyPowerPolicyAsync(int32_t requestId,const std::string & policyId,bool force)653 ScopedAStatus CarPowerPolicyServer::applyPowerPolicyAsync(int32_t requestId,
654 const std::string& policyId, bool force) {
655 ScopedAStatus status = checkSystemPermission();
656 if (!status.isOk()) {
657 return status;
658 }
659 if (auto ret = enqueuePowerPolicyRequest(requestId, policyId, force); !ret.isOk()) {
660 ALOGW("Failed to apply power policy(%s) with request ID(%d)", policyId.c_str(), requestId);
661 return ret;
662 }
663 return ScopedAStatus::ok();
664 }
665
enqueuePowerPolicyRequest(int32_t requestId,const std::string & policyId,bool force)666 ScopedAStatus CarPowerPolicyServer::enqueuePowerPolicyRequest(int32_t requestId,
667 const std::string& policyId,
668 bool force) {
669 Mutex::Autolock lock(mMutex);
670 if (mPolicyRequestById.count(requestId) > 0) {
671 return ScopedAStatus::
672 fromServiceSpecificErrorWithMessage(EX_ILLEGAL_ARGUMENT,
673 StringPrintf("Duplicated request ID(%d)",
674 requestId)
675 .c_str());
676 }
677 mPolicyRequestById[requestId] = PolicyRequest{.policyId = policyId, .force = force};
678 ALOGI("Queueing request ID(%d) for applying power policy(%s): force=%s", requestId,
679 policyId.c_str(), force ? "true" : "false");
680 mHandlerLooper->sendMessage(mRequestIdHandler, requestId);
681 return ScopedAStatus::ok();
682 }
683
notifyCarServiceReadyInternal(const std::shared_ptr<ICarPowerPolicyDelegateCallback> & callback,PowerPolicyInitData * aidlReturn)684 ScopedAStatus CarPowerPolicyServer::notifyCarServiceReadyInternal(
685 const std::shared_ptr<ICarPowerPolicyDelegateCallback>& callback,
686 PowerPolicyInitData* aidlReturn) {
687 ScopedAStatus status = checkSystemPermission();
688 if (!status.isOk()) {
689 return status;
690 }
691 if (callback == nullptr) {
692 std::string errorMsg = "Cannot register a null callback for notifyCarServiceReadyInternal";
693 ALOGW("%s", errorMsg.c_str());
694 return ScopedAStatus::fromServiceSpecificErrorWithMessage(EX_ILLEGAL_ARGUMENT,
695 errorMsg.c_str());
696 }
697 Mutex::Autolock lock(mMutex);
698 // Override with the newer callback.
699 mPowerPolicyDelegateCallback = callback->asBinder();
700 binder_status_t linkStatus =
701 mLinkUnlinkImpl->linkToDeath(mPowerPolicyDelegateCallback.get(),
702 mCarServiceDeathRecipient.get(), static_cast<void*>(this));
703 if (linkStatus != STATUS_OK) {
704 pid_t callingPid = IPCThreadState::self()->getCallingPid();
705 uid_t callingUid = IPCThreadState::self()->getCallingUid();
706 std::string errorStr =
707 StringPrintf("CarService(pid: %d, uid: %d) is dead", callingPid, callingUid);
708 const char* errorCause = errorStr.c_str();
709 ALOGW("Cannot handle notifyCarServiceReady: %s", errorCause);
710 return ScopedAStatus::fromServiceSpecificErrorWithMessage(EX_ILLEGAL_STATE, errorCause);
711 }
712
713 aidlReturn->registeredCustomComponents = std::move(mPolicyManager.getCustomComponents());
714 aidlReturn->currentPowerPolicy = *mCurrentPowerPolicyMeta.powerPolicy;
715 aidlReturn->registeredPolicies = std::move(mPolicyManager.getRegisteredPolicies());
716 ALOGI("CarService registers ICarPowerPolicyDelegateCallback");
717 return ScopedAStatus::ok();
718 }
719
dump(int fd,const char ** args,uint32_t numArgs)720 status_t CarPowerPolicyServer::dump(int fd, const char** args, uint32_t numArgs) {
721 Vector<String16> argsV;
722 for (size_t i = 0; i < numArgs; i++) {
723 argsV.push(String16(args[i]));
724 }
725
726 {
727 Mutex::Autolock lock(mMutex);
728 const char* indent = " ";
729 const char* doubleIndent = " ";
730 WriteStringToFd("CAR POWER POLICY DAEMON\n", fd);
731 WriteStringToFd(StringPrintf("%sCarService is in operation: %s\n", indent,
732 mIsCarServiceInOperation ? "true" : "false"),
733 fd);
734 WriteStringToFd(StringPrintf("%sConnection to VHAL: %s\n", indent,
735 mVhalService.get() ? "connected" : "disconnected"),
736 fd);
737 WriteStringToFd(StringPrintf("%sCurrent power policy: %s\n", indent,
738 isPowerPolicyAppliedLocked()
739 ? mCurrentPowerPolicyMeta.powerPolicy->policyId.c_str()
740 : "not set"),
741 fd);
742 WriteStringToFd(StringPrintf("%sLast uptime of applying power policy: %" PRId64 "ms\n",
743 indent, mLastApplyPowerPolicyUptimeMs.value_or(-1)),
744 fd);
745 WriteStringToFd(StringPrintf("%sPending power policy ID: %s\n", indent,
746 mPendingPowerPolicyId.c_str()),
747 fd);
748 WriteStringToFd(StringPrintf("%sCurrent power policy group ID: %s\n", indent,
749 mCurrentPolicyGroupId.empty() ? "not set"
750 : mCurrentPolicyGroupId.c_str()),
751 fd);
752 WriteStringToFd(StringPrintf("%sLast uptime of setting default power policy group: "
753 "%" PRId64 "ms\n",
754 indent, mLastSetDefaultPowerPolicyGroupUptimeMs.value_or(-1)),
755 fd);
756 WriteStringToFd(StringPrintf("%sPolicy change callbacks:%s\n", indent,
757 mPolicyChangeCallbacks.size() ? "" : " none"),
758 fd);
759 for (auto& callback : mPolicyChangeCallbacks) {
760 WriteStringToFd(StringPrintf("%s- %s\n", doubleIndent,
761 callbackToString(callback).c_str()),
762 fd);
763 }
764 }
765 if (const auto& ret = mPolicyManager.dump(fd, argsV); !ret.ok()) {
766 ALOGW("Failed to dump power policy handler: %s", ret.error().message().c_str());
767 return ret.error().code();
768 }
769 if (const auto& ret = mComponentHandler.dump(fd); !ret.ok()) {
770 ALOGW("Failed to dump power component handler: %s", ret.error().message().c_str());
771 return ret.error().code();
772 }
773 if (const auto& ret = mSilentModeHandler.dump(fd, argsV); !ret.ok()) {
774 ALOGW("Failed to dump Silent Mode handler: %s", ret.error().message().c_str());
775 return ret.error().code();
776 }
777 return OK;
778 }
779
init(const sp<Looper> & looper)780 Result<void> CarPowerPolicyServer::init(const sp<Looper>& looper) {
781 AIBinder* binderCarService = AServiceManager_checkService(kCarServiceInterface);
782 {
783 Mutex::Autolock lock(mMutex);
784 // Before initializing power policy daemon, we need to update mIsCarServiceInOperation
785 // according to whether CPMS is running.
786 mIsCarServiceInOperation = binderCarService != nullptr;
787 }
788 mHandlerLooper = looper;
789 mPolicyManager.init();
790 mComponentHandler.init();
791 mSilentModeHandler.init();
792
793 binder_exception_t err =
794 AServiceManager_addService(this->asBinder().get(), kCarPowerPolicyServerInterface);
795 if (err != EX_NONE) {
796 return Error(err) << "Failed to add carpowerpolicyd to ServiceManager";
797 }
798
799 if (car_power_policy_refactoring()) {
800 ALOGI("Registering ICarPowerPolicyDelegate");
801 mCarPowerPolicyDelegate = SharedRefBase::make<CarPowerPolicyDelegate>(this);
802 if (err = AServiceManager_addService(mCarPowerPolicyDelegate->asBinder().get(),
803 kCarPowerPolicyDelegateInterface);
804 err != EX_NONE) {
805 return Error(err) << "Failed to add car power policy delegate to ServiceManager";
806 }
807 } else {
808 mCarServiceNotificationHandler = SharedRefBase::make<CarServiceNotificationHandler>(this);
809 if (err = AServiceManager_addService(mCarServiceNotificationHandler->asBinder().get(),
810 kCarPowerPolicySystemNotificationInterface);
811 err != EX_NONE) {
812 return Error(err)
813 << "Failed to add car power policy system notification to ServiceManager";
814 }
815 }
816
817 connectToVhal();
818 return {};
819 }
820
terminate()821 void CarPowerPolicyServer::terminate() {
822 Mutex::Autolock lock(mMutex);
823 mPolicyChangeCallbacks.clear();
824 if (mVhalService != nullptr) {
825 mSubscriptionClient->unsubscribe(
826 {static_cast<int32_t>(VehicleProperty::POWER_POLICY_REQ),
827 static_cast<int32_t>(VehicleProperty::POWER_POLICY_GROUP_REQ)});
828 }
829
830 if (car_power_policy_refactoring()) {
831 if (mCarPowerPolicyDelegate != nullptr) {
832 mCarPowerPolicyDelegate->terminate();
833 mCarPowerPolicyDelegate = nullptr;
834 }
835 } else {
836 if (mCarServiceNotificationHandler != nullptr) {
837 mCarServiceNotificationHandler->terminate();
838 mCarServiceNotificationHandler = nullptr;
839 }
840 }
841
842 // Delete the deathRecipient so that all binders would be unlinked.
843 mClientDeathRecipient = ScopedAIBinder_DeathRecipient();
844 mSilentModeHandler.release();
845 // Remove the messages so that mEventHandler and mRequestIdHandler would no longer be used.
846 mHandlerLooper->removeMessages(mEventHandler);
847 mHandlerLooper->removeMessages(mRequestIdHandler);
848 }
849
onClientBinderDied(void * cookie)850 void CarPowerPolicyServer::onClientBinderDied(void* cookie) {
851 OnClientBinderDiedContext* context = static_cast<OnClientBinderDiedContext*>(cookie);
852 context->server->handleClientBinderDeath(context->clientId);
853 }
854
onCarServiceBinderDied(void * cookie)855 void CarPowerPolicyServer::onCarServiceBinderDied(void* cookie) {
856 CarPowerPolicyServer* server = static_cast<CarPowerPolicyServer*>(cookie);
857 server->handleCarServiceBinderDeath();
858 }
859
handleClientBinderDeath(const AIBinder * clientId)860 void CarPowerPolicyServer::handleClientBinderDeath(const AIBinder* clientId) {
861 Mutex::Autolock lock(mMutex);
862 auto it = lookupPowerPolicyChangeCallback(mPolicyChangeCallbacks, clientId);
863 if (it != mPolicyChangeCallbacks.end()) {
864 ALOGW("Power policy callback(pid: %d) died", it->pid);
865 mPolicyChangeCallbacks.erase(it);
866 }
867 mOnClientBinderDiedContexts.erase(clientId);
868 }
869
handleCarServiceBinderDeath()870 void CarPowerPolicyServer::handleCarServiceBinderDeath() {
871 Mutex::Autolock lock(mMutex);
872 mPowerPolicyDelegateCallback = nullptr;
873 }
874
handleVhalDeath()875 void CarPowerPolicyServer::handleVhalDeath() {
876 {
877 Mutex::Autolock lock(mMutex);
878 ALOGW("VHAL has died.");
879 mVhalService = nullptr;
880 }
881 connectToVhal();
882 }
883
handleApplyPowerPolicyRequest(const int32_t requestId)884 void CarPowerPolicyServer::handleApplyPowerPolicyRequest(const int32_t requestId) {
885 ALOGI("Handling request ID(%d) to apply power policy", requestId);
886 PolicyRequest policyRequest;
887 std::shared_ptr<ICarPowerPolicyDelegateCallback> callback;
888 {
889 Mutex::Autolock lock(mMutex);
890 if (mPolicyRequestById.count(requestId) == 0) {
891 ALOGW("Request ID(%d) for applying power policy is not found", requestId);
892 return;
893 }
894 policyRequest = mPolicyRequestById[requestId];
895 mPolicyRequestById.erase(requestId);
896 callback = ICarPowerPolicyDelegateCallback::fromBinder(mPowerPolicyDelegateCallback);
897 if (callback == nullptr) {
898 ALOGW("ICarPowerPolicyDelegateCallback is not set");
899 }
900 }
901 if (const auto& ret = applyPowerPolicyInternal(policyRequest.policyId, policyRequest.force,
902 /*notifyCarService=*/false);
903 !ret.ok()) {
904 ALOGW("%s", ret.error().message().c_str());
905 if (callback != nullptr) {
906 callback->onApplyPowerPolicyFailed(requestId,
907 convertErrorToFailureReason(ret.error().code()));
908 }
909 return;
910 } else if (callback != nullptr) {
911 callback->onApplyPowerPolicySucceeded(requestId, *mComponentHandler.getAccumulatedPolicy(),
912 !*ret);
913 }
914 }
915
applyPowerPolicy(const std::string & policyId,const bool carServiceInOperation,const bool force)916 Result<void> CarPowerPolicyServer::applyPowerPolicy(const std::string& policyId,
917 const bool carServiceInOperation,
918 const bool force) {
919 auto policyMeta = mPolicyManager.getPowerPolicy(policyId);
920 if (!policyMeta.ok()) {
921 return Error() << "Failed to apply power policy: " << policyMeta.error().message();
922 }
923
924 std::vector<CallbackInfo> clients;
925 if (Mutex::Autolock lock(mMutex); mIsCarServiceInOperation != carServiceInOperation) {
926 return Error() << (mIsCarServiceInOperation
927 ? "After CarService starts serving, power policy cannot be "
928 "managed in car power policy daemon"
929 : "Before CarService starts serving, power policy cannot be "
930 "applied from CarService");
931 } else {
932 if (!canApplyPowerPolicyLocked(*policyMeta, force, /*out*/ clients)) {
933 return {};
934 }
935 }
936 applyAndNotifyPowerPolicy(*policyMeta, clients, /*notifyCarService=*/false);
937 return {};
938 }
939
canApplyPowerPolicyLocked(const CarPowerPolicyMeta & policyMeta,const bool force,std::vector<CallbackInfo> & outClients)940 bool CarPowerPolicyServer::canApplyPowerPolicyLocked(const CarPowerPolicyMeta& policyMeta,
941 const bool force,
942 std::vector<CallbackInfo>& outClients) {
943 const std::string& policyId = policyMeta.powerPolicy->policyId;
944 bool isPolicyApplied = isPowerPolicyAppliedLocked();
945 if (isPolicyApplied && mCurrentPowerPolicyMeta.powerPolicy->policyId == policyId) {
946 ALOGI("Applying policy skipped: the given policy(ID: %s) is the current policy",
947 policyId.c_str());
948 return false;
949 }
950 if (policyMeta.isPreemptive) {
951 if (isPolicyApplied && !mCurrentPowerPolicyMeta.isPreemptive) {
952 mPendingPowerPolicyId = mCurrentPowerPolicyMeta.powerPolicy->policyId;
953 }
954 mIsPowerPolicyLocked = true;
955 } else {
956 if (force) {
957 mPendingPowerPolicyId.clear();
958 mIsPowerPolicyLocked = false;
959 } else if (mIsPowerPolicyLocked) {
960 ALOGI("%s is queued and will be applied after power policy get unlocked",
961 policyId.c_str());
962 mPendingPowerPolicyId = policyId;
963 return false;
964 }
965 }
966 mCurrentPowerPolicyMeta = policyMeta;
967 outClients = mPolicyChangeCallbacks;
968 mLastApplyPowerPolicyUptimeMs = uptimeMillis();
969 ALOGD("CurrentPowerPolicyMeta is updated to %s", policyId.c_str());
970 return true;
971 }
972
applyAndNotifyPowerPolicy(const CarPowerPolicyMeta & policyMeta,const std::vector<CallbackInfo> & clients,const bool notifyCarService)973 void CarPowerPolicyServer::applyAndNotifyPowerPolicy(const CarPowerPolicyMeta& policyMeta,
974 const std::vector<CallbackInfo>& clients,
975 const bool notifyCarService) {
976 CarPowerPolicyPtr policy = policyMeta.powerPolicy;
977 const std::string& policyId = policy->policyId;
978 mComponentHandler.applyPowerPolicy(policy);
979
980 std::shared_ptr<ICarPowerPolicyDelegateCallback> callback = nullptr;
981 if (car_power_policy_refactoring()) {
982 {
983 Mutex::Autolock lock(mMutex);
984 callback = ICarPowerPolicyDelegateCallback::fromBinder(mPowerPolicyDelegateCallback);
985 }
986 if (callback != nullptr) {
987 ALOGD("Asking CPMS to update power components for policy(%s)", policyId.c_str());
988 callback->updatePowerComponents(*policy);
989 } else {
990 ALOGW("CarService isn't ready to update power components for policy(%s)",
991 policyId.c_str());
992 }
993 }
994
995 if (const auto& ret = notifyVhalNewPowerPolicy(policy->policyId); !ret.ok()) {
996 ALOGW("Failed to tell VHAL the new power policy(%s): %s", policy->policyId.c_str(),
997 ret.error().message().c_str());
998 }
999 auto accumulatedPolicy = mComponentHandler.getAccumulatedPolicy();
1000 for (auto client : clients) {
1001 ICarPowerPolicyChangeCallback::fromBinder(client.binder)
1002 ->onPolicyChanged(*accumulatedPolicy);
1003 }
1004 if (notifyCarService && callback != nullptr) {
1005 callback->onPowerPolicyChanged(*accumulatedPolicy);
1006 }
1007 ALOGI("The current power policy is %s", policyId.c_str());
1008 }
1009
applyPowerPolicyInternal(const std::string & policyId,const bool force,const bool notifyCarService)1010 Result<bool> CarPowerPolicyServer::applyPowerPolicyInternal(const std::string& policyId,
1011 const bool force,
1012 const bool notifyCarService) {
1013 auto policyMeta = mPolicyManager.getPowerPolicy(policyId);
1014 if (!policyMeta.ok()) {
1015 return Error(EX_ILLEGAL_ARGUMENT)
1016 << "Failed to apply power policy: " << policyMeta.error().message();
1017 }
1018 std::vector<CallbackInfo> clients;
1019 {
1020 Mutex::Autolock lock(mMutex);
1021 if (!canApplyPowerPolicyLocked(*policyMeta, force, /*out*/ clients)) {
1022 return false;
1023 }
1024 }
1025 applyAndNotifyPowerPolicy(*policyMeta, clients, notifyCarService);
1026 return true;
1027 }
1028
setPowerPolicyGroupInternal(const std::string & groupId)1029 Result<void> CarPowerPolicyServer::setPowerPolicyGroupInternal(const std::string& groupId) {
1030 if (!mPolicyManager.isPowerPolicyGroupAvailable(groupId)) {
1031 return Error(EX_ILLEGAL_ARGUMENT)
1032 << StringPrintf("Power policy group(%s) is not available", groupId.c_str());
1033 }
1034 Mutex::Autolock lock(mMutex);
1035 if (!car_power_policy_refactoring() && mIsCarServiceInOperation) {
1036 return Error(EX_ILLEGAL_STATE) << "After CarService starts serving, power policy group "
1037 "cannot be set in car power policy daemon";
1038 }
1039 mCurrentPolicyGroupId = groupId;
1040 ALOGI("The current power policy group is |%s|", groupId.c_str());
1041 return {};
1042 }
1043
notifySilentModeChange(const bool isSilent)1044 void CarPowerPolicyServer::notifySilentModeChange(const bool isSilent) {
1045 if (car_power_policy_refactoring()) {
1046 notifySilentModeChangeInternal(isSilent);
1047 } else {
1048 notifySilentModeChangeLegacy(isSilent);
1049 }
1050 }
1051
notifySilentModeChangeLegacy(const bool isSilent)1052 void CarPowerPolicyServer::notifySilentModeChangeLegacy(const bool isSilent) {
1053 std::string pendingPowerPolicyId;
1054 if (Mutex::Autolock lock(mMutex); mIsCarServiceInOperation) {
1055 return;
1056 } else {
1057 pendingPowerPolicyId = mPendingPowerPolicyId;
1058 }
1059 ALOGI("Silent Mode is set to %s", isSilent ? "silent" : "non-silent");
1060 Result<void> ret;
1061 if (isSilent) {
1062 ret = applyPowerPolicy(kSystemPolicyIdNoUserInteraction,
1063 /*carServiceExpected=*/false, /*force=*/false);
1064 } else {
1065 ret = applyPowerPolicy(pendingPowerPolicyId,
1066 /*carServiceExpected=*/false, /*force=*/true);
1067 }
1068 if (!ret.ok()) {
1069 ALOGW("Failed to apply power policy: %s", ret.error().message().c_str());
1070 }
1071 }
1072
notifySilentModeChangeInternal(const bool isSilent)1073 void CarPowerPolicyServer::notifySilentModeChangeInternal(const bool isSilent) {
1074 std::string pendingPowerPolicyId;
1075 {
1076 Mutex::Autolock lock(mMutex);
1077 pendingPowerPolicyId = mPendingPowerPolicyId;
1078 }
1079 ALOGI("Silent Mode is set to %s", isSilent ? "silent" : "non-silent");
1080 Result<bool> ret;
1081 if (isSilent) {
1082 ret = applyPowerPolicyInternal(kSystemPolicyIdNoUserInteraction, /*force=*/false,
1083 /*notifyCarService=*/true);
1084 } else {
1085 ret = applyPowerPolicyInternal(pendingPowerPolicyId, /*force=*/true,
1086 /*notifyCarService=*/true);
1087 }
1088 if (!ret.ok()) {
1089 ALOGW("Failed to apply power policy: %s", ret.error().message().c_str());
1090 }
1091 }
1092
isRegisteredLocked(const AIBinder * binder)1093 bool CarPowerPolicyServer::isRegisteredLocked(const AIBinder* binder) {
1094 return lookupPowerPolicyChangeCallback(mPolicyChangeCallbacks, binder) !=
1095 mPolicyChangeCallbacks.end();
1096 }
1097
1098 // This method ensures that the attempt to connect to VHAL occurs in the main thread.
connectToVhal()1099 void CarPowerPolicyServer::connectToVhal() {
1100 mRemainingConnectionRetryCount = kMaxConnectionRetry;
1101 mHandlerLooper->sendMessage(mEventHandler, MSG_CONNECT_TO_VHAL);
1102 }
1103
1104 // connectToVhalHelper is always executed in the main thread.
connectToVhalHelper()1105 void CarPowerPolicyServer::connectToVhalHelper() {
1106 {
1107 Mutex::Autolock lock(mMutex);
1108 if (mVhalService != nullptr) {
1109 return;
1110 }
1111 }
1112 std::shared_ptr<IVhalClient> vhalService = IVhalClient::tryCreate();
1113 if (vhalService == nullptr) {
1114 ALOGW("Failed to connect to VHAL. Retrying in %" PRId64 " ms.",
1115 nanoseconds_to_milliseconds(kConnectionRetryIntervalNs));
1116 mRemainingConnectionRetryCount--;
1117 if (mRemainingConnectionRetryCount <= 0) {
1118 ALOGE("Failed to connect to VHAL after %d attempt%s. Gave up.", kMaxConnectionRetry,
1119 kMaxConnectionRetry > 1 ? "s" : "");
1120 return;
1121 }
1122 mHandlerLooper->sendMessageDelayed(kConnectionRetryIntervalNs, mEventHandler,
1123 MSG_CONNECT_TO_VHAL);
1124 return;
1125 }
1126 vhalService->addOnBinderDiedCallback(
1127 std::make_shared<IVhalClient::OnBinderDiedCallbackFunc>([this] { handleVhalDeath(); }));
1128 std::string currentPolicyId;
1129 {
1130 Mutex::Autolock lock(mMutex);
1131 mVhalService = vhalService;
1132 mSubscriptionClient = mVhalService->getSubscriptionClient(mPropertyChangeListener);
1133 if (isPowerPolicyAppliedLocked()) {
1134 currentPolicyId = mCurrentPowerPolicyMeta.powerPolicy->policyId;
1135 }
1136 }
1137 /*
1138 * When VHAL is first executed, a normal power management goes on. When VHAL is restarted due to
1139 * some reasons, the current policy is notified to VHAL.
1140 */
1141 if (mIsFirstConnectionToVhal) {
1142 applyInitialPowerPolicy();
1143 mIsFirstConnectionToVhal = false;
1144 } else if (!currentPolicyId.empty()) {
1145 notifyVhalNewPowerPolicy(currentPolicyId);
1146 }
1147 subscribeToVhal();
1148 ALOGI("Connected to VHAL");
1149 return;
1150 }
1151
applyInitialPowerPolicy()1152 void CarPowerPolicyServer::applyInitialPowerPolicy() {
1153 std::string policyId;
1154 std::string currentPolicyGroupId;
1155 CarPowerPolicyPtr powerPolicy;
1156 {
1157 Mutex::Autolock lock(mMutex);
1158 if (mIsCarServiceInOperation) {
1159 ALOGI("Skipping initial power policy application because CarService is running");
1160 return;
1161 }
1162 policyId = mPendingPowerPolicyId;
1163 currentPolicyGroupId = mCurrentPolicyGroupId;
1164 }
1165 if (policyId.empty()) {
1166 if (auto policy = mPolicyManager.getDefaultPowerPolicyForState(currentPolicyGroupId,
1167 VehicleApPowerStateReport::
1168 WAIT_FOR_VHAL);
1169 policy.ok()) {
1170 policyId = (*policy)->policyId;
1171 } else {
1172 policyId = kSystemPolicyIdInitialOn;
1173 }
1174 }
1175 if (const auto& ret = applyPowerPolicy(policyId, /*carServiceExpected=*/false, /*force=*/false);
1176 !ret.ok()) {
1177 ALOGW("Cannot apply the initial power policy(%s): %s", policyId.c_str(),
1178 ret.error().message().c_str());
1179 return;
1180 }
1181 ALOGD("Policy(%s) is applied as the initial one", policyId.c_str());
1182 }
1183
subscribeToVhal()1184 void CarPowerPolicyServer::subscribeToVhal() {
1185 subscribeToProperty(static_cast<int32_t>(VehicleProperty::POWER_POLICY_REQ),
1186 [this](const IHalPropValue& value) {
1187 std::string stringValue = value.getStringValue();
1188 if (stringValue.size() > 0) {
1189 const auto& ret = applyPowerPolicy(stringValue,
1190 /*carServiceExpected=*/false,
1191 /*force=*/false);
1192 if (!ret.ok()) {
1193 ALOGW("Failed to apply power policy(%s): %s",
1194 stringValue.c_str(), ret.error().message().c_str());
1195 }
1196 }
1197 });
1198 subscribeToProperty(static_cast<int32_t>(VehicleProperty::POWER_POLICY_GROUP_REQ),
1199 [this](const IHalPropValue& value) {
1200 std::string stringValue = value.getStringValue();
1201 if (stringValue.size() > 0) {
1202 const auto& ret = setPowerPolicyGroupInternal(stringValue);
1203 if (ret.ok()) {
1204 Mutex::Autolock lock(mMutex);
1205 mLastSetDefaultPowerPolicyGroupUptimeMs = value.getTimestamp();
1206 } else {
1207 ALOGW("Failed to set power policy group(%s): %s",
1208 stringValue.c_str(), ret.error().message().c_str());
1209 }
1210 }
1211 });
1212 }
1213
subscribeToProperty(int32_t prop,std::function<void (const IHalPropValue &)> processor)1214 void CarPowerPolicyServer::subscribeToProperty(
1215 int32_t prop, std::function<void(const IHalPropValue&)> processor) {
1216 if (!isPropertySupported(prop)) {
1217 ALOGW("Vehicle property(%d) is not supported by VHAL.", prop);
1218 return;
1219 }
1220 std::shared_ptr<IVhalClient> vhalService;
1221 {
1222 Mutex::Autolock lock(mMutex);
1223 if (mVhalService == nullptr) {
1224 ALOGW("Failed to subscribe to property(%d): VHAL is not ready", prop);
1225 return;
1226 }
1227 vhalService = mVhalService;
1228 }
1229
1230 VhalClientResult<std::unique_ptr<IHalPropValue>> result =
1231 vhalService->getValueSync(*vhalService->createHalPropValue(prop));
1232
1233 if (!result.ok()) {
1234 ALOGW("Failed to get vehicle property(%d) value, error: %s.", prop,
1235 result.error().message().c_str());
1236 return;
1237 }
1238 processor(*result.value());
1239 std::vector<SubscribeOptions> options = {
1240 {.propId = prop, .areaIds = {}},
1241 };
1242
1243 if (auto result = mSubscriptionClient->subscribe(options); !result.ok()) {
1244 ALOGW("Failed to subscribe to vehicle property(%d), error: %s", prop,
1245 result.error().message().c_str());
1246 }
1247 }
1248
notifyVhalNewPowerPolicy(const std::string & policyId)1249 Result<void> CarPowerPolicyServer::notifyVhalNewPowerPolicy(const std::string& policyId) {
1250 int32_t prop = static_cast<int32_t>(VehicleProperty::CURRENT_POWER_POLICY);
1251 if (!isPropertySupported(prop)) {
1252 return Error() << StringPrintf("Vehicle property(%d) is not supported by VHAL.", prop);
1253 }
1254 std::shared_ptr<IVhalClient> vhalService;
1255 {
1256 Mutex::Autolock lock(mMutex);
1257 if (mVhalService == nullptr) {
1258 return Error() << "VHAL is not ready";
1259 }
1260 vhalService = mVhalService;
1261 }
1262 std::unique_ptr<IHalPropValue> propValue = vhalService->createHalPropValue(prop);
1263 propValue->setStringValue(policyId);
1264
1265 VhalClientResult<void> result = vhalService->setValueSync(*propValue);
1266 if (!result.ok()) {
1267 return Error() << "Failed to set CURRENT_POWER_POLICY property";
1268 }
1269 ALOGD("Policy(%s) is notified to VHAL", policyId.c_str());
1270 return {};
1271 }
1272
isPropertySupported(const int32_t prop)1273 bool CarPowerPolicyServer::isPropertySupported(const int32_t prop) {
1274 if (mSupportedProperties.count(prop) > 0) {
1275 return mSupportedProperties[prop];
1276 }
1277 StatusCode status;
1278 hidl_vec<int32_t> props = {prop};
1279 std::shared_ptr<IVhalClient> vhalService;
1280 {
1281 Mutex::Autolock lock(mMutex);
1282 if (mVhalService == nullptr) {
1283 ALOGW("Failed to check if property(%d) is supported: VHAL is not ready", prop);
1284 return false;
1285 }
1286 vhalService = mVhalService;
1287 }
1288 auto result = vhalService->getPropConfigs(props);
1289 mSupportedProperties[prop] = result.ok();
1290 return mSupportedProperties[prop];
1291 }
1292
isPowerPolicyAppliedLocked() const1293 bool CarPowerPolicyServer::isPowerPolicyAppliedLocked() const {
1294 return mCurrentPowerPolicyMeta.powerPolicy != nullptr;
1295 }
1296
callbackToString(const CallbackInfo & callback)1297 std::string CarPowerPolicyServer::callbackToString(const CallbackInfo& callback) {
1298 const std::vector<PowerComponent>& components = callback.filter.components;
1299 return StringPrintf("callback(pid %d, filter: %s)", callback.pid, toString(components).c_str());
1300 }
1301
getPolicyChangeCallbacks()1302 std::vector<CallbackInfo> CarPowerPolicyServer::getPolicyChangeCallbacks() {
1303 Mutex::Autolock lock(mMutex);
1304 return mPolicyChangeCallbacks;
1305 }
1306
countOnClientBinderDiedContexts()1307 size_t CarPowerPolicyServer::countOnClientBinderDiedContexts() {
1308 Mutex::Autolock lock(mMutex);
1309 return mOnClientBinderDiedContexts.size();
1310 }
1311
linkToDeath(AIBinder * binder,AIBinder_DeathRecipient * recipient,void * cookie)1312 binder_status_t CarPowerPolicyServer::AIBinderLinkUnlinkImpl::linkToDeath(
1313 AIBinder* binder, AIBinder_DeathRecipient* recipient, void* cookie) {
1314 return AIBinder_linkToDeath(binder, recipient, cookie);
1315 }
1316
unlinkToDeath(AIBinder * binder,AIBinder_DeathRecipient * recipient,void * cookie)1317 binder_status_t CarPowerPolicyServer::AIBinderLinkUnlinkImpl::unlinkToDeath(
1318 AIBinder* binder, AIBinder_DeathRecipient* recipient, void* cookie) {
1319 return AIBinder_unlinkToDeath(binder, recipient, cookie);
1320 }
1321
1322 } // namespace powerpolicy
1323 } // namespace automotive
1324 } // namespace frameworks
1325 } // namespace android
1326