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