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