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_config_sensor_cluster.h"
17
18 #include <algorithm>
19
20 #include "string_operation.h"
21 #include "thermal_service.h"
22 #include "thermal_common.h"
23
24 namespace OHOS {
25 namespace PowerMgr {
26 namespace {
27 auto g_service = DelayedSpSingleton<ThermalService>::GetInstance();
28 }
Init()29 bool ThermalConfigSensorCluster::Init()
30 {
31 THERMAL_HILOGD(COMP_SVC, "Enter");
32 return true;
33 }
34
Dump()35 void ThermalConfigSensorCluster::Dump()
36 {
37 }
38
UpdateThermalLevel(TypeTempMap & typeTempInfo)39 void ThermalConfigSensorCluster::UpdateThermalLevel(TypeTempMap &typeTempInfo)
40 {
41 uint32_t level = 0;
42 std::vector<uint32_t> levelList;
43 if (auxFlag_) {
44 if (!IsAuxSensorTrigger(typeTempInfo, level)) {
45 THERMAL_HILOGD(COMP_SVC, "all auxiliary sensor not satisfied");
46 }
47 }
48
49 if (rateFlag_) {
50 if (!IsTempRateTrigger(typeTempInfo, level)) {
51 THERMAL_HILOGD(COMP_SVC, "all sensors not satisfied");
52 }
53 }
54
55 CalculateSensorLevel(typeTempInfo, levelList, level);
56
57 if (levelList.empty()) return;
58
59 auto max = std::max_element(levelList.begin(), levelList.end());
60 latestLevel_ = *max;
61 THERMAL_HILOGD(COMP_SVC, "final latestLevel = %{public}d", latestLevel_);
62 isRateMap_.clear();
63 }
64
CalculateSensorLevel(TypeTempMap & typeTempInfo,std::vector<uint32_t> & levelList,uint32_t & level)65 void ThermalConfigSensorCluster::CalculateSensorLevel(TypeTempMap &typeTempInfo,
66 std::vector<uint32_t> &levelList, uint32_t &level)
67 {
68 if (sensorInfolist_.empty()) {
69 return;
70 }
71
72 for (auto sensorInfo = sensorInfolist_.begin(); sensorInfo != sensorInfolist_.end(); ++sensorInfo) {
73 auto iter = typeTempInfo.find(sensorInfo->first);
74 if (iter != typeTempInfo.end()) {
75 level = latestLevel_;
76 if (descFlag_) {
77 DescJudgment(sensorInfo->second, iter->second, level);
78 auto rateItem = isRateMap_.find(sensorInfo->first);
79 if (rateItem != isRateMap_.end()) {
80 if (!rateItem->second) {
81 level = 0;
82 }
83 }
84 if (auxFlag_) {
85 if (IsAuxSensorTrigger(typeTempInfo, level)) {
86 THERMAL_HILOGD(COMP_SVC, "all auxiliary sensor is satisfied");
87 }
88 }
89 levelList.push_back(level);
90 } else {
91 AscJudgment(sensorInfo->second, iter->second, level);
92 auto rateItem = isRateMap_.find(sensorInfo->first);
93 if (rateItem != isRateMap_.end()) {
94 if (!rateItem->second) {
95 level = 0;
96 }
97 }
98 if (auxFlag_) {
99 if (IsAuxSensorTrigger(typeTempInfo, level)) {
100 THERMAL_HILOGD(COMP_SVC, "all auxiliary sensor is satisfied");
101 }
102 }
103 levelList.push_back(level);
104 }
105 } else {
106 continue;
107 }
108 }
109 }
110
CmpValue(const std::pair<std::string,uint32_t> left,const std::pair<std::string,uint32_t> right)111 bool ThermalConfigSensorCluster::CmpValue(const std::pair<std::string, uint32_t> left,
112 const std::pair<std::string, uint32_t> right)
113 {
114 return left.second < right.second;
115 }
116
AscJudgment(std::vector<LevelItem> & vlev,int32_t curTemp,uint32_t & level)117 void ThermalConfigSensorCluster::AscJudgment(std::vector<LevelItem> &vlev, int32_t curTemp, uint32_t &level)
118 {
119 if (level > 0 && level < vlev.size()) {
120 int32_t curDownTemp = vlev.at(level - 1).thresholdClr;
121 int32_t nextUptemp = vlev.at(level).threshold;
122 if (curTemp >= nextUptemp) {
123 for (uint32_t i = level; i < vlev.size(); i++) {
124 if (curTemp >= vlev.at(i).threshold) {
125 level = vlev.at(i).level;
126 } else {
127 break;
128 }
129 }
130 THERMAL_HILOGD(COMP_SVC, "first level = %{public}d", level);
131 } else if (curTemp < curDownTemp) {
132 for (uint32_t i = level; i >= 1; i--) {
133 if (curTemp < vlev.at(i - 1).thresholdClr) {
134 level = vlev.at(i - 1).level - 1;
135 } else {
136 break;
137 }
138 }
139 THERMAL_HILOGD(COMP_SVC, "second level = %{public}d", level);
140 } else {
141 level = vlev.at(level - 1).level;
142 THERMAL_HILOGD(COMP_SVC, "third level = %{public}d", level);
143 }
144 } else if (level == vlev.size()) {
145 int32_t curDownTemp = vlev.at(level - 1).thresholdClr;
146 if (curTemp < curDownTemp) {
147 for (uint32_t i = level; i >= 1; i--) {
148 if (curTemp < vlev.at(i - 1).thresholdClr) {
149 level = vlev.at(i - 1).level - 1;
150 } else {
151 break;
152 }
153 }
154 } else {
155 level = vlev.at(level - 1).level;
156 }
157 THERMAL_HILOGD(COMP_SVC, "fourth level = %{public}d", level);
158 } else if (level == 0) {
159 int32_t nextUptemp = vlev.at(level).threshold;
160 if (curTemp >= nextUptemp) {
161 for (uint32_t i = level; i < vlev.size(); i++) {
162 if (curTemp >= vlev.at(i).threshold) {
163 level = vlev.at(i).level;
164 } else {
165 break;
166 }
167 }
168 } else {
169 level = 0;
170 }
171 THERMAL_HILOGD(COMP_SVC, "fifth level = %{public}d", level);
172 }
173 }
174
DescJudgment(std::vector<LevelItem> & vlev,int32_t curTemp,uint32_t & level)175 void ThermalConfigSensorCluster::DescJudgment(std::vector<LevelItem> &vlev, int32_t curTemp, uint32_t &level)
176 {
177 level = latestLevel_;
178 if (level != 0 && level < vlev.size()) {
179 int32_t curDownTemp = vlev.at(level - 1).thresholdClr;
180 int32_t nextUptemp = vlev.at(level).threshold;
181 if (curTemp <= nextUptemp) {
182 for (uint32_t i = level; i < vlev.size(); i++) {
183 if (curTemp <= vlev.at(i).threshold) {
184 level = vlev.at(i).level;
185 } else {
186 break;
187 }
188 }
189 THERMAL_HILOGD(COMP_SVC, "first level = %{public}d", level);
190 } else if (curTemp > curDownTemp) {
191 for (uint32_t i = level; i >= 1; i--) {
192 if (curTemp > vlev.at(i - 1).thresholdClr) {
193 level = vlev.at(i - 1).level - 1;
194 } else {
195 break;
196 }
197 }
198 THERMAL_HILOGD(COMP_SVC, "second level = %{public}d", level);
199 } else {
200 level = vlev.at(level - 1).level;
201 THERMAL_HILOGD(COMP_SVC, "third level = %{public}d", level);
202 }
203 } else if (level == vlev.size()) {
204 int32_t curDownTemp = vlev.at(level - 1).thresholdClr;
205 if (curTemp > curDownTemp) {
206 for (uint32_t i = level; i >= 1; i--) {
207 if (curTemp > vlev.at(i - 1).thresholdClr) {
208 level = vlev.at(i - 1).level - 1;
209 } else {
210 break;
211 }
212 }
213 } else {
214 level = vlev.at(level - 1).level;
215 }
216 THERMAL_HILOGD(COMP_SVC, "fourth level = %{public}d", level);
217 } else if (level == 0) {
218 int32_t nextUptemp = vlev.at(level).threshold;
219 if (curTemp <= nextUptemp) {
220 for (uint32_t i = level; i < vlev.size(); i++) {
221 if (curTemp <= vlev.at(i).threshold) {
222 level = vlev.at(i).level;
223 } else {
224 break;
225 }
226 }
227 } else {
228 level = 0;
229 }
230 THERMAL_HILOGD(COMP_SVC, "fifth level = %{public}d", level);
231 }
232 }
233
IsTempRateTrigger(TypeTempMap & typeTempInfo,uint32_t & level)234 bool ThermalConfigSensorCluster::IsTempRateTrigger(TypeTempMap &typeTempInfo, uint32_t &level)
235 {
236 bool ret = false;
237 bool allRate = false;
238 auto rateMap = g_service->GetSubscriber()->GetSensorsRate();
239 if (level == 0) return false;
240 for (auto sensorInfo = sensorInfolist_.begin(); sensorInfo != sensorInfolist_.end(); ++sensorInfo) {
241 auto iter = typeTempInfo.find(sensorInfo->first);
242 THERMAL_HILOGD(COMP_SVC, "type:%{public}s temp:%{public}d", iter->first.c_str(), iter->second);
243 if (iter != typeTempInfo.end()) {
244 auto rateIter = rateMap.find(sensorInfo->first);
245 if (rateIter != rateMap.end()) {
246 double configRate = sensorInfo->second.at(level - 1).tempRiseRate;
247 THERMAL_HILOGD(COMP_SVC, "configRate = %{public}f", configRate);
248 if (rateIter->second > configRate) {
249 ret = true;
250 } else {
251 level = 0;
252 ret = false;
253 }
254 }
255 }
256 allRate |= ret;
257 isRateMap_.insert(std::make_pair(sensorInfo->first, ret));
258 }
259 return allRate;
260 }
261
IsAuxSensorTrigger(TypeTempMap & typeTempInfo,uint32_t & level)262 bool ThermalConfigSensorCluster::IsAuxSensorTrigger(TypeTempMap &typeTempInfo, uint32_t &level)
263 {
264 THERMAL_HILOGD(COMP_SVC, "Enter");
265 bool ret = false;
266 bool allAux = false;
267
268 if (level == 0) return false;
269
270 for (auto auxSensorInfo = auxSensorInfolist_.begin(); auxSensorInfo != auxSensorInfolist_.end(); ++auxSensorInfo) {
271 auto auxIter = typeTempInfo.find(auxSensorInfo->first);
272 if (auxIter != typeTempInfo.end()) {
273 int32_t lowerTemp = auxSensorInfo->second.at(level - 1).lowerTemp;
274 int32_t upperTemp = auxSensorInfo->second.at(level - 1).upperTemp;
275 if (auxIter->second >= lowerTemp && auxIter->second <= upperTemp) {
276 ret = true;
277 } else {
278 level = 0;
279 ret = false;
280 }
281 }
282 allAux |= ret;
283 }
284 return allAux;
285 }
286
GetCurrentLevel()287 uint32_t ThermalConfigSensorCluster::GetCurrentLevel()
288 {
289 THERMAL_HILOGD(COMP_SVC, "Enter");
290 std::unique_lock<std::mutex> lock(levelMutex_);
291 return latestLevel_;
292 }
293
GetDescFlag()294 bool ThermalConfigSensorCluster::GetDescFlag()
295 {
296 return descFlag_;
297 }
298
GetAuxFlag()299 bool ThermalConfigSensorCluster::GetAuxFlag()
300 {
301 return auxFlag_;
302 }
303
GetRateFlag()304 bool ThermalConfigSensorCluster::GetRateFlag()
305 {
306 return rateFlag_;
307 }
308
GetSensorInfoList()309 SensorInfoMap ThermalConfigSensorCluster::GetSensorInfoList()
310 {
311 return sensorInfolist_;
312 }
313
GetAuxSensorInfoList()314 AuxSensorInfoMap ThermalConfigSensorCluster::GetAuxSensorInfoList()
315 {
316 return auxSensorInfolist_;
317 }
SetSensorLevelInfo(SensorInfoMap & sensorInfolist)318 void ThermalConfigSensorCluster::SetSensorLevelInfo(SensorInfoMap &sensorInfolist)
319 {
320 sensorInfolist_ = sensorInfolist;
321 }
322
SetAuxSensorLevelInfo(AuxSensorInfoMap & auxSensorInfolist)323 void ThermalConfigSensorCluster::SetAuxSensorLevelInfo(AuxSensorInfoMap &auxSensorInfolist)
324 {
325 auxSensorInfolist_ = auxSensorInfolist;
326 }
327
SetDescFlag(bool descflag)328 void ThermalConfigSensorCluster::SetDescFlag(bool descflag)
329 {
330 descFlag_ = descflag;
331 }
332
SetAuxFlag(bool auxflag)333 void ThermalConfigSensorCluster::SetAuxFlag(bool auxflag)
334 {
335 auxFlag_ = auxflag;
336 }
337
SetRateFlag(bool rateFlag)338 void ThermalConfigSensorCluster::SetRateFlag(bool rateFlag)
339 {
340 rateFlag_ = rateFlag;
341 }
342 } // namespace PowerMgr
343 } // namespace OHOS
344