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