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_kernel_policy.h"
17
18
19 #include "thermal_common.h"
20 #include "thermal_device_control.h"
21 #include "thermal_kernel_service.h"
22
23 namespace OHOS {
24 namespace PowerMgr {
25 namespace {
26 auto &g_service = ThermalKernelService::GetInstance();
27 constexpr int32_t NUM_ZERO = 0;
28 }
Init()29 bool ThermalKernelPolicy::Init()
30 {
31 SetCallback();
32 SetMultiples();
33 Dump();
34 return true;
35 }
36
LevelDecision()37 void ThermalKernelPolicy::LevelDecision()
38 {
39 THERMAL_HILOGD(FEATURE_PROTECTOR, "Enter");
40 for (auto tzIter = tzInfoMap_.begin(); tzIter != tzInfoMap_.end(); tzIter++) {
41 auto typeIter = typeTempMap_.find(tzIter->first);
42 if (typeIter != typeTempMap_.end()) {
43 THERMAL_HILOGD(FEATURE_PROTECTOR, "start update thermal level");
44 tzIter->second->UpdateThermalLevel(typeIter->second);
45 uint32_t level = tzIter->second->GetThermalLevel();
46 levelMap_.emplace(std::pair(typeIter->first, level));
47 THERMAL_HILOGI(FEATURE_PROTECTOR, "final level = %{public}d", level);
48 }
49 }
50 }
51
PolicyDecision()52 void ThermalKernelPolicy::PolicyDecision()
53 {
54 THERMAL_HILOGD(FEATURE_PROTECTOR, "Enter");
55 for (auto policy = levelAction_.begin(); policy != levelAction_.end(); policy++) {
56 auto levelIter = levelMap_.find(policy->name);
57 if (levelIter != levelMap_.end()) {
58 if (levelIter->second == policy->level) {
59 ActionDecision(policy->vAction);
60 }
61 }
62 }
63 ActionExecution();
64 }
65
ActionDecision(std::vector<ActionItem> & vAction)66 void ThermalKernelPolicy::ActionDecision(std::vector<ActionItem> &vAction)
67 {
68 THERMAL_HILOGD(FEATURE_PROTECTOR, "Enter");
69 for (auto actionIter = vAction.begin(); actionIter != vAction.end(); actionIter++) {
70 ThermalDeviceControl::ThermalActionMap actionMap = g_service.GetControl()->GetThermalAction();
71 auto nameIter = actionMap.find(actionIter->name);
72 if (nameIter != actionMap.end()) {
73 if (nameIter->second == nullptr) {
74 continue;
75 }
76 nameIter->second->AddActionValue(actionIter->value);
77 executeActionList_.push_back(actionIter->name);
78 }
79 }
80 }
81
ActionExecution()82 void ThermalKernelPolicy::ActionExecution()
83 {
84 THERMAL_HILOGD(FEATURE_PROTECTOR, "Enter");
85
86 if (executeActionList_.empty()) {
87 THERMAL_HILOGI(FEATURE_PROTECTOR, "executeActionList_ is empty");
88 return;
89 }
90
91 ThermalDeviceControl::ThermalActionMap actionMap = g_service.GetControl()->GetThermalAction();
92 THERMAL_HILOGI(FEATURE_PROTECTOR, "size: %{public}zu", actionMap.size());
93 for (auto name : executeActionList_) {
94 auto executeIter = actionMap.find(name);
95 if (executeIter != actionMap.end()) {
96 if (executeIter->second == nullptr) {
97 continue;
98 }
99 executeIter->second->Execute();
100 }
101 }
102 }
103
SetCallback()104 void ThermalKernelPolicy::SetCallback()
105 {
106 ThermalProtectorTimer::NotifyTask task = std::bind(&ThermalKernelPolicy::OnReceivedSensorsInfo,
107 this, std::placeholders::_1);
108 g_service.GetTimer()->RegisterTask(task);
109 }
110
OnReceivedSensorsInfo(SensorsMap typeTempMap)111 void ThermalKernelPolicy::OnReceivedSensorsInfo(SensorsMap typeTempMap)
112 {
113 THERMAL_HILOGD(FEATURE_PROTECTOR, "Enter");
114 typeTempMap_ = typeTempMap;
115 LevelDecision();
116 PolicyDecision();
117 }
118
GetMaxCommonDivisor(int32_t a,int32_t b)119 int32_t ThermalKernelPolicy::GetMaxCommonDivisor(int32_t a, int32_t b)
120 {
121 if (b == 0) {
122 return NUM_ZERO;
123 }
124
125 if (a % b == 0) {
126 return b;
127 } else {
128 return GetMaxCommonDivisor(b, a % b);
129 }
130 }
131
SetMultiples()132 void ThermalKernelPolicy::SetMultiples()
133 {
134 CalculateMaxCd();
135 if (maxCd_ == NUM_ZERO) {
136 return;
137 }
138 for (auto &tzIter : tzInfoMap_) {
139 int32_t multiple = tzIter.second->GetInterval() / maxCd_;
140 tzIter.second->SetMultiple(multiple);
141 }
142 }
143
GetIntervalCommonDivisor(std::vector<int32_t> intervalList)144 int32_t ThermalKernelPolicy::GetIntervalCommonDivisor(std::vector<int32_t> intervalList)
145 {
146 if (intervalList.empty()) {
147 return NUM_ZERO;
148 }
149
150 uint32_t count = intervalList.size();
151 int32_t commonDivisor = intervalList[0];
152 for (uint32_t i = 1; i < count; i++) {
153 commonDivisor = GetMaxCommonDivisor(commonDivisor, intervalList[i]);
154 }
155 return commonDivisor;
156 }
157
CalculateMaxCd()158 void ThermalKernelPolicy::CalculateMaxCd()
159 {
160 std::vector<int32_t> intervalList;
161 if (tzInfoMap_.empty()) {
162 THERMAL_HILOGI(FEATURE_PROTECTOR, "info list is null");
163 }
164 for (auto &tzIter : tzInfoMap_) {
165 int32_t interval = tzIter.second->GetInterval();
166 intervalList.push_back(interval);
167 }
168 maxCd_ = GetIntervalCommonDivisor(intervalList);
169 THERMAL_HILOGI(FEATURE_PROTECTOR, "maxCd_ %{public}d", maxCd_);
170 }
171
SetThermalZoneMap(ThermalZoneMap & tzInfoMap)172 void ThermalKernelPolicy::SetThermalZoneMap(ThermalZoneMap &tzInfoMap)
173 {
174 tzInfoMap_ = tzInfoMap;
175 }
176
SetLevelAction(std::vector<LevelAction> & levelAction)177 void ThermalKernelPolicy::SetLevelAction(std::vector<LevelAction> &levelAction)
178 {
179 levelAction_ = levelAction;
180 }
181
GetThermalZoneMap()182 ThermalKernelPolicy::ThermalZoneMap ThermalKernelPolicy::GetThermalZoneMap()
183 {
184 return tzInfoMap_;
185 }
186
GetLevelAction()187 std::vector<LevelAction> ThermalKernelPolicy::GetLevelAction()
188 {
189 return levelAction_;
190 }
191
GetMaxCd()192 int32_t ThermalKernelPolicy::GetMaxCd()
193 {
194 return maxCd_;
195 }
196
Dump()197 void ThermalKernelPolicy::Dump()
198 {
199 THERMAL_HILOGD(FEATURE_PROTECTOR, "Enter");
200 for (auto &tzIter : tzInfoMap_) {
201 THERMAL_HILOGI(FEATURE_PROTECTOR, "type = %{public}s", tzIter.first.c_str());
202 tzIter.second->Dump();
203 }
204 for (auto &actionIter : levelAction_) {
205 THERMAL_HILOGI(FEATURE_PROTECTOR, "name:%{public}s, level:%{public}d",
206 actionIter.name.c_str(), actionIter.level);
207 for (auto &item : actionIter.vAction) {
208 THERMAL_HILOGI(FEATURE_PROTECTOR, "actionName:%{public}s, actionValue:%{public}d",
209 item.name.c_str(), item.value);
210 }
211 }
212 }
213 } // namespace PowerMgr
214 } // namespace OHOS
215