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 "PolicyManager.h"
21
22 #include <android-base/file.h>
23 #include <android-base/stringprintf.h>
24 #include <android-base/strings.h>
25 #include <utils/Log.h>
26
27 #include <tinyxml2.h>
28
29 #include <cstring>
30 #include <unordered_set>
31 #include <vector>
32
33 namespace android {
34 namespace frameworks {
35 namespace automotive {
36 namespace powerpolicy {
37
38 using ::aidl::android::frameworks::automotive::powerpolicy::CarPowerPolicy;
39 using ::aidl::android::frameworks::automotive::powerpolicy::PowerComponent;
40 using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReport;
41 using ::android::base::Error;
42 using ::android::base::Result;
43 using ::android::base::StartsWith;
44 using ::android::base::StringAppendF;
45 using ::android::base::StringPrintf;
46 using ::android::base::WriteStringToFd;
47 using ::tinyxml2::XML_SUCCESS;
48 using ::tinyxml2::XMLDocument;
49 using ::tinyxml2::XMLElement;
50
51 namespace {
52
53 // Vendor power policy filename.
54 constexpr const char kVendorPolicyFile[] = "/vendor/etc/automotive/power_policy.xml";
55
56 // Tags and attributes in vendor power policy XML file.
57 constexpr const char kTagRoot[] = "powerPolicy";
58 constexpr const char kTagPolicyGroups[] = "policyGroups";
59 constexpr const char kTagPolicyGroup[] = "policyGroup";
60 constexpr const char kTagDefaultPolicy[] = "defaultPolicy";
61 constexpr const char kTagNoDefaultPolicy[] = "noDefaultPolicy";
62 constexpr const char kTagPolicies[] = "policies";
63 constexpr const char kTagPolicy[] = "policy";
64 constexpr const char kTagOtherComponents[] = "otherComponents";
65 constexpr const char kTagComponent[] = "component";
66 constexpr const char kTagSystemPolicyOverrides[] = "systemPolicyOverrides";
67 constexpr const char kAttrBehavior[] = "behavior";
68 constexpr const char kAttrId[] = "id";
69 constexpr const char kAttrState[] = "state";
70 constexpr const char kAttrDefaultPolicyGroup[] = "defaultPolicyGroup";
71
72 // Power states.
73 constexpr const char kPowerStateOn[] = "on";
74 constexpr const char kPowerStateOff[] = "off";
75 constexpr const char kPowerStateUntouched[] = "untouched";
76
77 // Power transitions that a power policy can be applied with.
78 constexpr const char kPowerTransitionWaitForVhal[] = "WaitForVHAL";
79 constexpr const char kPowerTransitionOn[] = "On";
80
81 const PowerComponent INVALID_POWER_COMPONENT = static_cast<PowerComponent>(-1);
82 const int32_t INVALID_VEHICLE_POWER_STATE = -1;
83
84 constexpr const char kPowerComponentPrefix[] = "POWER_COMPONENT_";
85 constexpr const char kSystemPolicyPrefix[] = "system_power_policy_";
86
87 // System power policy definition: ID, enabled components, and disabled components.
88 const std::vector<PowerComponent> kNoUserInteractionEnabledComponents =
89 {PowerComponent::WIFI, PowerComponent::CELLULAR, PowerComponent::ETHERNET,
90 PowerComponent::TRUSTED_DEVICE_DETECTION, PowerComponent::CPU};
91 const std::vector<PowerComponent> kNoUserInteractionDisabledComponents =
92 {PowerComponent::AUDIO,
93 PowerComponent::MEDIA,
94 PowerComponent::DISPLAY,
95 PowerComponent::BLUETOOTH,
96 PowerComponent::PROJECTION,
97 PowerComponent::NFC,
98 PowerComponent::INPUT,
99 PowerComponent::VOICE_INTERACTION,
100 PowerComponent::VISUAL_INTERACTION,
101 PowerComponent::LOCATION,
102 PowerComponent::MICROPHONE};
103 const std::vector<PowerComponent> kAllComponents = {PowerComponent::AUDIO,
104 PowerComponent::MEDIA,
105 PowerComponent::DISPLAY,
106 PowerComponent::BLUETOOTH,
107 PowerComponent::WIFI,
108 PowerComponent::CELLULAR,
109 PowerComponent::ETHERNET,
110 PowerComponent::PROJECTION,
111 PowerComponent::NFC,
112 PowerComponent::INPUT,
113 PowerComponent::VOICE_INTERACTION,
114 PowerComponent::VISUAL_INTERACTION,
115 PowerComponent::TRUSTED_DEVICE_DETECTION,
116 PowerComponent::LOCATION,
117 PowerComponent::MICROPHONE,
118 PowerComponent::CPU};
119 const std::vector<PowerComponent> kInitialOnComponents = {PowerComponent::AUDIO,
120 PowerComponent::DISPLAY,
121 PowerComponent::CPU};
122 const std::vector<PowerComponent> kNoComponents;
123 const std::vector<PowerComponent> kSuspendPrepDisabledComponents = {PowerComponent::AUDIO,
124 PowerComponent::BLUETOOTH,
125 PowerComponent::WIFI,
126 PowerComponent::LOCATION,
127 PowerComponent::MICROPHONE,
128 PowerComponent::CPU};
129 const std::unordered_set<PowerComponent> kNoUserInteractionConfigurableComponents =
130 {PowerComponent::BLUETOOTH, PowerComponent::NFC, PowerComponent::TRUSTED_DEVICE_DETECTION};
131
iterateAllPowerComponents(const std::function<bool (PowerComponent)> & processor)132 void iterateAllPowerComponents(const std::function<bool(PowerComponent)>& processor) {
133 for (const auto component : ::ndk::enum_range<PowerComponent>()) {
134 if (!processor(component)) {
135 break;
136 }
137 }
138 }
139
toPowerComponent(std::string_view id,std::string_view prefix)140 PowerComponent toPowerComponent(std::string_view id, std::string_view prefix) {
141 if (!StartsWith(id, prefix)) {
142 return INVALID_POWER_COMPONENT;
143 }
144 std::string_view componentId = id.substr(prefix.size());
145 PowerComponent matchedComponent = INVALID_POWER_COMPONENT;
146 iterateAllPowerComponents([componentId, &matchedComponent](PowerComponent component) -> bool {
147 if (componentId == toString(component)) {
148 matchedComponent = component;
149 return false;
150 }
151 return true;
152 });
153 return matchedComponent;
154 }
155
safePtrPrint(const char * ptr)156 const char* safePtrPrint(const char* ptr) {
157 return ptr == nullptr ? "nullptr" : ptr;
158 }
159
toVehiclePowerState(const char * state)160 int32_t toVehiclePowerState(const char* state) {
161 if (!strcmp(state, kPowerTransitionWaitForVhal)) {
162 return static_cast<int32_t>(VehicleApPowerStateReport::WAIT_FOR_VHAL);
163 }
164 if (!strcmp(state, kPowerTransitionOn)) {
165 return static_cast<int32_t>(VehicleApPowerStateReport::ON);
166 }
167 return INVALID_VEHICLE_POWER_STATE;
168 }
169
isValidPowerState(int32_t state)170 bool isValidPowerState(int32_t state) {
171 return state != INVALID_VEHICLE_POWER_STATE;
172 }
173
logXmlError(const std::string & errMsg)174 void logXmlError(const std::string& errMsg) {
175 ALOGW("Proceed without registered policies: %s", errMsg.c_str());
176 }
177
readComponents(const XMLElement * pPolicy,CarPowerPolicyPtr policy,std::unordered_set<PowerComponent> * visited)178 Result<void> readComponents(const XMLElement* pPolicy, CarPowerPolicyPtr policy,
179 std::unordered_set<PowerComponent>* visited) {
180 for (const XMLElement* pComponent = pPolicy->FirstChildElement(kTagComponent);
181 pComponent != nullptr; pComponent = pComponent->NextSiblingElement(kTagComponent)) {
182 const char* id;
183 if (pComponent->QueryStringAttribute(kAttrId, &id) != XML_SUCCESS) {
184 return Error() << StringPrintf("Failed to read |%s| attribute in |%s| tag", kAttrId,
185 kTagComponent);
186 }
187 PowerComponent componentId = toPowerComponent(id, kPowerComponentPrefix);
188 if (componentId == INVALID_POWER_COMPONENT) {
189 return Error() << StringPrintf("XML configuration has invalid value(%s) in |%s| "
190 "attribute of |%s| tag",
191 safePtrPrint(id), kAttrId, kTagComponent);
192 }
193 if (visited->count(componentId) > 0) {
194 return Error() << StringPrintf("XML configuration has duplicated component(%s) in |%s| "
195 "attribute of |%s| tag",
196 toString(componentId).c_str(), kAttrId, kTagComponent);
197 }
198 visited->insert(componentId);
199 const char* powerState = pComponent->GetText();
200 if (!strcmp(powerState, kPowerStateOn)) {
201 policy->enabledComponents.push_back(componentId);
202 } else if (!strcmp(powerState, kPowerStateOff)) {
203 policy->disabledComponents.push_back(componentId);
204 } else {
205 return Error() << StringPrintf("XML configuration has invalid value(%s) in |%s| tag",
206 safePtrPrint(powerState), kTagComponent);
207 }
208 }
209 return {};
210 }
211
readOtherComponents(const XMLElement * pPolicy,CarPowerPolicyPtr policy,const std::unordered_set<PowerComponent> & visited)212 Result<void> readOtherComponents(const XMLElement* pPolicy, CarPowerPolicyPtr policy,
213 const std::unordered_set<PowerComponent>& visited) {
214 const char* otherComponentBehavior = kPowerStateUntouched;
215 const XMLElement* pElement = pPolicy->FirstChildElement(kTagOtherComponents);
216 if (pElement != nullptr) {
217 if (pElement->QueryStringAttribute(kAttrBehavior, &otherComponentBehavior) != XML_SUCCESS) {
218 return Error() << StringPrintf("Failed to read |%s| attribute in |%s| tag",
219 kAttrBehavior, kTagOtherComponents);
220 }
221 }
222 if (!strcmp(otherComponentBehavior, kPowerStateOn)) {
223 iterateAllPowerComponents([&visited, &policy](PowerComponent component) -> bool {
224 if (visited.count(component) == 0) {
225 policy->enabledComponents.push_back(component);
226 }
227 return true;
228 });
229 } else if (!strcmp(otherComponentBehavior, kPowerStateOff)) {
230 iterateAllPowerComponents([&visited, &policy](PowerComponent component) -> bool {
231 if (visited.count(component) == 0) {
232 policy->disabledComponents.push_back(component);
233 }
234 return true;
235 });
236 } else if (!strcmp(otherComponentBehavior, kPowerStateUntouched)) {
237 // Do nothing
238 } else {
239 return Error() << StringPrintf("XML configuration has invalid value(%s) in |%s| attribute "
240 "of |%s| tag",
241 safePtrPrint(otherComponentBehavior), kAttrBehavior,
242 kTagOtherComponents);
243 }
244 return {};
245 }
246
readPolicies(const XMLElement * pRoot,const char * tag,bool includeOtherComponents)247 Result<std::vector<CarPowerPolicyPtr>> readPolicies(const XMLElement* pRoot, const char* tag,
248 bool includeOtherComponents) {
249 std::vector<CarPowerPolicyPtr> policies;
250 const XMLElement* pPolicies = pRoot->FirstChildElement(tag);
251 if (pPolicies == nullptr) {
252 return std::vector<CarPowerPolicyPtr>();
253 }
254 for (const XMLElement* pPolicy = pPolicies->FirstChildElement(kTagPolicy); pPolicy != nullptr;
255 pPolicy = pPolicy->NextSiblingElement(kTagPolicy)) {
256 std::unordered_set<PowerComponent> visited;
257 const char* policyId;
258 if (pPolicy->QueryStringAttribute(kAttrId, &policyId) != XML_SUCCESS) {
259 return Error() << StringPrintf("Failed to read |%s| attribute in |%s| tag", kAttrId,
260 kTagPolicy);
261 }
262 if (includeOtherComponents && isSystemPowerPolicy(policyId)) {
263 return Error() << "Policy ID should not start with \"system_power_policy_\"";
264 }
265 auto policy = std::make_shared<CarPowerPolicy>();
266 policy->policyId = policyId;
267
268 auto ret = readComponents(pPolicy, policy, &visited);
269 if (!ret.ok()) {
270 return ret.error();
271 }
272 if (includeOtherComponents) {
273 ret = readOtherComponents(pPolicy, policy, visited);
274 if (!ret.ok()) {
275 return ret.error();
276 }
277 }
278 policies.push_back(policy);
279 }
280 return policies;
281 }
282
readPolicyGroup(const XMLElement * pPolicyGroup,const std::unordered_map<std::string,CarPowerPolicyPtr> & registeredPowerPolicies)283 Result<PolicyGroup> readPolicyGroup(
284 const XMLElement* pPolicyGroup,
285 const std::unordered_map<std::string, CarPowerPolicyPtr>& registeredPowerPolicies) {
286 PolicyGroup policyGroup;
287 for (const XMLElement* pDefaultPolicy = pPolicyGroup->FirstChildElement(kTagDefaultPolicy);
288 pDefaultPolicy != nullptr;
289 pDefaultPolicy = pDefaultPolicy->NextSiblingElement(kTagDefaultPolicy)) {
290 const char* state;
291 if (pDefaultPolicy->QueryStringAttribute(kAttrState, &state) != XML_SUCCESS) {
292 return Error() << StringPrintf("Failed to read |%s| attribute in |%s| tag", kAttrState,
293 kTagDefaultPolicy);
294 }
295 int32_t powerState = toVehiclePowerState(state);
296 if (!isValidPowerState(powerState)) {
297 return Error() << StringPrintf("Target state(%s) is not valid", state);
298 }
299 const char* policyId;
300 if (pDefaultPolicy->QueryStringAttribute(kAttrId, &policyId) != XML_SUCCESS) {
301 return Error() << StringPrintf("Failed to read |%s| attribute in |%s| tag", kAttrId,
302 kTagDefaultPolicy);
303 }
304 if (registeredPowerPolicies.count(policyId) == 0) {
305 return Error() << StringPrintf("Policy(id: %s) is not registered", policyId);
306 }
307 policyGroup.emplace(powerState, policyId);
308 }
309 for (const XMLElement* pNoPolicy = pPolicyGroup->FirstChildElement(kTagNoDefaultPolicy);
310 pNoPolicy != nullptr; pNoPolicy = pNoPolicy->NextSiblingElement(kTagNoDefaultPolicy)) {
311 const char* state;
312 if (pNoPolicy->QueryStringAttribute(kAttrState, &state) != XML_SUCCESS) {
313 return Error() << StringPrintf("Failed to read |%s| attribute in |%s| tag", kAttrState,
314 kTagNoDefaultPolicy);
315 }
316 int32_t powerState = toVehiclePowerState(state);
317 if (!isValidPowerState(powerState)) {
318 return Error() << StringPrintf("Target state(%s) is not valid", state);
319 }
320 if (policyGroup.count(powerState) > 0) {
321 return Error()
322 << StringPrintf("Target state(%s) is specified both in |%s| and |%s| tags",
323 state, kTagDefaultPolicy, kTagNoDefaultPolicy);
324 }
325 }
326 return policyGroup;
327 }
328
329 struct PolicyGroups {
330 std::unordered_map<std::string, PolicyGroup> groups;
331 std::string defaultGroup;
332 };
333
readPolicyGroups(const XMLElement * pRoot,const std::unordered_map<std::string,CarPowerPolicyPtr> & registeredPowerPolicies)334 Result<PolicyGroups> readPolicyGroups(
335 const XMLElement* pRoot,
336 const std::unordered_map<std::string, CarPowerPolicyPtr>& registeredPowerPolicies) {
337 const XMLElement* pPolicyGroups = pRoot->FirstChildElement(kTagPolicyGroups);
338
339 PolicyGroups policyGroups;
340
341 if (pPolicyGroups == nullptr) {
342 return policyGroups;
343 }
344
345 const char* pDefaultPolicyGroupId = nullptr;
346 pPolicyGroups->QueryStringAttribute(kAttrDefaultPolicyGroup, &pDefaultPolicyGroupId);
347 if (pDefaultPolicyGroupId != nullptr) {
348 policyGroups.defaultGroup = pDefaultPolicyGroupId;
349 }
350
351 for (const XMLElement* pPolicyGroup = pPolicyGroups->FirstChildElement(kTagPolicyGroup);
352 pPolicyGroup != nullptr;
353 pPolicyGroup = pPolicyGroup->NextSiblingElement(kTagPolicyGroup)) {
354 const char* policyGroupId;
355 if (pPolicyGroup->QueryStringAttribute(kAttrId, &policyGroupId) != XML_SUCCESS) {
356 return Error() << StringPrintf("Failed to read |%s| attribute in |%s| tag", kAttrId,
357 kTagPolicyGroup);
358 }
359 const auto& policyGroup = readPolicyGroup(pPolicyGroup, registeredPowerPolicies);
360 if (!policyGroup.ok()) {
361 return Error() << policyGroup.error();
362 }
363 policyGroups.groups.emplace(policyGroupId, *policyGroup);
364 }
365 return policyGroups;
366 }
367
isConfigurableComponent(PowerComponent component)368 bool isConfigurableComponent(PowerComponent component) {
369 return kNoUserInteractionConfigurableComponents.count(component) > 0;
370 }
371
checkConfigurableComponents(const std::vector<PowerComponent> & components)372 Result<void> checkConfigurableComponents(const std::vector<PowerComponent>& components) {
373 for (auto component : components) {
374 if (!isConfigurableComponent(component)) {
375 return Error()
376 << StringPrintf("Component(%s) is not configurable in system power policy.",
377 toString(component).c_str());
378 }
379 }
380 return {};
381 }
382
readSystemPolicyOverrides(const XMLElement * pRoot)383 Result<std::vector<CarPowerPolicyPtr>> readSystemPolicyOverrides(const XMLElement* pRoot) {
384 const auto& systemPolicyOverrides = readPolicies(pRoot, kTagSystemPolicyOverrides, false);
385 if (!systemPolicyOverrides.ok()) {
386 return Error() << systemPolicyOverrides.error().message();
387 }
388 for (auto policy : *systemPolicyOverrides) {
389 if (policy->policyId != kSystemPolicyIdNoUserInteraction) {
390 return Error() << StringPrintf("System power policy(%s) is not supported.",
391 policy->policyId.c_str());
392 }
393 auto ret = checkConfigurableComponents(policy->enabledComponents);
394 if (!ret.ok()) {
395 return ret.error();
396 }
397 ret = checkConfigurableComponents(policy->disabledComponents);
398 if (!ret.ok()) {
399 return ret.error();
400 }
401 }
402 return systemPolicyOverrides;
403 }
404
405 // configureComponents assumes that previously validated components are passed.
configureComponents(const std::vector<PowerComponent> & configComponents,std::vector<PowerComponent> * componentsAddedTo,std::vector<PowerComponent> * componentsRemovedFrom)406 void configureComponents(const std::vector<PowerComponent>& configComponents,
407 std::vector<PowerComponent>* componentsAddedTo,
408 std::vector<PowerComponent>* componentsRemovedFrom) {
409 for (const auto component : configComponents) {
410 auto it = std::find(componentsAddedTo->begin(), componentsAddedTo->end(), component);
411 if (it == componentsAddedTo->end()) {
412 componentsAddedTo->push_back(component);
413 }
414 it = std::find(componentsRemovedFrom->begin(), componentsRemovedFrom->end(), component);
415 if (it != componentsRemovedFrom->end()) {
416 componentsRemovedFrom->erase(it);
417 }
418 }
419 }
420
stringsToComponents(const std::vector<std::string> & arr,std::vector<PowerComponent> * components)421 Result<void> stringsToComponents(const std::vector<std::string>& arr,
422 std::vector<PowerComponent>* components) {
423 for (const auto& c : arr) {
424 const char* component = c.c_str();
425 PowerComponent componentId = toPowerComponent(component, "");
426 if (componentId == INVALID_POWER_COMPONENT) {
427 return Error() << StringPrintf("%s is not a valid component", component);
428 }
429 components->push_back(componentId);
430 }
431 return {};
432 }
433
createPolicy(const char * policyId,const std::vector<PowerComponent> & enabledComponents,const std::vector<PowerComponent> & disabledComponents)434 CarPowerPolicyPtr createPolicy(const char* policyId,
435 const std::vector<PowerComponent>& enabledComponents,
436 const std::vector<PowerComponent>& disabledComponents) {
437 CarPowerPolicyPtr policy = std::make_shared<CarPowerPolicy>();
438 policy->policyId = policyId;
439 policy->enabledComponents = enabledComponents;
440 policy->disabledComponents = disabledComponents;
441 return policy;
442 }
443
444 } // namespace
445
toString(const std::vector<PowerComponent> & components)446 std::string toString(const std::vector<PowerComponent>& components) {
447 size_t size = components.size();
448 if (size == 0) {
449 return "none";
450 }
451 std::string filterStr = toString(components[0]);
452 for (size_t i = 1; i < size; i++) {
453 StringAppendF(&filterStr, ", %s", toString(components[i]).c_str());
454 }
455 return filterStr;
456 }
457
toString(const CarPowerPolicy & policy)458 std::string toString(const CarPowerPolicy& policy) {
459 return StringPrintf("%s(enabledComponents: %s, disabledComponents: %s)",
460 policy.policyId.c_str(), toString(policy.enabledComponents).c_str(),
461 toString(policy.disabledComponents).c_str());
462 }
463
isSystemPowerPolicy(const std::string & policyId)464 bool isSystemPowerPolicy(const std::string& policyId) {
465 return StartsWith(policyId, kSystemPolicyPrefix);
466 }
467
init()468 void PolicyManager::init() {
469 initRegularPowerPolicy(/*override=*/true);
470 mPolicyGroups.clear();
471 initPreemptivePowerPolicy();
472 readPowerPolicyConfiguration();
473 }
474
getPowerPolicy(const std::string & policyId) const475 Result<CarPowerPolicyMeta> PolicyManager::getPowerPolicy(const std::string& policyId) const {
476 if (mRegisteredPowerPolicies.count(policyId) > 0) {
477 return CarPowerPolicyMeta{
478 .powerPolicy = mRegisteredPowerPolicies.at(policyId),
479 .isPreemptive = false,
480 };
481 }
482 if (mPreemptivePowerPolicies.count(policyId) > 0) {
483 return CarPowerPolicyMeta{
484 .powerPolicy = mPreemptivePowerPolicies.at(policyId),
485 .isPreemptive = true,
486 };
487 }
488 return Error() << StringPrintf("Power policy(id: %s) is not found", policyId.c_str());
489 }
490
getDefaultPowerPolicyForState(const std::string & groupId,VehicleApPowerStateReport state) const491 Result<CarPowerPolicyPtr> PolicyManager::getDefaultPowerPolicyForState(
492 const std::string& groupId, VehicleApPowerStateReport state) const {
493 auto groupIdToUse = groupId.empty() ? mDefaultPolicyGroup : groupId;
494
495 if (mPolicyGroups.count(groupIdToUse) == 0) {
496 return Error() << StringPrintf("Power policy group %s is not found", groupIdToUse.c_str());
497 }
498
499 PolicyGroup policyGroup = mPolicyGroups.at(groupIdToUse);
500 int32_t key = static_cast<int32_t>(state);
501 if (policyGroup.count(key) == 0) {
502 return Error() << StringPrintf("Policy for %s is not found", toString(state).c_str());
503 }
504 return mRegisteredPowerPolicies.at(policyGroup.at(key));
505 }
506
isPowerPolicyGroupAvailable(const std::string & groupId) const507 bool PolicyManager::isPowerPolicyGroupAvailable(const std::string& groupId) const {
508 return mPolicyGroups.count(groupId) > 0;
509 }
510
isPreemptivePowerPolicy(const std::string & policyId) const511 bool PolicyManager::isPreemptivePowerPolicy(const std::string& policyId) const {
512 return mPreemptivePowerPolicies.count(policyId) > 0;
513 }
514
definePowerPolicy(const std::string & policyId,const std::vector<std::string> & enabledComponents,const std::vector<std::string> & disabledComponents)515 Result<void> PolicyManager::definePowerPolicy(const std::string& policyId,
516 const std::vector<std::string>& enabledComponents,
517 const std::vector<std::string>& disabledComponents) {
518 if (mRegisteredPowerPolicies.count(policyId) > 0) {
519 return Error() << StringPrintf("%s is already registered", policyId.c_str());
520 }
521 auto policy = std::make_shared<CarPowerPolicy>();
522 policy->policyId = policyId;
523 auto ret = stringsToComponents(enabledComponents, &policy->enabledComponents);
524 if (!ret.ok()) {
525 return ret;
526 }
527 ret = stringsToComponents(disabledComponents, &policy->disabledComponents);
528 if (!ret.ok()) {
529 return ret;
530 }
531 mRegisteredPowerPolicies.emplace(policyId, policy);
532 return {};
533 }
534
dump(int fd,const Vector<String16> &)535 Result<void> PolicyManager::dump(int fd, const Vector<String16>& /*args*/) {
536 const char* indent = " ";
537 const char* doubleIndent = " ";
538 const char* tripleIndent = " ";
539
540 WriteStringToFd(StringPrintf("%sRegistered power policies:%s\n", indent,
541 mRegisteredPowerPolicies.size() ? "" : " none"),
542 fd);
543 for (auto& it : mRegisteredPowerPolicies) {
544 WriteStringToFd(StringPrintf("%s- %s\n", doubleIndent, toString(*it.second).c_str()), fd);
545 }
546 WriteStringToFd(StringPrintf("%sPower policy groups:%s\n", indent,
547 mPolicyGroups.size() ? "" : " none"),
548 fd);
549 for (auto& itGroup : mPolicyGroups) {
550 WriteStringToFd(StringPrintf("%s%s\n", doubleIndent, itGroup.first.c_str()), fd);
551 for (auto& itMapping : itGroup.second) {
552 VehicleApPowerStateReport state =
553 static_cast<VehicleApPowerStateReport>(itMapping.first);
554 WriteStringToFd(StringPrintf("%s- %s --> %s\n", tripleIndent, toString(state).c_str(),
555 itMapping.second.c_str()),
556 fd);
557 }
558 }
559 WriteStringToFd(StringPrintf("%sNo user interaction power policy: %s\n", indent,
560 toString(*mPreemptivePowerPolicies.at(
561 kSystemPolicyIdNoUserInteraction))
562 .c_str()),
563 fd);
564 return {};
565 }
566
readPowerPolicyConfiguration()567 void PolicyManager::readPowerPolicyConfiguration() {
568 XMLDocument xmlDoc;
569 xmlDoc.LoadFile(kVendorPolicyFile);
570 if (xmlDoc.ErrorID() != XML_SUCCESS) {
571 logXmlError(StringPrintf("Failed to read and/or parse %s", kVendorPolicyFile));
572 return;
573 }
574 readPowerPolicyFromXml(xmlDoc);
575 }
576
readPowerPolicyFromXml(const XMLDocument & xmlDoc)577 void PolicyManager::readPowerPolicyFromXml(const XMLDocument& xmlDoc) {
578 const XMLElement* pRootElement = xmlDoc.RootElement();
579 if (!pRootElement || strcmp(pRootElement->Name(), kTagRoot)) {
580 logXmlError(StringPrintf("XML file is not in the required format"));
581 return;
582 }
583 const auto& registeredPolicies = readPolicies(pRootElement, kTagPolicies, true);
584 if (!registeredPolicies.ok()) {
585 logXmlError(StringPrintf("Reading policies failed: %s",
586 registeredPolicies.error().message().c_str()));
587 return;
588 }
589 std::unordered_map<std::string, CarPowerPolicyPtr> registeredPoliciesMap;
590 for (auto policy : *registeredPolicies) {
591 registeredPoliciesMap.emplace(policy->policyId, policy);
592 }
593
594 const auto& policyGroups = readPolicyGroups(pRootElement, registeredPoliciesMap);
595 if (!policyGroups.ok()) {
596 logXmlError(StringPrintf("Reading power policy groups for power state failed: %s",
597 policyGroups.error().message().c_str()));
598 return;
599 }
600 const auto& systemPolicyOverrides = readSystemPolicyOverrides(pRootElement);
601 if (!systemPolicyOverrides.ok()) {
602 logXmlError(StringPrintf("Reading system power policy overrides failed: %s",
603 systemPolicyOverrides.error().message().c_str()));
604 return;
605 }
606
607 mRegisteredPowerPolicies = registeredPoliciesMap;
608 initRegularPowerPolicy(/*override=*/false);
609 mPolicyGroups = policyGroups->groups;
610 mDefaultPolicyGroup = policyGroups->defaultGroup;
611 reconstructNoUserInteractionPolicy(*systemPolicyOverrides);
612 }
613
reconstructNoUserInteractionPolicy(const std::vector<CarPowerPolicyPtr> & policyOverrides)614 void PolicyManager::reconstructNoUserInteractionPolicy(
615 const std::vector<CarPowerPolicyPtr>& policyOverrides) {
616 CarPowerPolicyPtr systemPolicy = mPreemptivePowerPolicies.at(kSystemPolicyIdNoUserInteraction);
617 for (auto policy : policyOverrides) {
618 configureComponents(policy->enabledComponents, &systemPolicy->enabledComponents,
619 &systemPolicy->disabledComponents);
620 configureComponents(policy->disabledComponents, &systemPolicy->disabledComponents,
621 &systemPolicy->enabledComponents);
622 }
623 }
624
initRegularPowerPolicy(bool override)625 void PolicyManager::initRegularPowerPolicy(bool override) {
626 if (override) {
627 mRegisteredPowerPolicies.clear();
628 }
629 mRegisteredPowerPolicies.emplace(kSystemPolicyIdAllOn,
630 createPolicy(kSystemPolicyIdAllOn, kAllComponents,
631 kNoComponents));
632
633 std::vector<PowerComponent> initialOnDisabledComponents;
634 for (const auto component : ::ndk::enum_range<PowerComponent>()) {
635 if (std::find(kInitialOnComponents.begin(), kInitialOnComponents.end(), component) ==
636 kInitialOnComponents.end()) {
637 initialOnDisabledComponents.push_back(component);
638 }
639 }
640 mRegisteredPowerPolicies.emplace(kSystemPolicyIdInitialOn,
641 createPolicy(kSystemPolicyIdInitialOn, kInitialOnComponents,
642 initialOnDisabledComponents));
643 }
644
initPreemptivePowerPolicy()645 void PolicyManager::initPreemptivePowerPolicy() {
646 mPreemptivePowerPolicies.clear();
647 mPreemptivePowerPolicies.emplace(kSystemPolicyIdNoUserInteraction,
648 createPolicy(kSystemPolicyIdNoUserInteraction,
649 kNoUserInteractionEnabledComponents,
650 kNoUserInteractionDisabledComponents));
651 mPreemptivePowerPolicies.emplace(kSystemPolicyIdSuspendPrep,
652 createPolicy(kSystemPolicyIdSuspendPrep, kNoComponents,
653 kSuspendPrepDisabledComponents));
654 }
655
getDefaultPolicyGroup() const656 std::string PolicyManager::getDefaultPolicyGroup() const {
657 return mDefaultPolicyGroup;
658 }
659
660 } // namespace powerpolicy
661 } // namespace automotive
662 } // namespace frameworks
663 } // namespace android
664