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