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