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/parseint.h"
23 
24 #include <android-base/file.h>
25 #include <android-base/stringprintf.h>
26 #include <android-base/strings.h>
27 #include <utils/Log.h>
28 
29 #include <tinyxml2.h>
30 
31 #include <cstring>
32 #include <unordered_set>
33 #include <vector>
34 
35 namespace android {
36 namespace frameworks {
37 namespace automotive {
38 namespace powerpolicy {
39 
40 using ::aidl::android::frameworks::automotive::powerpolicy::CarPowerPolicy;
41 using ::aidl::android::frameworks::automotive::powerpolicy::PowerComponent;
42 using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReport;
43 using ::android::base::Error;
44 using ::android::base::Result;
45 using ::android::base::StartsWith;
46 using ::android::base::StringAppendF;
47 using ::android::base::StringPrintf;
48 using ::android::base::WriteStringToFd;
49 using ::tinyxml2::XML_SUCCESS;
50 using ::tinyxml2::XMLDocument;
51 using ::tinyxml2::XMLElement;
52 
53 namespace {
54 
55 // Vendor power policy filename.
56 constexpr const char kVendorPolicyFile[] = "/vendor/etc/automotive/power_policy.xml";
57 
58 // Tags and attributes in vendor power policy XML file.
59 constexpr const char kTagRoot[] = "powerPolicy";
60 constexpr const char kTagPolicyGroups[] = "policyGroups";
61 constexpr const char kTagPolicyGroup[] = "policyGroup";
62 constexpr const char kTagDefaultPolicy[] = "defaultPolicy";
63 constexpr const char kTagNoDefaultPolicy[] = "noDefaultPolicy";
64 constexpr const char kTagPolicies[] = "policies";
65 constexpr const char kTagPolicy[] = "policy";
66 constexpr const char kTagOtherComponents[] = "otherComponents";
67 constexpr const char kTagComponent[] = "component";
68 constexpr const char kTagSystemPolicyOverrides[] = "systemPolicyOverrides";
69 constexpr const char kAttrBehavior[] = "behavior";
70 constexpr const char kAttrId[] = "id";
71 constexpr const char kAttrState[] = "state";
72 constexpr const char kAttrDefaultPolicyGroup[] = "defaultPolicyGroup";
73 constexpr const char kTagCustomComponents[] = "customComponents";
74 constexpr const char kTagCustomComponent[] = "customComponent";
75 constexpr const char kAttrValue[] = "value";
76 // Power states.
77 constexpr const char kPowerStateOn[] = "on";
78 constexpr const char kPowerStateOff[] = "off";
79 constexpr const char kPowerStateUntouched[] = "untouched";
80 
81 // Power transitions that a power policy can be applied with.
82 constexpr const char kPowerTransitionWaitForVhal[] = "WaitForVHAL";
83 constexpr const char kPowerTransitionOn[] = "On";
84 
85 const PowerComponent INVALID_POWER_COMPONENT = static_cast<PowerComponent>(-1);
86 const int32_t INVALID_CUSTOM_POWER_COMPONENT = -1;
87 const int32_t MINIMUM_CUSTOM_COMPONENT_VALUE =
88         static_cast<int>(PowerComponent::MINIMUM_CUSTOM_COMPONENT_VALUE);
89 const int32_t INVALID_VEHICLE_POWER_STATE = -1;
90 const int32_t WAIT_FOR_VHAL_STATE = static_cast<int32_t>(VehicleApPowerStateReport::WAIT_FOR_VHAL);
91 const int32_t ON_STATE = static_cast<int32_t>(VehicleApPowerStateReport::ON);
92 
93 constexpr const char kPowerComponentPrefix[] = "POWER_COMPONENT_";
94 constexpr const char kSystemPolicyPrefix[] = "system_power_policy_";
95 
96 // System power policy definition: ID, enabled components, and disabled components.
97 const std::vector<PowerComponent> kNoUserInteractionEnabledComponents =
98         {PowerComponent::WIFI, PowerComponent::CELLULAR, PowerComponent::ETHERNET,
99          PowerComponent::TRUSTED_DEVICE_DETECTION, PowerComponent::CPU};
100 const std::vector<PowerComponent> kNoUserInteractionDisabledComponents =
101         {PowerComponent::AUDIO,
102          PowerComponent::MEDIA,
103          PowerComponent::DISPLAY,
104          PowerComponent::BLUETOOTH,
105          PowerComponent::PROJECTION,
106          PowerComponent::NFC,
107          PowerComponent::INPUT,
108          PowerComponent::VOICE_INTERACTION,
109          PowerComponent::VISUAL_INTERACTION,
110          PowerComponent::LOCATION,
111          PowerComponent::MICROPHONE};
112 const std::vector<PowerComponent> kAllComponents = {PowerComponent::AUDIO,
113                                                     PowerComponent::MEDIA,
114                                                     PowerComponent::DISPLAY,
115                                                     PowerComponent::BLUETOOTH,
116                                                     PowerComponent::WIFI,
117                                                     PowerComponent::CELLULAR,
118                                                     PowerComponent::ETHERNET,
119                                                     PowerComponent::PROJECTION,
120                                                     PowerComponent::NFC,
121                                                     PowerComponent::INPUT,
122                                                     PowerComponent::VOICE_INTERACTION,
123                                                     PowerComponent::VISUAL_INTERACTION,
124                                                     PowerComponent::TRUSTED_DEVICE_DETECTION,
125                                                     PowerComponent::LOCATION,
126                                                     PowerComponent::MICROPHONE,
127                                                     PowerComponent::CPU};
128 const std::vector<PowerComponent> kInitialOnComponents = {PowerComponent::AUDIO,
129                                                           PowerComponent::DISPLAY,
130                                                           PowerComponent::CPU};
131 const std::vector<PowerComponent> kNoComponents;
132 const std::vector<PowerComponent> kSuspendPrepDisabledComponents = {PowerComponent::AUDIO,
133                                                                     PowerComponent::BLUETOOTH,
134                                                                     PowerComponent::WIFI,
135                                                                     PowerComponent::LOCATION,
136                                                                     PowerComponent::MICROPHONE,
137                                                                     PowerComponent::CPU};
138 const std::unordered_set<PowerComponent> kNoUserInteractionConfigurableComponents =
139         {PowerComponent::BLUETOOTH, PowerComponent::NFC, PowerComponent::TRUSTED_DEVICE_DETECTION};
140 
iterateAllPowerComponents(const std::function<bool (PowerComponent)> & processor)141 void iterateAllPowerComponents(const std::function<bool(PowerComponent)>& processor) {
142     for (const auto component : ::ndk::enum_range<PowerComponent>()) {
143         if (component >= PowerComponent::MINIMUM_CUSTOM_COMPONENT_VALUE) {
144             continue;
145         }
146         if (!processor(component)) {
147             break;
148         }
149     }
150 }
151 
toPowerComponent(std::string_view id,std::string_view prefix)152 PowerComponent toPowerComponent(std::string_view id, std::string_view prefix) {
153     if (!StartsWith(id, prefix)) {
154         return INVALID_POWER_COMPONENT;
155     }
156     std::string_view componentId = id.substr(prefix.size());
157     PowerComponent matchedComponent = INVALID_POWER_COMPONENT;
158     iterateAllPowerComponents([componentId, &matchedComponent](PowerComponent component) -> bool {
159         if (componentId == toString(component)) {
160             matchedComponent = component;
161             return false;
162         }
163         return true;
164     });
165     return matchedComponent;
166 }
167 
toCustomPowerComponent(const std::unordered_map<std::string,int> & customComponents,const std::string_view & id)168 int toCustomPowerComponent(const std::unordered_map<std::string, int>& customComponents,
169                            const std::string_view& id) {
170     if (customComponents.size() == 0) {
171         return INVALID_CUSTOM_POWER_COMPONENT;
172     }
173     return customComponents.count(std::string(id)) > 0 ? customComponents.at(std::string(id))
174                                                        : INVALID_CUSTOM_POWER_COMPONENT;
175 }
176 
safePtrPrint(const char * ptr)177 const char* safePtrPrint(const char* ptr) {
178     return ptr == nullptr ? "nullptr" : ptr;
179 }
180 
toVehiclePowerState(const char * state)181 int32_t toVehiclePowerState(const char* state) {
182     if (!strcmp(state, kPowerTransitionWaitForVhal)) {
183         return WAIT_FOR_VHAL_STATE;
184     }
185     if (!strcmp(state, kPowerTransitionOn)) {
186         return ON_STATE;
187     }
188     return INVALID_VEHICLE_POWER_STATE;
189 }
190 
isValidPowerState(int32_t state)191 bool isValidPowerState(int32_t state) {
192     return state != INVALID_VEHICLE_POWER_STATE;
193 }
194 
logXmlError(const std::string & errMsg)195 void logXmlError(const std::string& errMsg) {
196     ALOGW("Proceed without registered policies: %s", errMsg.c_str());
197 }
198 
readComponents(const XMLElement * pPolicy,CarPowerPolicyPtr policy,std::unordered_set<PowerComponent> * visited,std::unordered_set<int> * visitedCustomComponents,const std::unordered_map<std::string,int> & customComponents)199 Result<void> readComponents(const XMLElement* pPolicy, CarPowerPolicyPtr policy,
200                             std::unordered_set<PowerComponent>* visited,
201                             std::unordered_set<int>* visitedCustomComponents,
202                             const std::unordered_map<std::string, int>& customComponents) {
203     auto updateVisitedComponents = [](const auto& componentId, auto* visitedComponents) {
204         visitedComponents->insert(componentId);
205     };
206 
207     auto updateComponentState = [](const auto& componentId, const auto& powerState,
208                                    auto* enabledComponents,
209                                    auto* disabledComponents) -> Result<void> {
210         if (!strcmp(powerState, kPowerStateOn)) {
211             enabledComponents->push_back(componentId);
212         } else if (!strcmp(powerState, kPowerStateOff)) {
213             disabledComponents->push_back(componentId);
214         } else {
215             return Error() << StringPrintf("XML configuration has invalid value(%s) in |%s| tag",
216                                            safePtrPrint(powerState), kTagComponent);
217         }
218         return {};
219     };
220     for (const XMLElement* pComponent = pPolicy->FirstChildElement(kTagComponent);
221          pComponent != nullptr; pComponent = pComponent->NextSiblingElement(kTagComponent)) {
222         const char* id;
223         if (pComponent->QueryStringAttribute(kAttrId, &id) != XML_SUCCESS) {
224             return Error() << StringPrintf("Failed to read |%s| attribute in |%s| tag", kAttrId,
225                                            kTagComponent);
226         }
227         PowerComponent componentId = toPowerComponent(id, kPowerComponentPrefix);
228         int customComponentId = INVALID_CUSTOM_POWER_COMPONENT;
229         if (componentId == INVALID_POWER_COMPONENT) {
230             customComponentId = toCustomPowerComponent(customComponents, id);
231         }
232 
233         if (componentId == INVALID_POWER_COMPONENT &&
234             customComponentId == INVALID_CUSTOM_POWER_COMPONENT) {
235             return Error() << StringPrintf("XML configuration has invalid value(%s) in |%s| "
236                                            "attribute of |%s| tag",
237                                            safePtrPrint(id), kAttrId, kTagComponent);
238         }
239 
240         if ((componentId != INVALID_POWER_COMPONENT && visited->count(componentId) > 0) ||
241             (customComponentId != INVALID_CUSTOM_POWER_COMPONENT &&
242              visitedCustomComponents->count(customComponentId) > 0)) {
243             return Error() << StringPrintf("XML configuration has duplicated component(%s) in |%s| "
244                                            "attribute of |%s| tag",
245                                            toString(componentId).c_str(), kAttrId, kTagComponent);
246         }
247 
248         if (componentId != INVALID_POWER_COMPONENT) {
249             updateVisitedComponents(componentId, visited);
250         } else if (customComponentId >= MINIMUM_CUSTOM_COMPONENT_VALUE) {
251             updateVisitedComponents(customComponentId, visitedCustomComponents);
252         }
253 
254         const char* powerState = pComponent->GetText();
255         Result<void> result{};
256         if (componentId != INVALID_POWER_COMPONENT) {
257             result = updateComponentState(componentId, powerState, &policy->enabledComponents,
258                                           &policy->disabledComponents);
259         } else if (customComponentId >= MINIMUM_CUSTOM_COMPONENT_VALUE) {
260             result = updateComponentState(customComponentId, powerState,
261                                           &policy->enabledCustomComponents,
262                                           &policy->disabledCustomComponents);
263         }
264 
265         if (!result.ok()) {
266             return result.error();
267         }
268     }
269     return {};
270 }
271 
readOtherComponents(const XMLElement * pPolicy,CarPowerPolicyPtr policy,const std::unordered_set<PowerComponent> & visited,const std::unordered_map<std::string,int> & customComponents,const std::unordered_set<int> & visitedCustomComponents)272 Result<void> readOtherComponents(const XMLElement* pPolicy, CarPowerPolicyPtr policy,
273                                  const std::unordered_set<PowerComponent>& visited,
274                                  const std::unordered_map<std::string, int>& customComponents,
275                                  const std::unordered_set<int>& visitedCustomComponents) {
276     const char* otherComponentBehavior = kPowerStateUntouched;
277     const XMLElement* pElement = pPolicy->FirstChildElement(kTagOtherComponents);
278     if (pElement != nullptr) {
279         if (pElement->QueryStringAttribute(kAttrBehavior, &otherComponentBehavior) != XML_SUCCESS) {
280             return Error() << StringPrintf("Failed to read |%s| attribute in |%s| tag",
281                                            kAttrBehavior, kTagOtherComponents);
282         }
283     }
284 
285     std::vector<int> customComponentsVector;
286     customComponentsVector.reserve(customComponents.size());
287     std::transform(customComponents.begin(), customComponents.end(),
288                    std::back_inserter(customComponentsVector),
289                    [](const auto& element) { return element.second; });
290 
291     if (!strcmp(otherComponentBehavior, kPowerStateOn)) {
292         iterateAllPowerComponents([&visited, &policy](PowerComponent component) -> bool {
293             if (visited.count(component) == 0) {
294                 policy->enabledComponents.push_back(component);
295             }
296             return true;
297         });
298 
299         std::copy_if(customComponentsVector.begin(), customComponentsVector.end(),
300                      std::back_inserter(policy->enabledCustomComponents),
301                      [&visitedCustomComponents](int componentId) {
302                          return visitedCustomComponents.count(componentId) == 0;
303                      });
304     } else if (!strcmp(otherComponentBehavior, kPowerStateOff)) {
305         iterateAllPowerComponents([&visited, &policy](PowerComponent component) -> bool {
306             if (visited.count(component) == 0) {
307                 policy->disabledComponents.push_back(component);
308             }
309             return true;
310         });
311         std::copy_if(customComponentsVector.begin(), customComponentsVector.end(),
312                      std::back_inserter(policy->disabledCustomComponents),
313                      [&visitedCustomComponents](int componentId) {
314                          return visitedCustomComponents.count(componentId) == 0;
315                      });
316     } else if (!strcmp(otherComponentBehavior, kPowerStateUntouched)) {
317         // Do nothing
318     } else {
319         return Error() << StringPrintf("XML configuration has invalid value(%s) in |%s| attribute "
320                                        "of |%s| tag",
321                                        safePtrPrint(otherComponentBehavior), kAttrBehavior,
322                                        kTagOtherComponents);
323     }
324     return {};
325 }
326 
readPolicies(const XMLElement * pRoot,const char * tag,bool includeOtherComponents,const std::unordered_map<std::string,int> & customComponents)327 Result<std::vector<CarPowerPolicyPtr>> readPolicies(
328         const XMLElement* pRoot, const char* tag, bool includeOtherComponents,
329         const std::unordered_map<std::string, int>& customComponents) {
330     std::vector<CarPowerPolicyPtr> policies;
331     const XMLElement* pPolicies = pRoot->FirstChildElement(tag);
332     if (pPolicies == nullptr) {
333         return std::vector<CarPowerPolicyPtr>();
334     }
335     for (const XMLElement* pPolicy = pPolicies->FirstChildElement(kTagPolicy); pPolicy != nullptr;
336          pPolicy = pPolicy->NextSiblingElement(kTagPolicy)) {
337         std::unordered_set<PowerComponent> visited;
338         std::unordered_set<int> visitedCustomComponents;
339 
340         const char* policyId;
341         if (pPolicy->QueryStringAttribute(kAttrId, &policyId) != XML_SUCCESS) {
342             return Error() << StringPrintf("Failed to read |%s| attribute in |%s| tag", kAttrId,
343                                            kTagPolicy);
344         }
345         if (includeOtherComponents && isSystemPowerPolicy(policyId)) {
346             return Error() << "Policy ID should not start with \"system_power_policy_\"";
347         }
348         auto policy = std::make_shared<CarPowerPolicy>();
349         policy->policyId = policyId;
350 
351         auto ret = readComponents(pPolicy, policy, &visited, &visitedCustomComponents,
352                                   customComponents);
353         if (!ret.ok()) {
354             return ret.error();
355         }
356         if (includeOtherComponents) {
357             ret = readOtherComponents(pPolicy, policy, visited, customComponents,
358                                       visitedCustomComponents);
359             if (!ret.ok()) {
360                 return ret.error();
361             }
362         }
363         policies.push_back(policy);
364     }
365     return policies;
366 }
367 
readPolicyGroup(const XMLElement * pPolicyGroup,const std::unordered_map<std::string,CarPowerPolicyPtr> & registeredPowerPolicies)368 Result<PolicyGroup> readPolicyGroup(
369         const XMLElement* pPolicyGroup,
370         const std::unordered_map<std::string, CarPowerPolicyPtr>& registeredPowerPolicies) {
371     PolicyGroup policyGroup;
372     for (const XMLElement* pDefaultPolicy = pPolicyGroup->FirstChildElement(kTagDefaultPolicy);
373          pDefaultPolicy != nullptr;
374          pDefaultPolicy = pDefaultPolicy->NextSiblingElement(kTagDefaultPolicy)) {
375         const char* state;
376         if (pDefaultPolicy->QueryStringAttribute(kAttrState, &state) != XML_SUCCESS) {
377             return Error() << StringPrintf("Failed to read |%s| attribute in |%s| tag", kAttrState,
378                                            kTagDefaultPolicy);
379         }
380         int32_t powerState = toVehiclePowerState(state);
381         if (!isValidPowerState(powerState)) {
382             return Error() << StringPrintf("Target state(%s) is not valid", state);
383         }
384         const char* policyId;
385         if (pDefaultPolicy->QueryStringAttribute(kAttrId, &policyId) != XML_SUCCESS) {
386             return Error() << StringPrintf("Failed to read |%s| attribute in |%s| tag", kAttrId,
387                                            kTagDefaultPolicy);
388         }
389         if (registeredPowerPolicies.count(policyId) == 0) {
390             return Error() << StringPrintf("Policy(id: %s) is not registered", policyId);
391         }
392         policyGroup.emplace(powerState, policyId);
393     }
394     for (const XMLElement* pNoPolicy = pPolicyGroup->FirstChildElement(kTagNoDefaultPolicy);
395          pNoPolicy != nullptr; pNoPolicy = pNoPolicy->NextSiblingElement(kTagNoDefaultPolicy)) {
396         const char* state;
397         if (pNoPolicy->QueryStringAttribute(kAttrState, &state) != XML_SUCCESS) {
398             return Error() << StringPrintf("Failed to read |%s| attribute in |%s| tag", kAttrState,
399                                            kTagNoDefaultPolicy);
400         }
401         int32_t powerState = toVehiclePowerState(state);
402         if (!isValidPowerState(powerState)) {
403             return Error() << StringPrintf("Target state(%s) is not valid", state);
404         }
405         if (policyGroup.count(powerState) > 0) {
406             return Error()
407                     << StringPrintf("Target state(%s) is specified both in |%s| and |%s| tags",
408                                     state, kTagDefaultPolicy, kTagNoDefaultPolicy);
409         }
410     }
411     return policyGroup;
412 }
413 
414 struct PolicyGroups {
415     std::unordered_map<std::string, PolicyGroup> groups;
416     std::string defaultGroup;
417 };
418 
readPolicyGroups(const XMLElement * pRoot,const std::unordered_map<std::string,CarPowerPolicyPtr> & registeredPowerPolicies)419 Result<PolicyGroups> readPolicyGroups(
420         const XMLElement* pRoot,
421         const std::unordered_map<std::string, CarPowerPolicyPtr>& registeredPowerPolicies) {
422     const XMLElement* pPolicyGroups = pRoot->FirstChildElement(kTagPolicyGroups);
423 
424     PolicyGroups policyGroups;
425 
426     if (pPolicyGroups == nullptr) {
427         return policyGroups;
428     }
429 
430     const char* pDefaultPolicyGroupId = nullptr;
431     pPolicyGroups->QueryStringAttribute(kAttrDefaultPolicyGroup, &pDefaultPolicyGroupId);
432     if (pDefaultPolicyGroupId != nullptr) {
433         policyGroups.defaultGroup = pDefaultPolicyGroupId;
434     }
435 
436     for (const XMLElement* pPolicyGroup = pPolicyGroups->FirstChildElement(kTagPolicyGroup);
437          pPolicyGroup != nullptr;
438          pPolicyGroup = pPolicyGroup->NextSiblingElement(kTagPolicyGroup)) {
439         const char* policyGroupId;
440         if (pPolicyGroup->QueryStringAttribute(kAttrId, &policyGroupId) != XML_SUCCESS) {
441             return Error() << StringPrintf("Failed to read |%s| attribute in |%s| tag", kAttrId,
442                                            kTagPolicyGroup);
443         }
444         const auto& policyGroup = readPolicyGroup(pPolicyGroup, registeredPowerPolicies);
445         if (!policyGroup.ok()) {
446             return Error() << policyGroup.error();
447         }
448         policyGroups.groups.emplace(policyGroupId, *policyGroup);
449     }
450     return policyGroups;
451 }
452 
isConfigurableComponent(PowerComponent component)453 bool isConfigurableComponent(PowerComponent component) {
454     return kNoUserInteractionConfigurableComponents.count(component) > 0;
455 }
456 
checkConfigurableComponents(const std::vector<PowerComponent> & components)457 Result<void> checkConfigurableComponents(const std::vector<PowerComponent>& components) {
458     for (auto component : components) {
459         if (!isConfigurableComponent(component)) {
460             return Error()
461                     << StringPrintf("Component(%s) is not configurable in system power policy.",
462                                     toString(component).c_str());
463         }
464     }
465     return {};
466 }
467 
readSystemPolicyOverrides(const XMLElement * pRoot,const std::unordered_map<std::string,int> & customComponents)468 Result<std::vector<CarPowerPolicyPtr>> readSystemPolicyOverrides(
469         const XMLElement* pRoot, const std::unordered_map<std::string, int>& customComponents) {
470     const auto& systemPolicyOverrides =
471             readPolicies(pRoot, kTagSystemPolicyOverrides, false, customComponents);
472     if (!systemPolicyOverrides.ok()) {
473         return Error() << systemPolicyOverrides.error().message();
474     }
475     for (auto policy : *systemPolicyOverrides) {
476         if (policy->policyId != kSystemPolicyIdNoUserInteraction) {
477             return Error() << StringPrintf("System power policy(%s) is not supported.",
478                                            policy->policyId.c_str());
479         }
480         auto ret = checkConfigurableComponents(policy->enabledComponents);
481         if (!ret.ok()) {
482             return ret.error();
483         }
484         ret = checkConfigurableComponents(policy->disabledComponents);
485         if (!ret.ok()) {
486             return ret.error();
487         }
488     }
489     return systemPolicyOverrides;
490 }
491 
readCustomComponents(const XMLElement * pRoot)492 Result<std::unordered_map<std::string, int>> readCustomComponents(const XMLElement* pRoot) {
493     const XMLElement* pCustomComponents = pRoot->FirstChildElement(kTagCustomComponents);
494     std::unordered_map<std::string, int> customComponentsMap;
495 
496     if (pCustomComponents == nullptr) {
497         return {};
498     }
499 
500     for (const XMLElement* pCustomComponent =
501                  pCustomComponents->FirstChildElement(kTagCustomComponent);
502          pCustomComponent != nullptr;
503          pCustomComponent = pCustomComponent->NextSiblingElement(kTagCustomComponent)) {
504         const char* componentName = pCustomComponent->GetText();
505 
506         int value = 0;
507         pCustomComponent->QueryIntAttribute(kAttrValue, &value);
508 
509         if (value < MINIMUM_CUSTOM_COMPONENT_VALUE) {
510             // log error
511             logXmlError(StringPrintf("Component value is not in allowed range. componentName =  "
512                                      "%s, value = %d",
513                                      componentName, value));
514             return Error() << StringPrintf("Component value is not in allowed range");
515         }
516         customComponentsMap.insert({componentName, value});
517     }
518 
519     return customComponentsMap;
520 }
521 
522 // configureComponents assumes that previously validated components are passed.
configureComponents(const std::vector<PowerComponent> & configComponents,std::vector<PowerComponent> * componentsAddedTo,std::vector<PowerComponent> * componentsRemovedFrom)523 void configureComponents(const std::vector<PowerComponent>& configComponents,
524                          std::vector<PowerComponent>* componentsAddedTo,
525                          std::vector<PowerComponent>* componentsRemovedFrom) {
526     for (const auto component : configComponents) {
527         auto it = std::find(componentsAddedTo->begin(), componentsAddedTo->end(), component);
528         if (it == componentsAddedTo->end()) {
529             componentsAddedTo->push_back(component);
530         }
531         it = std::find(componentsRemovedFrom->begin(), componentsRemovedFrom->end(), component);
532         if (it != componentsRemovedFrom->end()) {
533             componentsRemovedFrom->erase(it);
534         }
535     }
536 }
537 
stringsToComponents(const std::vector<std::string> & arr,std::vector<PowerComponent> * components,std::vector<int> * customComponents)538 Result<void> stringsToComponents(const std::vector<std::string>& arr,
539                                  std::vector<PowerComponent>* components,
540                                  std::vector<int>* customComponents) {
541     for (const auto& c : arr) {
542         const char* component = c.c_str();
543         PowerComponent componentId = toPowerComponent(component, "");
544         if (componentId == INVALID_POWER_COMPONENT) {
545             int customComponentId = 0;
546             bool result = android::base::ParseInt(component, &customComponentId);
547             if (!result || customComponentId < MINIMUM_CUSTOM_COMPONENT_VALUE) {
548                 return Error() << StringPrintf("%s is not a valid component", component);
549             }
550             customComponents->push_back(customComponentId);
551         } else {
552             components->push_back(componentId);
553         }
554     }
555     return {};
556 }
557 
createPolicy(const char * policyId,const std::vector<PowerComponent> & enabledComponents,const std::vector<PowerComponent> & disabledComponents,const std::vector<int> & enabledCustomComponents,const std::vector<int> & disabledCustomComponents)558 CarPowerPolicyPtr createPolicy(const char* policyId,
559                                const std::vector<PowerComponent>& enabledComponents,
560                                const std::vector<PowerComponent>& disabledComponents,
561                                const std::vector<int>& enabledCustomComponents,
562                                const std::vector<int>& disabledCustomComponents) {
563     CarPowerPolicyPtr policy = std::make_shared<CarPowerPolicy>();
564     policy->policyId = policyId;
565     policy->enabledComponents = enabledComponents;
566     policy->disabledComponents = disabledComponents;
567     policy->disabledCustomComponents = disabledCustomComponents;
568     policy->enabledCustomComponents = enabledCustomComponents;
569     return policy;
570 }
571 
572 }  // namespace
573 
toString(const std::vector<PowerComponent> & components)574 std::string toString(const std::vector<PowerComponent>& components) {
575     size_t size = components.size();
576     if (size == 0) {
577         return "none";
578     }
579     std::string filterStr = toString(components[0]);
580     for (size_t i = 1; i < size; i++) {
581         StringAppendF(&filterStr, ", %s", toString(components[i]).c_str());
582     }
583     return filterStr;
584 }
585 
toString(const CarPowerPolicy & policy)586 std::string toString(const CarPowerPolicy& policy) {
587     return StringPrintf("%s(enabledComponents: %s, disabledComponents: %s)",
588                         policy.policyId.c_str(), toString(policy.enabledComponents).c_str(),
589                         toString(policy.disabledComponents).c_str());
590 }
591 
isSystemPowerPolicy(const std::string & policyId)592 bool isSystemPowerPolicy(const std::string& policyId) {
593     return StartsWith(policyId, kSystemPolicyPrefix);
594 }
595 
init()596 void PolicyManager::init() {
597     initRegularPowerPolicy(/*override=*/true);
598     mPolicyGroups.clear();
599     initPreemptivePowerPolicy();
600     readPowerPolicyConfiguration();
601 }
602 
getPowerPolicy(const std::string & policyId) const603 Result<CarPowerPolicyMeta> PolicyManager::getPowerPolicy(const std::string& policyId) const {
604     if (mRegisteredPowerPolicies.count(policyId) > 0) {
605         return CarPowerPolicyMeta{
606                 .powerPolicy = mRegisteredPowerPolicies.at(policyId),
607                 .isPreemptive = false,
608         };
609     }
610     if (mPreemptivePowerPolicies.count(policyId) > 0) {
611         return CarPowerPolicyMeta{
612                 .powerPolicy = mPreemptivePowerPolicies.at(policyId),
613                 .isPreemptive = true,
614         };
615     }
616     return Error() << StringPrintf("Power policy(id: %s) is not found", policyId.c_str());
617 }
618 
getDefaultPowerPolicyForState(const std::string & groupId,VehicleApPowerStateReport state) const619 Result<CarPowerPolicyPtr> PolicyManager::getDefaultPowerPolicyForState(
620         const std::string& groupId, VehicleApPowerStateReport state) const {
621     auto groupIdToUse = groupId.empty() ? mDefaultPolicyGroup : groupId;
622 
623     if (mPolicyGroups.count(groupIdToUse) == 0) {
624         return Error() << StringPrintf("Power policy group %s is not found", groupIdToUse.c_str());
625     }
626 
627     PolicyGroup policyGroup = mPolicyGroups.at(groupIdToUse);
628     int32_t key = static_cast<int32_t>(state);
629     if (policyGroup.count(key) == 0) {
630         return Error() << StringPrintf("Policy for %s is not found", toString(state).c_str());
631     }
632     return mRegisteredPowerPolicies.at(policyGroup.at(key));
633 }
634 
isPowerPolicyGroupAvailable(const std::string & groupId) const635 bool PolicyManager::isPowerPolicyGroupAvailable(const std::string& groupId) const {
636     return mPolicyGroups.count(groupId) > 0;
637 }
638 
isPreemptivePowerPolicy(const std::string & policyId) const639 bool PolicyManager::isPreemptivePowerPolicy(const std::string& policyId) const {
640     return mPreemptivePowerPolicies.count(policyId) > 0;
641 }
642 
definePowerPolicy(const std::string & policyId,const std::vector<std::string> & enabledComponents,const std::vector<std::string> & disabledComponents)643 Result<void> PolicyManager::definePowerPolicy(const std::string& policyId,
644                                               const std::vector<std::string>& enabledComponents,
645                                               const std::vector<std::string>& disabledComponents) {
646     if (mRegisteredPowerPolicies.count(policyId) > 0) {
647         return Error() << StringPrintf("%s is already registered", policyId.c_str());
648     }
649     auto policy = std::make_shared<CarPowerPolicy>();
650     policy->policyId = policyId;
651     auto ret = stringsToComponents(enabledComponents, &policy->enabledComponents,
652                                    &policy->enabledCustomComponents);
653     if (!ret.ok()) {
654         return ret;
655     }
656     ret = stringsToComponents(disabledComponents, &policy->disabledComponents,
657                               &policy->disabledCustomComponents);
658     if (!ret.ok()) {
659         return ret;
660     }
661     mRegisteredPowerPolicies.emplace(policyId, policy);
662     return {};
663 }
664 
definePowerPolicyGroup(const std::string & policyGroupId,const std::vector<std::string> & powerPolicyPerState)665 Result<void> PolicyManager::definePowerPolicyGroup(
666         const std::string& policyGroupId, const std::vector<std::string>& powerPolicyPerState) {
667     if (isPowerPolicyGroupAvailable(policyGroupId)) {
668         return Error() << StringPrintf("%s is already registered", policyGroupId.c_str());
669     }
670     if (powerPolicyPerState.size() != 2) {
671         return Error() << StringPrintf(
672                        "Power policies for both WaitForVHAL and On should be given");
673     }
674     PolicyGroup policyGroup;
675     int32_t i = 0;
676     for (const int32_t powerState : {WAIT_FOR_VHAL_STATE, ON_STATE}) {
677         if (const auto& policy = getPowerPolicy(powerPolicyPerState[i]); policy.ok()) {
678             policyGroup[powerState] = powerPolicyPerState[i];
679         } else if (!powerPolicyPerState[i].empty()) {
680             return Error() << StringPrintf(
681                            "Power policy group with unregistered policy cannot be registered");
682         }
683         i++;
684     }
685     mPolicyGroups.emplace(policyGroupId, policyGroup);
686     return {};
687 }
688 
dump(int fd,const Vector<String16> &)689 Result<void> PolicyManager::dump(int fd, const Vector<String16>& /*args*/) {
690     const char* indent = "  ";
691     const char* doubleIndent = "    ";
692     const char* tripleIndent = "      ";
693 
694     WriteStringToFd(StringPrintf("%sRegistered power policies:%s\n", indent,
695                                  mRegisteredPowerPolicies.size() ? "" : " none"),
696                     fd);
697     for (auto& it : mRegisteredPowerPolicies) {
698         WriteStringToFd(StringPrintf("%s- %s\n", doubleIndent, toString(*it.second).c_str()), fd);
699     }
700     WriteStringToFd(StringPrintf("%sPower policy groups:%s\n", indent,
701                                  mPolicyGroups.size() ? "" : " none"),
702                     fd);
703     for (auto& itGroup : mPolicyGroups) {
704         WriteStringToFd(StringPrintf("%s%s\n", doubleIndent, itGroup.first.c_str()), fd);
705         for (auto& itMapping : itGroup.second) {
706             VehicleApPowerStateReport state =
707                     static_cast<VehicleApPowerStateReport>(itMapping.first);
708             WriteStringToFd(StringPrintf("%s- %s --> %s\n", tripleIndent, toString(state).c_str(),
709                                          itMapping.second.c_str()),
710                             fd);
711         }
712     }
713     WriteStringToFd(StringPrintf("%sNo user interaction power policy: %s\n", indent,
714                                  toString(*mPreemptivePowerPolicies.at(
715                                                   kSystemPolicyIdNoUserInteraction))
716                                          .c_str()),
717                     fd);
718     return {};
719 }
720 
getDefaultPolicyGroup() const721 std::string PolicyManager::getDefaultPolicyGroup() const {
722     return mDefaultPolicyGroup;
723 }
724 
getCustomComponents() const725 std::vector<int32_t> PolicyManager::getCustomComponents() const {
726     std::vector<int32_t> customComponents;
727     for (const auto& [_, component] : mCustomComponents) {
728         customComponents.push_back(component);
729     }
730 
731     return customComponents;
732 }
733 
getRegisteredPolicies() const734 std::vector<CarPowerPolicy> PolicyManager::getRegisteredPolicies() const {
735     std::vector<CarPowerPolicy> registeredPolicies;
736     auto policyMapToVector =
737             [&registeredPolicies](
738                     const std::unordered_map<std::string, CarPowerPolicyPtr>& policyMap) {
739                 for (const auto& [_, policy] : policyMap) {
740                     registeredPolicies.push_back(*policy);
741                 }
742             };
743     policyMapToVector(mPreemptivePowerPolicies);
744     policyMapToVector(mRegisteredPowerPolicies);
745 
746     return registeredPolicies;
747 }
748 
readPowerPolicyConfiguration()749 void PolicyManager::readPowerPolicyConfiguration() {
750     XMLDocument xmlDoc;
751     xmlDoc.LoadFile(kVendorPolicyFile);
752     if (xmlDoc.ErrorID() != XML_SUCCESS) {
753         logXmlError(StringPrintf("Failed to read and/or parse %s", kVendorPolicyFile));
754         return;
755     }
756     readPowerPolicyFromXml(xmlDoc);
757 }
758 
readPowerPolicyFromXml(const XMLDocument & xmlDoc)759 void PolicyManager::readPowerPolicyFromXml(const XMLDocument& xmlDoc) {
760     const XMLElement* pRootElement = xmlDoc.RootElement();
761     if (!pRootElement || strcmp(pRootElement->Name(), kTagRoot)) {
762         logXmlError(StringPrintf("XML file is not in the required format"));
763         return;
764     }
765 
766     const auto& customComponents = readCustomComponents(pRootElement);
767     if (!customComponents.ok()) {
768         logXmlError(StringPrintf("Reading custom components failed: %s",
769                                  customComponents.error().message().c_str()));
770         return;
771     }
772 
773     mCustomComponents = *customComponents;
774     const auto& registeredPolicies =
775             readPolicies(pRootElement, kTagPolicies, true, mCustomComponents);
776 
777     if (!registeredPolicies.ok()) {
778         logXmlError(StringPrintf("Reading policies failed: %s",
779                                  registeredPolicies.error().message().c_str()));
780         return;
781     }
782     std::unordered_map<std::string, CarPowerPolicyPtr> registeredPoliciesMap;
783     for (auto policy : *registeredPolicies) {
784         registeredPoliciesMap.emplace(policy->policyId, policy);
785     }
786 
787     const auto& policyGroups = readPolicyGroups(pRootElement, registeredPoliciesMap);
788     if (!policyGroups.ok()) {
789         logXmlError(StringPrintf("Reading power policy groups for power state failed: %s",
790                                  policyGroups.error().message().c_str()));
791         return;
792     }
793     const auto& systemPolicyOverrides = readSystemPolicyOverrides(pRootElement, mCustomComponents);
794     if (!systemPolicyOverrides.ok()) {
795         logXmlError(StringPrintf("Reading system power policy overrides failed: %s",
796                                  systemPolicyOverrides.error().message().c_str()));
797         return;
798     }
799 
800     mRegisteredPowerPolicies = registeredPoliciesMap;
801     initRegularPowerPolicy(/*override=*/false);
802     mPolicyGroups = policyGroups->groups;
803     mDefaultPolicyGroup = policyGroups->defaultGroup;
804     // TODO(b/273315694) check if custom components in policies are defined
805     reconstructNoUserInteractionPolicy(*systemPolicyOverrides);
806 }
807 
reconstructNoUserInteractionPolicy(const std::vector<CarPowerPolicyPtr> & policyOverrides)808 void PolicyManager::reconstructNoUserInteractionPolicy(
809         const std::vector<CarPowerPolicyPtr>& policyOverrides) {
810     CarPowerPolicyPtr systemPolicy = mPreemptivePowerPolicies.at(kSystemPolicyIdNoUserInteraction);
811     for (auto policy : policyOverrides) {
812         configureComponents(policy->enabledComponents, &systemPolicy->enabledComponents,
813                             &systemPolicy->disabledComponents);
814         configureComponents(policy->disabledComponents, &systemPolicy->disabledComponents,
815                             &systemPolicy->enabledComponents);
816     }
817 }
818 
initRegularPowerPolicy(bool override)819 void PolicyManager::initRegularPowerPolicy(bool override) {
820     if (override) {
821         mRegisteredPowerPolicies.clear();
822     }
823     mRegisteredPowerPolicies.emplace(kSystemPolicyIdAllOn,
824                                      createPolicy(kSystemPolicyIdAllOn, kAllComponents,
825                                                   kNoComponents, {}, {}));
826 
827     std::vector<PowerComponent> initialOnDisabledComponents;
828     for (const auto component : ::ndk::enum_range<PowerComponent>()) {
829         if (component >= PowerComponent::MINIMUM_CUSTOM_COMPONENT_VALUE) {
830             continue;
831         }
832         if (std::find(kInitialOnComponents.begin(), kInitialOnComponents.end(), component) ==
833             kInitialOnComponents.end()) {
834             initialOnDisabledComponents.push_back(component);
835         }
836     }
837     mRegisteredPowerPolicies.emplace(kSystemPolicyIdInitialOn,
838                                      createPolicy(kSystemPolicyIdInitialOn, kInitialOnComponents,
839                                                   initialOnDisabledComponents, {}, {}));
840 }
841 
initPreemptivePowerPolicy()842 void PolicyManager::initPreemptivePowerPolicy() {
843     mPreemptivePowerPolicies.clear();
844     mPreemptivePowerPolicies.emplace(kSystemPolicyIdNoUserInteraction,
845                                      createPolicy(kSystemPolicyIdNoUserInteraction,
846                                                   kNoUserInteractionEnabledComponents,
847                                                   kNoUserInteractionDisabledComponents, {}, {}));
848     mPreemptivePowerPolicies.emplace(kSystemPolicyIdSuspendPrep,
849                                      createPolicy(kSystemPolicyIdSuspendPrep, kNoComponents,
850                                                   kSuspendPrepDisabledComponents, {}, {}));
851 }
852 
853 }  // namespace powerpolicy
854 }  // namespace automotive
855 }  // namespace frameworks
856 }  // namespace android
857