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