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
19 
20 #include "PowerComponentHandler.h"
21 
22 #include <android-base/file.h>
23 #include <android-base/stringprintf.h>
24 
25 namespace android {
26 namespace frameworks {
27 namespace automotive {
28 namespace powerpolicy {
29 
30 using ::aidl::android::frameworks::automotive::powerpolicy::CarPowerPolicy;
31 using ::aidl::android::frameworks::automotive::powerpolicy::PowerComponent;
32 
33 using ::android::base::Error;
34 using ::android::base::Result;
35 using ::android::base::StringPrintf;
36 using ::android::base::WriteStringToFd;
37 
init()38 void PowerComponentHandler::init() {
39     Mutex::Autolock lock(mMutex);
40     mAccumulatedPolicy = std::make_shared<CarPowerPolicy>();
41     for (const auto componentId : ::ndk::enum_range<PowerComponent>()) {
42         if (componentId >= PowerComponent::MINIMUM_CUSTOM_COMPONENT_VALUE) {
43             continue;  // skip custom components
44         }
45         mAccumulatedPolicy->disabledComponents.push_back(componentId);
46     }
47 }
48 
applyPowerPolicy(const CarPowerPolicyPtr & powerPolicy)49 void PowerComponentHandler::applyPowerPolicy(const CarPowerPolicyPtr& powerPolicy) {
50     Mutex::Autolock lock(mMutex);
51     std::unordered_map<PowerComponent, bool> componentStates;
52     std::unordered_map<int, bool> customComponentStates;
53 
54     auto setComponentStates = [](auto& map, const auto& componentsVec, auto value) {
55         for (const auto component : componentsVec) {
56             map[component] = value;
57         }
58     };
59 
60     mAccumulatedPolicy->policyId = powerPolicy->policyId;
61     setComponentStates(componentStates, mAccumulatedPolicy->enabledComponents, true);
62     setComponentStates(componentStates, mAccumulatedPolicy->disabledComponents, false);
63     setComponentStates(componentStates, powerPolicy->enabledComponents, true);
64     setComponentStates(componentStates, powerPolicy->disabledComponents, false);
65 
66     setComponentStates(customComponentStates, mAccumulatedPolicy->enabledCustomComponents, true);
67     setComponentStates(customComponentStates, mAccumulatedPolicy->disabledCustomComponents, false);
68     setComponentStates(customComponentStates, powerPolicy->enabledCustomComponents, true);
69     setComponentStates(customComponentStates, powerPolicy->disabledCustomComponents, false);
70 
71     mAccumulatedPolicy->enabledComponents.clear();
72     mAccumulatedPolicy->disabledComponents.clear();
73     mAccumulatedPolicy->enabledCustomComponents.clear();
74     mAccumulatedPolicy->disabledCustomComponents.clear();
75 
76     auto setAccumulatedPolicy = [](auto& statesMap, auto& enabledComponents,
77                                    auto& disabledComponents) {
78         for (const auto [component, state] : statesMap) {
79             if (state) {
80                 enabledComponents.push_back(component);
81             } else {
82                 disabledComponents.push_back(component);
83             }
84         }
85     };
86 
87     setAccumulatedPolicy(componentStates, mAccumulatedPolicy->enabledComponents,
88                          mAccumulatedPolicy->disabledComponents);
89     setAccumulatedPolicy(customComponentStates, mAccumulatedPolicy->enabledCustomComponents,
90                          mAccumulatedPolicy->disabledCustomComponents);
91 }
92 
93 template <typename T>
getComponentState(const T & componentId,const std::vector<T> & enabledComponents,const std::vector<T> & disabledComponents)94 Result<bool> getComponentState(const T& componentId, const std::vector<T>& enabledComponents,
95                                const std::vector<T>& disabledComponents) {
96     auto findComponent = [componentId](const std::vector<T> components) -> bool {
97         return std::find(components.begin(), components.end(), componentId) != components.end();
98     };
99 
100     if (findComponent(enabledComponents)) {
101         return true;
102     }
103     if (findComponent(disabledComponents)) {
104         return false;
105     }
106     return Error() << StringPrintf("Invalid power component(%d)", componentId);
107 }
108 
getCustomPowerComponentState(const int componentId) const109 Result<bool> PowerComponentHandler::getCustomPowerComponentState(const int componentId) const {
110     Mutex::Autolock lock(mMutex);
111 
112     return getComponentState(componentId, mAccumulatedPolicy->enabledCustomComponents,
113                              mAccumulatedPolicy->disabledCustomComponents);
114 }
115 
getPowerComponentState(const PowerComponent componentId) const116 Result<bool> PowerComponentHandler::getPowerComponentState(const PowerComponent componentId) const {
117     Mutex::Autolock lock(mMutex);
118     return getComponentState(componentId, mAccumulatedPolicy->enabledComponents,
119                              mAccumulatedPolicy->disabledComponents);
120 }
121 
getAccumulatedPolicy() const122 CarPowerPolicyPtr PowerComponentHandler::getAccumulatedPolicy() const {
123     Mutex::Autolock lock(mMutex);
124     return mAccumulatedPolicy;
125 }
126 
dump(int fd)127 Result<void> PowerComponentHandler::dump(int fd) {
128     Mutex::Autolock lock(mMutex);
129     const char* indent = "  ";
130     const char* doubleIndent = "    ";
131 
132     auto customComponentToString = [](int component) -> std::string {
133         return std::to_string(component);
134     };
135 
136     auto printComponents = [fd](const auto& components, auto toStringFunc) {
137         bool isNotFirst = false;
138         for (const auto component : components) {
139             if (isNotFirst) {
140                 WriteStringToFd(", ", fd);
141             } else {
142                 isNotFirst = true;
143             }
144             WriteStringToFd(toStringFunc(component), fd);
145         }
146         WriteStringToFd("\n", fd);
147     };
148 
149     WriteStringToFd(StringPrintf("%sCurrent state of power components:\n", indent), fd);
150     WriteStringToFd(StringPrintf("%sEnabled components: ", doubleIndent), fd);
151     printComponents(mAccumulatedPolicy->enabledComponents,
152                     aidl::android::frameworks::automotive::powerpolicy::toString);
153     WriteStringToFd(StringPrintf("%sDisabled components: ", doubleIndent), fd);
154     printComponents(mAccumulatedPolicy->disabledComponents,
155                     aidl::android::frameworks::automotive::powerpolicy::toString);
156     WriteStringToFd(StringPrintf("%sEnabled custom components: ", doubleIndent), fd);
157     printComponents(mAccumulatedPolicy->enabledCustomComponents, customComponentToString);
158     WriteStringToFd(StringPrintf("%sDisabled custom components: ", doubleIndent), fd);
159     printComponents(mAccumulatedPolicy->disabledCustomComponents, customComponentToString);
160 
161     return {};
162 }
163 
164 }  // namespace powerpolicy
165 }  // namespace automotive
166 }  // namespace frameworks
167 }  // namespace android
168