• 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     LevelDecision();
52     WriteLevel();
53     PolicyDecision();
54 }
55 
ExecutePolicy()56 void ThermalPolicy::ExecutePolicy()
57 {
58     PolicyDecision();
59 }
60 
SetPolicyMap(PolicyConfigMap & pcm)61 void ThermalPolicy::SetPolicyMap(PolicyConfigMap& pcm)
62 {
63     clusterPolicyMap_ = pcm;
64 }
65 
SetSensorClusterMap(SensorClusterMap & scm)66 void ThermalPolicy::SetSensorClusterMap(SensorClusterMap& scm)
67 {
68     sensorClusterMap_ = scm;
69 }
70 
GetClusterLevelMap()71 std::map<std::string, uint32_t> ThermalPolicy::GetClusterLevelMap()
72 {
73     return clusterLevelMap_;
74 }
75 
76 
SortLevel()77 void ThermalPolicy::SortLevel()
78 {
79     for (auto clusterPolicy = clusterPolicyMap_.begin(); clusterPolicy != clusterPolicyMap_.end(); clusterPolicy++) {
80         sort(clusterPolicy->second.begin(), clusterPolicy->second.end(), LevelCompare);
81     }
82 }
83 
RegisterObserver()84 void ThermalPolicy::RegisterObserver()
85 {
86     ThermalObserver::Callback callback = std::bind(&ThermalPolicy::OnSensorInfoReported, this, std::placeholders::_1);
87     g_service->GetObserver()->SetRegisterCallback(callback);
88 }
89 
LevelDecision()90 void ThermalPolicy::LevelDecision()
91 {
92     for (auto cluster = sensorClusterMap_.begin(); cluster != sensorClusterMap_.end(); cluster++) {
93         THERMAL_HILOGD(COMP_SVC, "update [%{public}s] level", cluster->first.c_str());
94         cluster->second->UpdateThermalLevel(typeTempMap_);
95         uint32_t level = cluster->second->GetCurrentLevel();
96         clusterLevelMap_[cluster->first] = level;
97     }
98 }
99 
WriteLevel()100 void ThermalPolicy::WriteLevel()
101 {
102     std::list<uint32_t> levelList;
103     int32_t ret = -1;
104     char levelBuf[MAX_PATH] = {0};
105     for (auto iter = clusterLevelMap_.begin(); iter != clusterLevelMap_.end(); iter++) {
106         levelList.push_back(iter->second);
107     }
108     auto level = *max_element(levelList.begin(), levelList.end());
109 
110     ret = snprintf_s(levelBuf, MAX_PATH, sizeof(levelBuf) - 1, LEVEL_PATH);
111     if (ret < EOK) {
112         return;
113     }
114     std::string valueString = std::to_string(level) + "\n";
115     ret = FileOperation::WriteFile(levelBuf, valueString, valueString.length());
116     if (ret != ERR_OK) {
117         return;
118     }
119 }
120 
PolicyDecision()121 void ThermalPolicy::PolicyDecision()
122 {
123     for (auto clusterPolicy = clusterPolicyMap_.begin(); clusterPolicy != clusterPolicyMap_.end(); clusterPolicy++) {
124         const std::string& clusterName = clusterPolicy->first;
125         const std::vector<PolicyConfig>& policyConfig = clusterPolicy->second;
126         if (clusterName.empty() || policyConfig.empty()) {
127             continue;
128         }
129         auto clusterIter = clusterLevelMap_.find(clusterName);
130         if (clusterIter == clusterLevelMap_.end()) {
131             continue;
132         }
133         uint32_t clusterCurrLev = clusterIter->second;
134         for (auto levelAction = policyConfig.rbegin(); levelAction != policyConfig.rend(); levelAction++) {
135             if (clusterCurrLev >= levelAction->level) {
136                 ActionDecision(levelAction->policyActionList);
137                 break;
138             }
139         }
140     }
141 
142     PrintPolicyState();
143 
144     if (!ActionExecution()) {
145         THERMAL_HILOGW(COMP_SVC, "failed to execute action");
146         return;
147     }
148 
149     ActionCharger::ExecuteCurrentLimit();
150     ActionVoltage::ExecuteVoltageLimit();
151 }
152 
ActionDecision(const std::vector<PolicyAction> & actionList)153 void ThermalPolicy::ActionDecision(const std::vector<PolicyAction>& actionList)
154 {
155     for (auto action = actionList.begin(); action != actionList.end(); action++) {
156         ThermalActionManager::ThermalActionMap actionMap = g_service->GetActionManagerObj()->GetActionMap();
157         auto actionIter = actionMap.find(action->actionName);
158         if (actionIter == actionMap.end() || actionIter->second == nullptr) {
159             THERMAL_HILOGE(COMP_SVC, "can't find action [%{public}s] ability", action->actionName.c_str());
160             continue;
161         }
162         if (action->isProp) {
163             if (!StateMachineDecision(action->actionPropMap)) {
164                 continue;
165             }
166             actionIter->second->AddActionValue(action->actionValue);
167             auto it = action->actionPropMap.find(STATE_SCNEN);
168             if (it != action->actionPropMap.end()) {
169                 actionIter->second->SetXmlScene(it->second, action->actionValue);
170             }
171         } else {
172             actionIter->second->AddActionValue(action->actionValue);
173         }
174     }
175 }
176 
FindSubscribeActionValue()177 void ThermalPolicy::FindSubscribeActionValue()
178 {
179     THERMAL_HILOGD(COMP_SVC, "Enter");
180     if (g_service == nullptr) {
181         THERMAL_HILOGI(COMP_SVC, "g_service is nullptr");
182         return;
183     }
184     if (g_service->GetObserver() ==nullptr) {
185         THERMAL_HILOGI(COMP_SVC, "g_service->GetObserver() is nullptr");
186         return;
187     }
188 
189     g_service->GetObserver()->FindSubscribeActionValue();
190 }
191 
StateMachineDecision(const std::map<std::string,std::string> & stateMap)192 bool ThermalPolicy::StateMachineDecision(const std::map<std::string, std::string>& stateMap)
193 {
194     for (auto prop = stateMap.begin(); prop != stateMap.end(); prop++) {
195         StateMachine::StateMachineMap stateMachineMap = g_service->GetStateMachineObj()->GetStateCollectionMap();
196         auto stateIter = stateMachineMap.find(prop->first);
197         if (stateIter == stateMachineMap.end() || stateIter->second == nullptr) {
198             THERMAL_HILOGE(COMP_SVC, "can't find state machine [%{public}s]", prop->first.c_str());
199             return false;
200         }
201         if (stateIter->second->DecideState(prop->second)) {
202             continue;
203         } else {
204             return false;
205         }
206     }
207     return true;
208 }
209 
ActionExecution()210 bool ThermalPolicy::ActionExecution()
211 {
212     auto actionMgr = g_service->GetActionManagerObj();
213     if (actionMgr == nullptr) {
214         return false;
215     }
216 
217     ThermalActionManager::ThermalActionMap actionMap = actionMgr->GetActionMap();
218     for (auto iter = actionMap.begin(); iter != actionMap.end(); iter++) {
219         iter->second->Execute();
220     }
221 
222     FFRTUtils::SubmitTask([this] {
223         return FindSubscribeActionValue();
224     });
225     return true;
226 }
227 
PrintPolicyState()228 void ThermalPolicy::PrintPolicyState()
229 {
230     std::string levInfo = "";
231     for (auto clusterIter = clusterLevelMap_.begin(); clusterIter != clusterLevelMap_.end(); clusterIter++) {
232         levInfo.append(clusterIter->first).append("-").append(std::to_string(clusterIter->second)).append(" ");
233     }
234     g_service->GetObserver()->UpdatePolicyState(levInfo);
235     THERMAL_HILOGD(COMP_SVC, "current level: %{public}s", levInfo.c_str());
236 }
237 
DumpLevel(std::string & result)238 void ThermalPolicy::DumpLevel(std::string& result)
239 {
240     for (auto iter = clusterLevelMap_.begin(); iter != clusterLevelMap_.end(); ++iter) {
241         result.append("name: ");
242         result.append(iter->first);
243         result.append("\t");
244         result.append("level: ");
245         result.append(std::to_string(iter->second));
246         result.append("\n");
247     }
248 }
249 
PrintPolicyAction(std::vector<PolicyAction> policyActionList,std::string & result)250 void ThermalPolicy::PrintPolicyAction(std::vector<PolicyAction> policyActionList, std::string& result)
251 {
252     for (auto iter = policyActionList.begin(); iter != policyActionList.end(); ++iter) {
253         result.append("actionName: ");
254         result.append(iter->actionName);
255         result.append("\t");
256         result.append("actionValue: ");
257         result.append(iter->actionValue);
258         result.append("\t");
259         for (auto it = iter->actionPropMap.begin(); it != iter->actionPropMap.end(); ++it) {
260             result.append(it->first);
261             result.append(": ");
262             result.append(it->second);
263             result.append("\t");
264         }
265         result.append("isProp: ");
266         result.append(std::to_string(iter->isProp));
267         result.append("\n");
268     }
269 }
270 
DumpPolicy(std::string & result)271 void ThermalPolicy::DumpPolicy(std::string& result)
272 {
273     for (auto iter = clusterPolicyMap_.begin(); iter != clusterPolicyMap_.end(); ++iter) {
274         result.append("name: ");
275         result.append(iter->first);
276         result.append("\t");
277         for (auto it = iter->second.begin(); it != iter->second.end(); ++it) {
278             result.append("level: ");
279             result.append(std::to_string(it->level));
280             result.append("\n");
281             PrintPolicyAction(it->policyActionList, result);
282             result.append("\n");
283         }
284         result.append("\n");
285     }
286 }
287 } // namespace PowerMgr
288 } // namespace OHOS
289