• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2020, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "carpowerpolicyd"
18 #define DEBUG false  // STOPSHIP if true.
19 
20 #include "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 
91 constexpr const char kPowerComponentPrefix[] = "POWER_COMPONENT_";
92 constexpr const char kSystemPolicyPrefix[] = "system_power_policy_";
93 
94 // System power policy definition: ID, enabled components, and disabled components.
95 const std::vector<PowerComponent> kNoUserInteractionEnabledComponents =
96         {PowerComponent::WIFI, PowerComponent::CELLULAR, PowerComponent::ETHERNET,
97          PowerComponent::TRUSTED_DEVICE_DETECTION, PowerComponent::CPU};
98 const std::vector<PowerComponent> kNoUserInteractionDisabledComponents =
99         {PowerComponent::AUDIO,
100          PowerComponent::MEDIA,
101          PowerComponent::DISPLAY,
102          PowerComponent::BLUETOOTH,
103          PowerComponent::PROJECTION,
104          PowerComponent::NFC,
105          PowerComponent::INPUT,
106          PowerComponent::VOICE_INTERACTION,
107          PowerComponent::VISUAL_INTERACTION,
108          PowerComponent::LOCATION,
109          PowerComponent::MICROPHONE};
110 const std::vector<PowerComponent> kAllComponents = {PowerComponent::AUDIO,
111                                                     PowerComponent::MEDIA,
112                                                     PowerComponent::DISPLAY,
113                                                     PowerComponent::BLUETOOTH,
114                                                     PowerComponent::WIFI,
115                                                     PowerComponent::CELLULAR,
116                                                     PowerComponent::ETHERNET,
117                                                     PowerComponent::PROJECTION,
118                                                     PowerComponent::NFC,
119                                                     PowerComponent::INPUT,
120                                                     PowerComponent::VOICE_INTERACTION,
121                                                     PowerComponent::VISUAL_INTERACTION,
122                                                     PowerComponent::TRUSTED_DEVICE_DETECTION,
123                                                     PowerComponent::LOCATION,
124                                                     PowerComponent::MICROPHONE,
125                                                     PowerComponent::CPU};
126 const std::vector<PowerComponent> kInitialOnComponents = {PowerComponent::AUDIO,
127                                                           PowerComponent::DISPLAY,
128                                                           PowerComponent::CPU};
129 const std::vector<PowerComponent> kNoComponents;
130 const std::vector<PowerComponent> kSuspendPrepDisabledComponents = {PowerComponent::AUDIO,
131                                                                     PowerComponent::BLUETOOTH,
132                                                                     PowerComponent::WIFI,
133                                                                     PowerComponent::LOCATION,
134                                                                     PowerComponent::MICROPHONE,
135                                                                     PowerComponent::CPU};
136 const std::unordered_set<PowerComponent> kNoUserInteractionConfigurableComponents =
137         {PowerComponent::BLUETOOTH, PowerComponent::NFC, PowerComponent::TRUSTED_DEVICE_DETECTION};
138 
iterateAllPowerComponents(const std::function<bool (PowerComponent)> & processor)139 void iterateAllPowerComponents(const std::function<bool(PowerComponent)>& processor) {
140     for (const auto component : ::ndk::enum_range<PowerComponent>()) {
141         if (component >= PowerComponent::MINIMUM_CUSTOM_COMPONENT_VALUE) {
142             continue;
143         }
144         if (!processor(component)) {
145             break;
146         }
147     }
148 }
149 
toPowerComponent(std::string_view id,std::string_view prefix)150 PowerComponent toPowerComponent(std::string_view id, std::string_view prefix) {
151     if (!StartsWith(id, prefix)) {
152         return INVALID_POWER_COMPONENT;
153     }
154     std::string_view componentId = id.substr(prefix.size());
155     PowerComponent matchedComponent = INVALID_POWER_COMPONENT;
156     iterateAllPowerComponents([componentId, &matchedComponent](PowerComponent component) -> bool {
157         if (componentId == toString(component)) {
158             matchedComponent = component;
159             return false;
160         }
161         return true;
162     });
163     return matchedComponent;
164 }
165 
toCustomPowerComponent(const std::unordered_map<std::string,int> & customComponents,const std::string_view & id)166 int toCustomPowerComponent(const std::unordered_map<std::string, int>& customComponents,
167                            const std::string_view& id) {
168     if (customComponents.size() == 0) {
169         return INVALID_CUSTOM_POWER_COMPONENT;
170     }
171     return customComponents.count(std::string(id)) > 0 ? customComponents.at(std::string(id))
172                                                        : INVALID_CUSTOM_POWER_COMPONENT;
173 }
174 
safePtrPrint(const char * ptr)175 const char* safePtrPrint(const char* ptr) {
176     return ptr == nullptr ? "nullptr" : ptr;
177 }
178 
toVehiclePowerState(const char * state)179 int32_t toVehiclePowerState(const char* state) {
180     if (!strcmp(state, kPowerTransitionWaitForVhal)) {
181         return static_cast<int32_t>(VehicleApPowerStateReport::WAIT_FOR_VHAL);
182     }
183     if (!strcmp(state, kPowerTransitionOn)) {
184         return static_cast<int32_t>(VehicleApPowerStateReport::ON);
185     }
186     return INVALID_VEHICLE_POWER_STATE;
187 }
188 
isValidPowerState(int32_t state)189 bool isValidPowerState(int32_t state) {
190     return state != INVALID_VEHICLE_POWER_STATE;
191 }
192 
logXmlError(const std::string & errMsg)193 void logXmlError(const std::string& errMsg) {
194     ALOGW("Proceed without registered policies: %s", errMsg.c_str());
195 }
196 
readComponents(const XMLElement * pPolicy,CarPowerPolicyPtr policy,std::unordered_set<PowerComponent> * visited,std::unordered_set<int> * visitedCustomComponents,const std::unordered_map<std::string,int> & customComponents)197 Result<void> readComponents(const XMLElement* pPolicy, CarPowerPolicyPtr policy,
198                             std::unordered_set<PowerComponent>* visited,
199                             std::unordered_set<int>* visitedCustomComponents,
200                             const std::unordered_map<std::string, int>& customComponents) {
201     auto updateVisitedComponents = [](const auto& componentId, auto* visitedComponents) {
202         visitedComponents->insert(componentId);
203     };
204 
205     auto updateComponentState = [](const auto& componentId, const auto& powerState,
206                                    auto* enabledComponents,
207                                    auto* disabledComponents) -> Result<void> {
208         if (!strcmp(powerState, kPowerStateOn)) {
209             enabledComponents->push_back(componentId);
210         } else if (!strcmp(powerState, kPowerStateOff)) {
211             disabledComponents->push_back(componentId);
212         } else {
213             return Error() << StringPrintf("XML configuration has invalid value(%s) in |%s| tag",
214                                            safePtrPrint(powerState), kTagComponent);
215         }
216         return {};
217     };
218     for (const XMLElement* pComponent = pPolicy->FirstChildElement(kTagComponent);
219          pComponent != nullptr; pComponent = pComponent->NextSiblingElement(kTagComponent)) {
220         const char* id;
221         if (pComponent->QueryStringAttribute(kAttrId, &id) != XML_SUCCESS) {
222             return Error() << StringPrintf("Failed to read |%s| attribute in |%s| tag", kAttrId,
223                                            kTagComponent);
224         }
225         PowerComponent componentId = toPowerComponent(id, kPowerComponentPrefix);
226         int customComponentId = INVALID_CUSTOM_POWER_COMPONENT;
227         if (componentId == INVALID_POWER_COMPONENT) {
228             customComponentId = toCustomPowerComponent(customComponents, id);
229         }
230 
231         if (componentId == INVALID_POWER_COMPONENT &&
232             customComponentId == INVALID_CUSTOM_POWER_COMPONENT) {
233             return Error() << StringPrintf("XML configuration has invalid value(%s) in |%s| "
234                                            "attribute of |%s| tag",
235                                            safePtrPrint(id), kAttrId, kTagComponent);
236         }
237 
238         if ((componentId != INVALID_POWER_COMPONENT && visited->count(componentId) > 0) ||
239             (customComponentId != INVALID_CUSTOM_POWER_COMPONENT &&
240              visitedCustomComponents->count(customComponentId) > 0)) {
241             return Error() << StringPrintf("XML configuration has duplicated component(%s) in |%s| "
242                                            "attribute of |%s| tag",
243                                            toString(componentId).c_str(), kAttrId, kTagComponent);
244         }
245 
246         if (componentId != INVALID_POWER_COMPONENT) {
247             updateVisitedComponents(componentId, visited);
248         } else if (customComponentId >= MINIMUM_CUSTOM_COMPONENT_VALUE) {
249             updateVisitedComponents(customComponentId, visitedCustomComponents);
250         }
251 
252         const char* powerState = pComponent->GetText();
253         Result<void> result{};
254         if (componentId != INVALID_POWER_COMPONENT) {
255             result = updateComponentState(componentId, powerState, &policy->enabledComponents,
256                                           &policy->disabledComponents);
257         } else if (customComponentId >= MINIMUM_CUSTOM_COMPONENT_VALUE) {
258             result = updateComponentState(customComponentId, powerState,
259                                           &policy->enabledCustomComponents,
260                                           &policy->disabledCustomComponents);
261         }
262 
263         if (!result.ok()) {
264             return result.error();
265         }
266     }
267     return {};
268 }
269 
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)270 Result<void> readOtherComponents(const XMLElement* pPolicy, CarPowerPolicyPtr policy,
271                                  const std::unordered_set<PowerComponent>& visited,
272                                  const std::unordered_map<std::string, int>& customComponents,
273                                  const std::unordered_set<int>& visitedCustomComponents) {
274     const char* otherComponentBehavior = kPowerStateUntouched;
275     const XMLElement* pElement = pPolicy->FirstChildElement(kTagOtherComponents);
276     if (pElement != nullptr) {
277         if (pElement->QueryStringAttribute(kAttrBehavior, &otherComponentBehavior) != XML_SUCCESS) {
278             return Error() << StringPrintf("Failed to read |%s| attribute in |%s| tag",
279                                            kAttrBehavior, kTagOtherComponents);
280         }
281     }
282 
283     std::vector<int> customComponentsVector;
284     customComponentsVector.reserve(customComponents.size());
285     std::transform(customComponents.begin(), customComponents.end(),
286                    std::back_inserter(customComponentsVector),
287                    [](const auto& element) { return element.second; });
288 
289     if (!strcmp(otherComponentBehavior, kPowerStateOn)) {
290         iterateAllPowerComponents([&visited, &policy](PowerComponent component) -> bool {
291             if (visited.count(component) == 0) {
292                 policy->enabledComponents.push_back(component);
293             }
294             return true;
295         });
296 
297         std::copy_if(customComponentsVector.begin(), customComponentsVector.end(),
298                      std::back_inserter(policy->enabledCustomComponents),
299                      [&visitedCustomComponents](int componentId) {
300                          return visitedCustomComponents.count(componentId) == 0;
301                      });
302     } else if (!strcmp(otherComponentBehavior, kPowerStateOff)) {
303         iterateAllPowerComponents([&visited, &policy](PowerComponent component) -> bool {
304             if (visited.count(component) == 0) {
305                 policy->disabledComponents.push_back(component);
306             }
307             return true;
308         });
309         std::copy_if(customComponentsVector.begin(), customComponentsVector.end(),
310                      std::back_inserter(policy->disabledCustomComponents),
311                      [&visitedCustomComponents](int componentId) {
312                          return visitedCustomComponents.count(componentId) == 0;
313                      });
314     } else if (!strcmp(otherComponentBehavior, kPowerStateUntouched)) {
315         // Do nothing
316     } else {
317         return Error() << StringPrintf("XML configuration has invalid value(%s) in |%s| attribute "
318                                        "of |%s| tag",
319                                        safePtrPrint(otherComponentBehavior), kAttrBehavior,
320                                        kTagOtherComponents);
321     }
322     return {};
323 }
324 
readPolicies(const XMLElement * pRoot,const char * tag,bool includeOtherComponents,const std::unordered_map<std::string,int> & customComponents)325 Result<std::vector<CarPowerPolicyPtr>> readPolicies(
326         const XMLElement* pRoot, const char* tag, bool includeOtherComponents,
327         const std::unordered_map<std::string, int>& customComponents) {
328     std::vector<CarPowerPolicyPtr> policies;
329     const XMLElement* pPolicies = pRoot->FirstChildElement(tag);
330     if (pPolicies == nullptr) {
331         return std::vector<CarPowerPolicyPtr>();
332     }
333     for (const XMLElement* pPolicy = pPolicies->FirstChildElement(kTagPolicy); pPolicy != nullptr;
334          pPolicy = pPolicy->NextSiblingElement(kTagPolicy)) {
335         std::unordered_set<PowerComponent> visited;
336         std::unordered_set<int> visitedCustomComponents;
337 
338         const char* policyId;
339         if (pPolicy->QueryStringAttribute(kAttrId, &policyId) != XML_SUCCESS) {
340             return Error() << StringPrintf("Failed to read |%s| attribute in |%s| tag", kAttrId,
341                                            kTagPolicy);
342         }
343         if (includeOtherComponents && isSystemPowerPolicy(policyId)) {
344             return Error() << "Policy ID should not start with \"system_power_policy_\"";
345         }
346         auto policy = std::make_shared<CarPowerPolicy>();
347         policy->policyId = policyId;
348 
349         auto ret = readComponents(pPolicy, policy, &visited, &visitedCustomComponents,
350                                   customComponents);
351         if (!ret.ok()) {
352             return ret.error();
353         }
354         if (includeOtherComponents) {
355             ret = readOtherComponents(pPolicy, policy, visited, customComponents,
356                                       visitedCustomComponents);
357             if (!ret.ok()) {
358                 return ret.error();
359             }
360         }
361         policies.push_back(policy);
362     }
363     return policies;
364 }
365 
readPolicyGroup(const XMLElement * pPolicyGroup,const std::unordered_map<std::string,CarPowerPolicyPtr> & registeredPowerPolicies)366 Result<PolicyGroup> readPolicyGroup(
367         const XMLElement* pPolicyGroup,
368         const std::unordered_map<std::string, CarPowerPolicyPtr>& registeredPowerPolicies) {
369     PolicyGroup policyGroup;
370     for (const XMLElement* pDefaultPolicy = pPolicyGroup->FirstChildElement(kTagDefaultPolicy);
371          pDefaultPolicy != nullptr;
372          pDefaultPolicy = pDefaultPolicy->NextSiblingElement(kTagDefaultPolicy)) {
373         const char* state;
374         if (pDefaultPolicy->QueryStringAttribute(kAttrState, &state) != XML_SUCCESS) {
375             return Error() << StringPrintf("Failed to read |%s| attribute in |%s| tag", kAttrState,
376                                            kTagDefaultPolicy);
377         }
378         int32_t powerState = toVehiclePowerState(state);
379         if (!isValidPowerState(powerState)) {
380             return Error() << StringPrintf("Target state(%s) is not valid", state);
381         }
382         const char* policyId;
383         if (pDefaultPolicy->QueryStringAttribute(kAttrId, &policyId) != XML_SUCCESS) {
384             return Error() << StringPrintf("Failed to read |%s| attribute in |%s| tag", kAttrId,
385                                            kTagDefaultPolicy);
386         }
387         if (registeredPowerPolicies.count(policyId) == 0) {
388             return Error() << StringPrintf("Policy(id: %s) is not registered", policyId);
389         }
390         policyGroup.emplace(powerState, policyId);
391     }
392     for (const XMLElement* pNoPolicy = pPolicyGroup->FirstChildElement(kTagNoDefaultPolicy);
393          pNoPolicy != nullptr; pNoPolicy = pNoPolicy->NextSiblingElement(kTagNoDefaultPolicy)) {
394         const char* state;
395         if (pNoPolicy->QueryStringAttribute(kAttrState, &state) != XML_SUCCESS) {
396             return Error() << StringPrintf("Failed to read |%s| attribute in |%s| tag", kAttrState,
397                                            kTagNoDefaultPolicy);
398         }
399         int32_t powerState = toVehiclePowerState(state);
400         if (!isValidPowerState(powerState)) {
401             return Error() << StringPrintf("Target state(%s) is not valid", state);
402         }
403         if (policyGroup.count(powerState) > 0) {
404             return Error()
405                     << StringPrintf("Target state(%s) is specified both in |%s| and |%s| tags",
406                                     state, kTagDefaultPolicy, kTagNoDefaultPolicy);
407         }
408     }
409     return policyGroup;
410 }
411 
412 struct PolicyGroups {
413     std::unordered_map<std::string, PolicyGroup> groups;
414     std::string defaultGroup;
415 };
416 
readPolicyGroups(const XMLElement * pRoot,const std::unordered_map<std::string,CarPowerPolicyPtr> & registeredPowerPolicies)417 Result<PolicyGroups> readPolicyGroups(
418         const XMLElement* pRoot,
419         const std::unordered_map<std::string, CarPowerPolicyPtr>& registeredPowerPolicies) {
420     const XMLElement* pPolicyGroups = pRoot->FirstChildElement(kTagPolicyGroups);
421 
422     PolicyGroups policyGroups;
423 
424     if (pPolicyGroups == nullptr) {
425         return policyGroups;
426     }
427 
428     const char* pDefaultPolicyGroupId = nullptr;
429     pPolicyGroups->QueryStringAttribute(kAttrDefaultPolicyGroup, &pDefaultPolicyGroupId);
430     if (pDefaultPolicyGroupId != nullptr) {
431         policyGroups.defaultGroup = pDefaultPolicyGroupId;
432     }
433 
434     for (const XMLElement* pPolicyGroup = pPolicyGroups->FirstChildElement(kTagPolicyGroup);
435          pPolicyGroup != nullptr;
436          pPolicyGroup = pPolicyGroup->NextSiblingElement(kTagPolicyGroup)) {
437         const char* policyGroupId;
438         if (pPolicyGroup->QueryStringAttribute(kAttrId, &policyGroupId) != XML_SUCCESS) {
439             return Error() << StringPrintf("Failed to read |%s| attribute in |%s| tag", kAttrId,
440                                            kTagPolicyGroup);
441         }
442         const auto& policyGroup = readPolicyGroup(pPolicyGroup, registeredPowerPolicies);
443         if (!policyGroup.ok()) {
444             return Error() << policyGroup.error();
445         }
446         policyGroups.groups.emplace(policyGroupId, *policyGroup);
447     }
448     return policyGroups;
449 }
450 
isConfigurableComponent(PowerComponent component)451 bool isConfigurableComponent(PowerComponent component) {
452     return kNoUserInteractionConfigurableComponents.count(component) > 0;
453 }
454 
checkConfigurableComponents(const std::vector<PowerComponent> & components)455 Result<void> checkConfigurableComponents(const std::vector<PowerComponent>& components) {
456     for (auto component : components) {
457         if (!isConfigurableComponent(component)) {
458             return Error()
459                     << StringPrintf("Component(%s) is not configurable in system power policy.",
460                                     toString(component).c_str());
461         }
462     }
463     return {};
464 }
465 
readSystemPolicyOverrides(const XMLElement * pRoot,const std::unordered_map<std::string,int> & customComponents)466 Result<std::vector<CarPowerPolicyPtr>> readSystemPolicyOverrides(
467         const XMLElement* pRoot, const std::unordered_map<std::string, int>& customComponents) {
468     const auto& systemPolicyOverrides =
469             readPolicies(pRoot, kTagSystemPolicyOverrides, false, customComponents);
470     if (!systemPolicyOverrides.ok()) {
471         return Error() << systemPolicyOverrides.error().message();
472     }
473     for (auto policy : *systemPolicyOverrides) {
474         if (policy->policyId != kSystemPolicyIdNoUserInteraction) {
475             return Error() << StringPrintf("System power policy(%s) is not supported.",
476                                            policy->policyId.c_str());
477         }
478         auto ret = checkConfigurableComponents(policy->enabledComponents);
479         if (!ret.ok()) {
480             return ret.error();
481         }
482         ret = checkConfigurableComponents(policy->disabledComponents);
483         if (!ret.ok()) {
484             return ret.error();
485         }
486     }
487     return systemPolicyOverrides;
488 }
489 
readCustomComponents(const XMLElement * pRoot)490 Result<std::unordered_map<std::string, int>> readCustomComponents(const XMLElement* pRoot) {
491     const XMLElement* pCustomComponents = pRoot->FirstChildElement(kTagCustomComponents);
492     std::unordered_map<std::string, int> customComponentsMap;
493 
494     if (pCustomComponents == nullptr) {
495         return {};
496     }
497 
498     for (const XMLElement* pCustomComponent =
499                  pCustomComponents->FirstChildElement(kTagCustomComponent);
500          pCustomComponent != nullptr;
501          pCustomComponent = pCustomComponent->NextSiblingElement(kTagCustomComponent)) {
502         const char* componentName = pCustomComponent->GetText();
503 
504         int value = 0;
505         pCustomComponent->QueryIntAttribute(kAttrValue, &value);
506 
507         if (value < MINIMUM_CUSTOM_COMPONENT_VALUE) {
508             // log error
509             logXmlError(StringPrintf("Component value is not in allowed range. componentName =  "
510                                      "%s, value = %d",
511                                      componentName, value));
512             return Error() << StringPrintf("Component value is not in allowed range");
513         }
514         customComponentsMap.insert({componentName, value});
515     }
516 
517     return customComponentsMap;
518 }
519 
520 // configureComponents assumes that previously validated components are passed.
configureComponents(const std::vector<PowerComponent> & configComponents,std::vector<PowerComponent> * componentsAddedTo,std::vector<PowerComponent> * componentsRemovedFrom)521 void configureComponents(const std::vector<PowerComponent>& configComponents,
522                          std::vector<PowerComponent>* componentsAddedTo,
523                          std::vector<PowerComponent>* componentsRemovedFrom) {
524     for (const auto component : configComponents) {
525         auto it = std::find(componentsAddedTo->begin(), componentsAddedTo->end(), component);
526         if (it == componentsAddedTo->end()) {
527             componentsAddedTo->push_back(component);
528         }
529         it = std::find(componentsRemovedFrom->begin(), componentsRemovedFrom->end(), component);
530         if (it != componentsRemovedFrom->end()) {
531             componentsRemovedFrom->erase(it);
532         }
533     }
534 }
535 
stringsToComponents(const std::vector<std::string> & arr,std::vector<PowerComponent> * components,std::vector<int> * customComponents)536 Result<void> stringsToComponents(const std::vector<std::string>& arr,
537                                  std::vector<PowerComponent>* components,
538                                  std::vector<int>* customComponents) {
539     for (const auto& c : arr) {
540         const char* component = c.c_str();
541         PowerComponent componentId = toPowerComponent(component, "");
542         if (componentId == INVALID_POWER_COMPONENT) {
543             int customComponentId = 0;
544             bool result = android::base::ParseInt(component, &customComponentId);
545             if (!result || customComponentId < MINIMUM_CUSTOM_COMPONENT_VALUE) {
546                 return Error() << StringPrintf("%s is not a valid component", component);
547             }
548             customComponents->push_back(customComponentId);
549         } else {
550             components->push_back(componentId);
551         }
552     }
553     return {};
554 }
555 
createPolicy(const char * policyId,const std::vector<PowerComponent> & enabledComponents,const std::vector<PowerComponent> & disabledComponents,const std::vector<int> & enabledCustomComponents,const std::vector<int> & disabledCustomComponents)556 CarPowerPolicyPtr createPolicy(const char* policyId,
557                                const std::vector<PowerComponent>& enabledComponents,
558                                const std::vector<PowerComponent>& disabledComponents,
559                                const std::vector<int>& enabledCustomComponents,
560                                const std::vector<int>& disabledCustomComponents) {
561     CarPowerPolicyPtr policy = std::make_shared<CarPowerPolicy>();
562     policy->policyId = policyId;
563     policy->enabledComponents = enabledComponents;
564     policy->disabledComponents = disabledComponents;
565     policy->disabledCustomComponents = disabledCustomComponents;
566     policy->enabledCustomComponents = enabledCustomComponents;
567     return policy;
568 }
569 
570 }  // namespace
571 
toString(const std::vector<PowerComponent> & components)572 std::string toString(const std::vector<PowerComponent>& components) {
573     size_t size = components.size();
574     if (size == 0) {
575         return "none";
576     }
577     std::string filterStr = toString(components[0]);
578     for (size_t i = 1; i < size; i++) {
579         StringAppendF(&filterStr, ", %s", toString(components[i]).c_str());
580     }
581     return filterStr;
582 }
583 
toString(const CarPowerPolicy & policy)584 std::string toString(const CarPowerPolicy& policy) {
585     return StringPrintf("%s(enabledComponents: %s, disabledComponents: %s)",
586                         policy.policyId.c_str(), toString(policy.enabledComponents).c_str(),
587                         toString(policy.disabledComponents).c_str());
588 }
589 
isSystemPowerPolicy(const std::string & policyId)590 bool isSystemPowerPolicy(const std::string& policyId) {
591     return StartsWith(policyId, kSystemPolicyPrefix);
592 }
593 
init()594 void PolicyManager::init() {
595     initRegularPowerPolicy(/*override=*/true);
596     mPolicyGroups.clear();
597     initPreemptivePowerPolicy();
598     readPowerPolicyConfiguration();
599 }
600 
getPowerPolicy(const std::string & policyId) const601 Result<CarPowerPolicyMeta> PolicyManager::getPowerPolicy(const std::string& policyId) const {
602     if (mRegisteredPowerPolicies.count(policyId) > 0) {
603         return CarPowerPolicyMeta{
604                 .powerPolicy = mRegisteredPowerPolicies.at(policyId),
605                 .isPreemptive = false,
606         };
607     }
608     if (mPreemptivePowerPolicies.count(policyId) > 0) {
609         return CarPowerPolicyMeta{
610                 .powerPolicy = mPreemptivePowerPolicies.at(policyId),
611                 .isPreemptive = true,
612         };
613     }
614     return Error() << StringPrintf("Power policy(id: %s) is not found", policyId.c_str());
615 }
616 
getDefaultPowerPolicyForState(const std::string & groupId,VehicleApPowerStateReport state) const617 Result<CarPowerPolicyPtr> PolicyManager::getDefaultPowerPolicyForState(
618         const std::string& groupId, VehicleApPowerStateReport state) const {
619     auto groupIdToUse = groupId.empty() ? mDefaultPolicyGroup : groupId;
620 
621     if (mPolicyGroups.count(groupIdToUse) == 0) {
622         return Error() << StringPrintf("Power policy group %s is not found", groupIdToUse.c_str());
623     }
624 
625     PolicyGroup policyGroup = mPolicyGroups.at(groupIdToUse);
626     int32_t key = static_cast<int32_t>(state);
627     if (policyGroup.count(key) == 0) {
628         return Error() << StringPrintf("Policy for %s is not found", toString(state).c_str());
629     }
630     return mRegisteredPowerPolicies.at(policyGroup.at(key));
631 }
632 
isPowerPolicyGroupAvailable(const std::string & groupId) const633 bool PolicyManager::isPowerPolicyGroupAvailable(const std::string& groupId) const {
634     return mPolicyGroups.count(groupId) > 0;
635 }
636 
isPreemptivePowerPolicy(const std::string & policyId) const637 bool PolicyManager::isPreemptivePowerPolicy(const std::string& policyId) const {
638     return mPreemptivePowerPolicies.count(policyId) > 0;
639 }
640 
definePowerPolicy(const std::string & policyId,const std::vector<std::string> & enabledComponents,const std::vector<std::string> & disabledComponents)641 Result<void> PolicyManager::definePowerPolicy(const std::string& policyId,
642                                               const std::vector<std::string>& enabledComponents,
643                                               const std::vector<std::string>& disabledComponents) {
644     if (mRegisteredPowerPolicies.count(policyId) > 0) {
645         return Error() << StringPrintf("%s is already registered", policyId.c_str());
646     }
647     auto policy = std::make_shared<CarPowerPolicy>();
648     policy->policyId = policyId;
649     auto ret = stringsToComponents(enabledComponents, &policy->enabledComponents,
650                                    &policy->enabledCustomComponents);
651     if (!ret.ok()) {
652         return ret;
653     }
654     ret = stringsToComponents(disabledComponents, &policy->disabledComponents,
655                               &policy->disabledCustomComponents);
656     if (!ret.ok()) {
657         return ret;
658     }
659     mRegisteredPowerPolicies.emplace(policyId, policy);
660     return {};
661 }
662 
dump(int fd,const Vector<String16> &)663 Result<void> PolicyManager::dump(int fd, const Vector<String16>& /*args*/) {
664     const char* indent = "  ";
665     const char* doubleIndent = "    ";
666     const char* tripleIndent = "      ";
667 
668     WriteStringToFd(StringPrintf("%sRegistered power policies:%s\n", indent,
669                                  mRegisteredPowerPolicies.size() ? "" : " none"),
670                     fd);
671     for (auto& it : mRegisteredPowerPolicies) {
672         WriteStringToFd(StringPrintf("%s- %s\n", doubleIndent, toString(*it.second).c_str()), fd);
673     }
674     WriteStringToFd(StringPrintf("%sPower policy groups:%s\n", indent,
675                                  mPolicyGroups.size() ? "" : " none"),
676                     fd);
677     for (auto& itGroup : mPolicyGroups) {
678         WriteStringToFd(StringPrintf("%s%s\n", doubleIndent, itGroup.first.c_str()), fd);
679         for (auto& itMapping : itGroup.second) {
680             VehicleApPowerStateReport state =
681                     static_cast<VehicleApPowerStateReport>(itMapping.first);
682             WriteStringToFd(StringPrintf("%s- %s --> %s\n", tripleIndent, toString(state).c_str(),
683                                          itMapping.second.c_str()),
684                             fd);
685         }
686     }
687     WriteStringToFd(StringPrintf("%sNo user interaction power policy: %s\n", indent,
688                                  toString(*mPreemptivePowerPolicies.at(
689                                                   kSystemPolicyIdNoUserInteraction))
690                                          .c_str()),
691                     fd);
692     return {};
693 }
694 
readPowerPolicyConfiguration()695 void PolicyManager::readPowerPolicyConfiguration() {
696     XMLDocument xmlDoc;
697     xmlDoc.LoadFile(kVendorPolicyFile);
698     if (xmlDoc.ErrorID() != XML_SUCCESS) {
699         logXmlError(StringPrintf("Failed to read and/or parse %s", kVendorPolicyFile));
700         return;
701     }
702     readPowerPolicyFromXml(xmlDoc);
703 }
704 
readPowerPolicyFromXml(const XMLDocument & xmlDoc)705 void PolicyManager::readPowerPolicyFromXml(const XMLDocument& xmlDoc) {
706     const XMLElement* pRootElement = xmlDoc.RootElement();
707     if (!pRootElement || strcmp(pRootElement->Name(), kTagRoot)) {
708         logXmlError(StringPrintf("XML file is not in the required format"));
709         return;
710     }
711 
712     const auto& customComponents = readCustomComponents(pRootElement);
713     if (!customComponents.ok()) {
714         logXmlError(StringPrintf("Reading custom components failed: %s",
715                                  customComponents.error().message().c_str()));
716         return;
717     }
718 
719     mCustomComponents = *customComponents;
720     const auto& registeredPolicies =
721             readPolicies(pRootElement, kTagPolicies, true, mCustomComponents);
722 
723     if (!registeredPolicies.ok()) {
724         logXmlError(StringPrintf("Reading policies failed: %s",
725                                  registeredPolicies.error().message().c_str()));
726         return;
727     }
728     std::unordered_map<std::string, CarPowerPolicyPtr> registeredPoliciesMap;
729     for (auto policy : *registeredPolicies) {
730         registeredPoliciesMap.emplace(policy->policyId, policy);
731     }
732 
733     const auto& policyGroups = readPolicyGroups(pRootElement, registeredPoliciesMap);
734     if (!policyGroups.ok()) {
735         logXmlError(StringPrintf("Reading power policy groups for power state failed: %s",
736                                  policyGroups.error().message().c_str()));
737         return;
738     }
739     const auto& systemPolicyOverrides = readSystemPolicyOverrides(pRootElement, mCustomComponents);
740     if (!systemPolicyOverrides.ok()) {
741         logXmlError(StringPrintf("Reading system power policy overrides failed: %s",
742                                  systemPolicyOverrides.error().message().c_str()));
743         return;
744     }
745 
746     mRegisteredPowerPolicies = registeredPoliciesMap;
747     initRegularPowerPolicy(/*override=*/false);
748     mPolicyGroups = policyGroups->groups;
749     mDefaultPolicyGroup = policyGroups->defaultGroup;
750     // TODO(b/273315694) check if custom components in policies are defined
751     reconstructNoUserInteractionPolicy(*systemPolicyOverrides);
752 }
753 
reconstructNoUserInteractionPolicy(const std::vector<CarPowerPolicyPtr> & policyOverrides)754 void PolicyManager::reconstructNoUserInteractionPolicy(
755         const std::vector<CarPowerPolicyPtr>& policyOverrides) {
756     CarPowerPolicyPtr systemPolicy = mPreemptivePowerPolicies.at(kSystemPolicyIdNoUserInteraction);
757     for (auto policy : policyOverrides) {
758         configureComponents(policy->enabledComponents, &systemPolicy->enabledComponents,
759                             &systemPolicy->disabledComponents);
760         configureComponents(policy->disabledComponents, &systemPolicy->disabledComponents,
761                             &systemPolicy->enabledComponents);
762     }
763 }
764 
initRegularPowerPolicy(bool override)765 void PolicyManager::initRegularPowerPolicy(bool override) {
766     if (override) {
767         mRegisteredPowerPolicies.clear();
768     }
769     mRegisteredPowerPolicies.emplace(kSystemPolicyIdAllOn,
770                                      createPolicy(kSystemPolicyIdAllOn, kAllComponents,
771                                                   kNoComponents, {}, {}));
772 
773     std::vector<PowerComponent> initialOnDisabledComponents;
774     for (const auto component : ::ndk::enum_range<PowerComponent>()) {
775         if (component >= PowerComponent::MINIMUM_CUSTOM_COMPONENT_VALUE) {
776             continue;
777         }
778         if (std::find(kInitialOnComponents.begin(), kInitialOnComponents.end(), component) ==
779             kInitialOnComponents.end()) {
780             initialOnDisabledComponents.push_back(component);
781         }
782     }
783     mRegisteredPowerPolicies.emplace(kSystemPolicyIdInitialOn,
784                                      createPolicy(kSystemPolicyIdInitialOn, kInitialOnComponents,
785                                                   initialOnDisabledComponents, {}, {}));
786 }
787 
initPreemptivePowerPolicy()788 void PolicyManager::initPreemptivePowerPolicy() {
789     mPreemptivePowerPolicies.clear();
790     mPreemptivePowerPolicies.emplace(kSystemPolicyIdNoUserInteraction,
791                                      createPolicy(kSystemPolicyIdNoUserInteraction,
792                                                   kNoUserInteractionEnabledComponents,
793                                                   kNoUserInteractionDisabledComponents, {}, {}));
794     mPreemptivePowerPolicies.emplace(kSystemPolicyIdSuspendPrep,
795                                      createPolicy(kSystemPolicyIdSuspendPrep, kNoComponents,
796                                                   kSuspendPrepDisabledComponents, {}, {}));
797 }
798 
getDefaultPolicyGroup() const799 std::string PolicyManager::getDefaultPolicyGroup() const {
800     return mDefaultPolicyGroup;
801 }
802 
803 }  // namespace powerpolicy
804 }  // namespace automotive
805 }  // namespace frameworks
806 }  // namespace android
807