• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "thermal_policy.h"
17 
18 #include <algorithm>
19 #include "action_charger.h"
20 #include "action_voltage.h"
21 #include "constants.h"
22 #include "file_operation.h"
23 #include "thermal_common.h"
24 #include "thermal_service.h"
25 #include "securec.h"
26 #include "ffrt_utils.h"
27 #include "string_operation.h"
28 
29 using namespace OHOS::AppExecFwk;
30 namespace OHOS {
31 namespace PowerMgr {
32 namespace {
33 auto g_service = DelayedSpSingleton<ThermalService>::GetInstance();
34 constexpr const char* LEVEL_PATH = "/data/service/el0/thermal/config/configLevel";
35 const int MAX_PATH = 256;
36 }
37 
Init()38 bool ThermalPolicy::Init()
39 {
40     SortLevel();
41     if (g_service == nullptr) {
42         return false;
43     }
44     RegisterObserver();
45     return true;
46 }
47 
OnSensorInfoReported(const TypeTempMap & info)48 void ThermalPolicy::OnSensorInfoReported(const TypeTempMap& info)
49 {
50     typeTempMap_ = info;
51 
52     LevelDecision();
53     WriteLevel();
54     PolicyDecision();
55 }
56 
SetPolicyMap(PolicyConfigMap & pcm)57 void ThermalPolicy::SetPolicyMap(PolicyConfigMap& pcm)
58 {
59     clusterPolicyMap_ = pcm;
60 }
61 
SetSensorClusterMap(SensorClusterMap & scm)62 void ThermalPolicy::SetSensorClusterMap(SensorClusterMap& scm)
63 {
64     sensorClusterMap_ = scm;
65 }
66 
GetClusterLevelMap()67 std::map<std::string, uint32_t> ThermalPolicy::GetClusterLevelMap()
68 {
69     return clusterLevelMap_;
70 }
71 
72 
SortLevel()73 void ThermalPolicy::SortLevel()
74 {
75     for (auto clusterPolicy = clusterPolicyMap_.begin(); clusterPolicy != clusterPolicyMap_.end(); clusterPolicy++) {
76         sort(clusterPolicy->second.begin(), clusterPolicy->second.end(), LevelCompare);
77     }
78 }
79 
RegisterObserver()80 void ThermalPolicy::RegisterObserver()
81 {
82     ThermalObserver::Callback callback = std::bind(&ThermalPolicy::OnSensorInfoReported, this, std::placeholders::_1);
83     g_service->GetObserver()->SetRegisterCallback(callback);
84 }
85 
LevelDecision()86 void ThermalPolicy::LevelDecision()
87 {
88     for (auto cluster = sensorClusterMap_.begin(); cluster != sensorClusterMap_.end(); cluster++) {
89         THERMAL_HILOGD(COMP_SVC, "update [%{public}s] level", cluster->first.c_str());
90         cluster->second->UpdateThermalLevel(typeTempMap_);
91         uint32_t level = cluster->second->GetCurrentLevel();
92         clusterLevelMap_[cluster->first] = level;
93     }
94 }
95 
WriteLevel()96 void ThermalPolicy::WriteLevel()
97 {
98     std::list<uint32_t> levelList;
99     int32_t ret = -1;
100     char levelBuf[MAX_PATH] = {0};
101     for (auto iter = clusterLevelMap_.begin(); iter != clusterLevelMap_.end(); iter++) {
102         levelList.push_back(iter->second);
103     }
104     auto level = *max_element(levelList.begin(), levelList.end());
105 
106     ret = snprintf_s(levelBuf, MAX_PATH, sizeof(levelBuf) - 1, LEVEL_PATH);
107     if (ret < EOK) {
108         return;
109     }
110     std::string valueString = std::to_string(level) + "\n";
111     ret = FileOperation::WriteFile(levelBuf, valueString, valueString.length());
112     if (ret != ERR_OK) {
113         return;
114     }
115 }
116 
PolicyDecision()117 void ThermalPolicy::PolicyDecision()
118 {
119     for (auto clusterPolicy = clusterPolicyMap_.begin(); clusterPolicy != clusterPolicyMap_.end(); clusterPolicy++) {
120         const std::string& clusterName = clusterPolicy->first;
121         const std::vector<PolicyConfig>& policyConfig = clusterPolicy->second;
122         if (clusterName.empty() || policyConfig.empty()) {
123             continue;
124         }
125         auto clusterIter = clusterLevelMap_.find(clusterName);
126         if (clusterIter == clusterLevelMap_.end()) {
127             continue;
128         }
129         uint32_t clusterCurrLev = clusterIter->second;
130         for (auto levelAction = policyConfig.rbegin(); levelAction != policyConfig.rend(); levelAction++) {
131             if (clusterCurrLev >= levelAction->level) {
132                 ActionDecision(levelAction->policyActionList);
133                 break;
134             }
135         }
136     }
137 
138     PrintPolicyState();
139 
140     if (!ActionExecution()) {
141         THERMAL_HILOGW(COMP_SVC, "failed to execute action");
142         return;
143     }
144 
145     ActionCharger::ExecuteCurrentLimit();
146     ActionVoltage::ExecuteVoltageLimit();
147 }
148 
ActionDecision(const std::vector<PolicyAction> & actionList)149 void ThermalPolicy::ActionDecision(const std::vector<PolicyAction>& actionList)
150 {
151     for (auto action = actionList.begin(); action != actionList.end(); action++) {
152         ThermalActionManager::ThermalActionMap actionMap = g_service->GetActionManagerObj()->GetActionMap();
153         auto actionIter = actionMap.find(action->actionName);
154         if (actionIter == actionMap.end() || actionIter->second == nullptr) {
155             THERMAL_HILOGE(COMP_SVC, "can't find action [%{public}s] ability", action->actionName.c_str());
156             continue;
157         }
158         if (action->isProp) {
159             if (!StateMachineDecision(action->actionPropMap)) {
160                 continue;
161             }
162             actionIter->second->AddActionValue(action->actionValue);
163             auto it = action->actionPropMap.find(STATE_SCNEN);
164             if (it != action->actionPropMap.end()) {
165                 actionIter->second->SetXmlScene(it->second, action->actionValue);
166             }
167         } else {
168             actionIter->second->AddActionValue(action->actionValue);
169         }
170     }
171 }
172 
FindSubscribeActionValue()173 void ThermalPolicy::FindSubscribeActionValue()
174 {
175     THERMAL_HILOGD(COMP_SVC, "Enter");
176     if (g_service == nullptr) {
177         THERMAL_HILOGI(COMP_SVC, "g_service is nullptr");
178         return;
179     }
180     if (g_service->GetObserver() ==nullptr) {
181         THERMAL_HILOGI(COMP_SVC, "g_service->GetObserver() is nullptr");
182         return;
183     }
184 
185     g_service->GetObserver()->FindSubscribeActionValue();
186 }
187 
StateMachineDecision(const std::map<std::string,std::string> & stateMap)188 bool ThermalPolicy::StateMachineDecision(const std::map<std::string, std::string>& stateMap)
189 {
190     for (auto prop = stateMap.begin(); prop != stateMap.end(); prop++) {
191         StateMachine::StateMachineMap stateMachineMap = g_service->GetStateMachineObj()->GetStateCollectionMap();
192         auto stateIter = stateMachineMap.find(prop->first);
193         if (stateIter == stateMachineMap.end() || stateIter->second == nullptr) {
194             THERMAL_HILOGE(COMP_SVC, "can't find state machine [%{public}s]", prop->first.c_str());
195             return false;
196         }
197         if (stateIter->second->DecideState(prop->second)) {
198             continue;
199         } else {
200             return false;
201         }
202     }
203     return true;
204 }
205 
ActionExecution()206 bool ThermalPolicy::ActionExecution()
207 {
208     auto actionMgr = g_service->GetActionManagerObj();
209     if (actionMgr == nullptr) {
210         return false;
211     }
212 
213     ThermalActionManager::ThermalActionMap actionMap = actionMgr->GetActionMap();
214     for (auto iter = actionMap.begin(); iter != actionMap.end(); iter++) {
215         iter->second->Execute();
216     }
217 
218     FFRTUtils::SubmitTask([this] {
219         return FindSubscribeActionValue();
220     });
221     return true;
222 }
223 
PrintPolicyState()224 void ThermalPolicy::PrintPolicyState()
225 {
226     std::string levInfo = "";
227     for (auto clusterIter = clusterLevelMap_.begin(); clusterIter != clusterLevelMap_.end(); clusterIter++) {
228         levInfo.append(clusterIter->first).append("-").append(std::to_string(clusterIter->second)).append(" ");
229     }
230     THERMAL_HILOGD(COMP_SVC, "current level: %{public}s", levInfo.c_str());
231 }
232 
DumpLevel(std::string & result)233 void ThermalPolicy::DumpLevel(std::string& result)
234 {
235     for (auto iter = clusterLevelMap_.begin(); iter != clusterLevelMap_.end(); ++iter) {
236         result.append("name: ");
237         result.append(iter->first);
238         result.append("\t");
239         result.append("level: ");
240         result.append(std::to_string(iter->second));
241         result.append("\n");
242     }
243 }
244 
PrintPolicyAction(std::vector<PolicyAction> policyActionList,std::string & result)245 void ThermalPolicy::PrintPolicyAction(std::vector<PolicyAction> policyActionList, std::string& result)
246 {
247     for (auto iter = policyActionList.begin(); iter != policyActionList.end(); ++iter) {
248         result.append("actionName: ");
249         result.append(iter->actionName);
250         result.append("\t");
251         result.append("actionValue: ");
252         result.append(iter->actionValue);
253         result.append("\t");
254         for (auto it = iter->actionPropMap.begin(); it != iter->actionPropMap.end(); ++it) {
255             result.append(it->first);
256             result.append(": ");
257             result.append(it->second);
258             result.append("\t");
259         }
260         result.append("isProp: ");
261         result.append(std::to_string(iter->isProp));
262         result.append("\n");
263     }
264 }
265 
DumpPolicy(std::string & result)266 void ThermalPolicy::DumpPolicy(std::string& result)
267 {
268     for (auto iter = clusterPolicyMap_.begin(); iter != clusterPolicyMap_.end(); ++iter) {
269         result.append("name: ");
270         result.append(iter->first);
271         result.append("\t");
272         for (auto it = iter->second.begin(); it != iter->second.end(); ++it) {
273             result.append("level: ");
274             result.append(std::to_string(it->level));
275             result.append("\n");
276             PrintPolicyAction(it->policyActionList, result);
277             result.append("\n");
278         }
279         result.append("\n");
280     }
281 }
282 } // namespace PowerMgr
283 } // namespace OHOS
284