• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 "string_operation.h"
27 
28 using namespace OHOS::AppExecFwk;
29 namespace OHOS {
30 namespace PowerMgr {
31 namespace {
32 auto g_service = DelayedSpSingleton<ThermalService>::GetInstance();
33 TypeTempMap typeTempMap;
34 constexpr const char* LEVEL_PATH = "/data/service/el0/thermal/config/configLevel";
35 const int MAX_PATH = 256;
36 }
37 
ThermalPolicy()38 ThermalPolicy::ThermalPolicy() {};
39 
Init()40 bool ThermalPolicy::Init()
41 {
42     THERMAL_HILOGD(COMP_SVC, "Enter");
43     DumpConfigInfo();
44     SortLevel();
45     if (g_service == nullptr) {
46         return false;
47     }
48     handler_ = g_service->GetHandler();
49     RegisterObserver();
50     return true;
51 }
52 
RegisterObserver()53 void ThermalPolicy::RegisterObserver()
54 {
55     THERMAL_HILOGD(COMP_SVC, "Enter");
56     ThermalObserver::Callback callback = std::bind(&ThermalPolicy::GetSensorInfomation, this, std::placeholders::_1);
57     g_service->GetObserver()->SetRegisterCallback(callback);
58 }
59 
GetSensorInfomation(TypeTempMap info)60 void ThermalPolicy::GetSensorInfomation(TypeTempMap info)
61 {
62     typeTempMap = info;
63 
64     LevelDecision();
65     WriteLevel();
66     PolicyDecision(clusterLevelMap_);
67 }
68 
LevelDecision()69 void ThermalPolicy::LevelDecision()
70 {
71     for (auto cluster = msc_.begin(); cluster != msc_.end(); cluster++) {
72         cluster->second->UpdateThermalLevel(typeTempMap);
73         uint32_t level = cluster->second->GetCurrentLevel();
74         clusterLevelMap_[cluster->first] = level;
75     }
76 }
77 
WriteLevel()78 void ThermalPolicy::WriteLevel()
79 {
80     std::list<uint32_t> levelList;
81     int32_t ret = -1;
82     char levelBuf[MAX_PATH] = {0};
83     for (auto iter = clusterLevelMap_.begin(); iter != clusterLevelMap_.end(); iter++) {
84         levelList.push_back(iter->second);
85     }
86     auto level = *max_element(levelList.begin(), levelList.end());
87 
88     ret = snprintf_s(levelBuf, MAX_PATH, sizeof(levelBuf) - 1, LEVEL_PATH);
89     if (ret < EOK) {
90         return;
91     }
92     std::string valueString = std::to_string(level) + "\n";
93     ret = FileOperation::WriteFile(levelBuf, valueString, valueString.length());
94     if (ret != ERR_OK) {
95         return;
96     }
97 }
98 
PolicyDecision(std::map<std::string,uint32_t> & clusterLevelMap)99 void ThermalPolicy::PolicyDecision(std::map<std::string, uint32_t> &clusterLevelMap)
100 {
101     THERMAL_HILOGD(COMP_SVC, "policySize = %{public}zu, clusterSize = %{public}zu",
102         clusterPolicyMap_.size(), clusterLevelMap.size());
103     for (auto clusterPolicy = clusterPolicyMap_.begin(); clusterPolicy != clusterPolicyMap_.end(); clusterPolicy++) {
104         if (clusterPolicy->first.empty() && clusterPolicy->second.empty()) {
105             continue;
106         }
107         auto clusterIter = clusterLevelMap.find(clusterPolicy->first);
108         if (clusterIter != clusterLevelMap.end()) {
109             for (auto levelAction = clusterPolicy->second.rbegin(); levelAction != clusterPolicy->second.rend();
110                 levelAction++) {
111                 if (clusterIter->second >= levelAction->level) {
112                     ActionDecision(levelAction->vPolicyAction);
113                     break;
114                 }
115             }
116         } else {
117             continue;
118         }
119     }
120 
121     /* Action Execute */
122     if (!ActionExecution()) {
123         THERMAL_HILOGW(COMP_SVC, "failed to execute action");
124         return;
125     }
126 
127     ActionCharger::ExecuteCurrentLimit();
128     ActionVoltage::ExecuteVoltageLimit();
129 }
130 
ActionDecision(std::vector<PolicyAction> & vAction)131 void ThermalPolicy::ActionDecision(std::vector<PolicyAction> &vAction)
132 {
133     THERMAL_HILOGD(COMP_SVC, "action.size=%{public}zu", vAction.size());
134     for (auto action = vAction.begin(); action != vAction.end(); action++) {
135         THERMAL_HILOGD(COMP_SVC, "actionName: %{public}s", action->actionName.c_str());
136         ThermalActionManager::ThermalActionMap actionMap = g_service->GetActionManagerObj()->GetActionMap();
137         auto actionIter = actionMap.find(action->actionName);
138         if (actionIter != actionMap.end()) {
139             THERMAL_HILOGD(COMP_SVC, "action Iter Name = %{public}s", actionIter->first.c_str());
140             if (actionIter->second == nullptr) {
141                 THERMAL_HILOGE(COMP_SVC, "action instance is nullptr");
142                 continue;
143             }
144             if (action->isProp) {
145                 THERMAL_HILOGD(COMP_SVC, "start state decision");
146                 if (StateMachineDecision(action->mActionProp)) {
147                     actionIter->second->AddActionValue(action->actionValue);
148                     actionIter->second->SetXmlScene(action->mActionProp.begin()->second, action->actionValue);
149                 } else {
150                     THERMAL_HILOGW(COMP_SVC, "failed to decide state");
151                 }
152             } else {
153                 THERMAL_HILOGD(COMP_SVC, "add action value");
154                 actionIter->second->AddActionValue(action->actionValue);
155             }
156         } else {
157             THERMAL_HILOGE(COMP_SVC, "failed to find action");
158             continue;
159         }
160     }
161 }
162 
FindSubscribeActionValue()163 void ThermalPolicy::FindSubscribeActionValue()
164 {
165     THERMAL_HILOGD(COMP_SVC, "Enter");
166     if (g_service == nullptr) {
167         THERMAL_HILOGI(COMP_SVC, "g_service is nullptr");
168         return;
169     }
170     if (g_service->GetObserver() ==nullptr) {
171         THERMAL_HILOGI(COMP_SVC, "g_service->GetObserver() is nullptr");
172         return;
173     }
174 
175     g_service->GetObserver()->FindSubscribeActionValue();
176 }
177 
StateMachineDecision(std::map<std::string,std::string> & stateMap)178 bool ThermalPolicy::StateMachineDecision(std::map<std::string, std::string> &stateMap)
179 {
180     THERMAL_HILOGD(COMP_SVC, "Enter");
181     bool ret = true;
182 
183     for (auto prop = stateMap.begin(); prop != stateMap.end(); prop++) {
184         StateMachine::StateMachineMap stateMachineMap = g_service->GetStateMachineObj()->GetStateCollectionMap();
185         auto stateIter = stateMachineMap.find(prop->first);
186         THERMAL_HILOGD(COMP_SVC, "statename = %{public}s stateItername = %{public}s",
187             prop->first.c_str(), stateIter->first.c_str());
188         if (stateIter != stateMachineMap.end()) {
189             if (stateIter->second == nullptr) {
190                 THERMAL_HILOGE(COMP_SVC, "state instance is nullptr");
191                 continue;
192             }
193             if (stateIter->second->DecideState(prop->second)) {
194                 continue;
195             } else {
196                 ret = false;
197                 break;
198             }
199         }
200     }
201     return ret;
202 }
203 
ActionExecution()204 bool ThermalPolicy::ActionExecution()
205 {
206     THERMAL_HILOGD(COMP_SVC, "Enter");
207     auto actionMgr = g_service->GetActionManagerObj();
208     if (actionMgr == nullptr) {
209         return false;
210     }
211 
212     if (!actionFallbackSet_.empty()) {
213         for (auto currentIter = actionFallbackSet_.begin(); currentIter != actionFallbackSet_.end(); currentIter++) {
214             preExecuteList_.insert(*currentIter);
215         }
216         actionFallbackSet_.clear();
217     }
218 
219     ThermalActionManager::ThermalActionMap actionMap = actionMgr->GetActionMap();
220     for (auto iter = actionMap.begin(); iter != actionMap.end(); iter++) {
221         iter->second->Execute();
222         actionFallbackSet_.insert(iter->second);
223     }
224     handler_->SendEvent(ThermalsrvEventHandler::SEND_ACTION_HUB_LISTENER, 0, 0);
225     return true;
226 }
227 
ActionFallbackDecision()228 bool ThermalPolicy::ActionFallbackDecision()
229 {
230     THERMAL_HILOGD(COMP_SVC, "Enter");
231     if (!preExecuteList_.empty()) {
232         for (auto preAction = preExecuteList_.begin(); preAction != preExecuteList_.end(); preAction++) {
233             auto currentAction = actionFallbackSet_.find(*preAction);
234             if (currentAction != actionFallbackSet_.end()) {
235                 (*currentAction)->AddActionValue(FALLBACK_ACTION_VALUE);
236                 (*currentAction)->Execute();
237                 preExecuteList_.erase(preAction);
238                 return true;
239             } else {
240                 return false;
241             }
242         }
243     }
244     return false;
245 }
246 
SortLevel()247 void ThermalPolicy::SortLevel()
248 {
249     THERMAL_HILOGD(COMP_SVC, "Enter");
250     for (auto clusterPolicy = clusterPolicyMap_.begin(); clusterPolicy != clusterPolicyMap_.end(); clusterPolicy++) {
251         sort(clusterPolicy->second.begin(), clusterPolicy->second.end(), LevelCompare);
252     }
253 }
254 
SetPolicyMap(PolicyConfigMap & policyConfigMap)255 void ThermalPolicy::SetPolicyMap(PolicyConfigMap &policyConfigMap)
256 {
257     clusterPolicyMap_ = policyConfigMap;
258 }
259 
SetSensorClusterMap(std::map<std::string,std::shared_ptr<ThermalConfigSensorCluster>> & msc)260 void ThermalPolicy::SetSensorClusterMap(std::map<std::string, std::shared_ptr<ThermalConfigSensorCluster>> &msc)
261 {
262     msc_ = msc;
263 }
264 
GetClusterLevelMap()265 std::map<std::string, uint32_t> ThermalPolicy::GetClusterLevelMap()
266 {
267     return clusterLevelMap_;
268 }
269 
DumpConfigInfo()270 void ThermalPolicy::DumpConfigInfo()
271 {
272     THERMAL_HILOGD(COMP_SVC, "Enter");
273     for (auto cluster : msc_) {
274         THERMAL_HILOGD(COMP_SVC, "name: %{public}s", cluster.first.c_str());
275         for (auto levelinfo : cluster.second->GetSensorInfoList()) {
276             THERMAL_HILOGD(COMP_SVC, "type %{public}s", levelinfo.first.c_str());
277             for (auto item : levelinfo.second) {
278                 THERMAL_HILOGD(COMP_SVC,
279                     "threshold:%{public}d, clr:%{public}d, tempRiseRate:%{public}f, level:%{public}d",
280                     item.threshold, item.thresholdClr, item.tempRiseRate, item.level);
281             }
282         }
283         for (auto auxlevelinfo : cluster.second->GetAuxSensorInfoList()) {
284             THERMAL_HILOGD(COMP_SVC, "type: %{public}s", auxlevelinfo.first.c_str());
285             for (auto item : auxlevelinfo.second) {
286                 THERMAL_HILOGD(COMP_SVC, "lowerTemp: %{public}d, upperTemp: %{public}d",
287                     item.lowerTemp, item.upperTemp);
288             }
289         }
290     }
291 
292     for (auto policy : clusterPolicyMap_) {
293         if (policy.first.empty() && policy.second.empty()) continue;
294         THERMAL_HILOGD(COMP_SVC, "clusterName = %{public}s", policy.first.c_str());
295         for (auto policyConfig : policy.second) {
296             THERMAL_HILOGD(COMP_SVC, "level = %{public}d", policyConfig.level);
297             for (auto action : policyConfig.vPolicyAction) {
298                 THERMAL_HILOGD(COMP_SVC, "actionName = %{public}s, actionValue = %{public}s, prop = %{public}d",
299                     action.actionName.c_str(), action.actionValue.c_str(), action.isProp);
300                 for (auto prop : action.mActionProp) {
301                     THERMAL_HILOGD(COMP_SVC, "propName = %{public}s, propValue = %{public}s",
302                         prop.first.c_str(), prop.second.c_str());
303                 }
304             }
305         }
306     }
307 }
308 } // namespace PowerMgr
309 } // namespace OHOS
310