• 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_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 }
29 
CheckStandard()30 bool ThermalConfigSensorCluster::CheckStandard()
31 {
32     if (sensorInfolist_.empty()) {
33         THERMAL_HILOGE(COMP_SVC, "sensor info is empty");
34         return false;
35     }
36     uint32_t expectedLevSize = static_cast<uint32_t>(sensorInfolist_.begin()->second.size());
37     for (auto sensorInfo = sensorInfolist_.begin(); sensorInfo != sensorInfolist_.end(); ++sensorInfo) {
38         uint32_t actualLevSize = static_cast<uint32_t>(sensorInfo->second.size());
39         if (actualLevSize != expectedLevSize) {
40             THERMAL_HILOGE(COMP_SVC, "sensor [%{public}s] lev size mismatch", sensorInfo->first.c_str());
41             return false;
42         }
43         for (uint32_t i = 0; i < sensorInfo->second.size(); ++i) {
44             uint32_t expectedLev = i + 1;
45             if (sensorInfo->second.at(i).level != expectedLev) {
46                 THERMAL_HILOGE(COMP_SVC, "sensor [%{public}s] lev mismatch", sensorInfo->first.c_str());
47                 return false;
48             }
49         }
50     }
51     for (auto sensorInfo = auxSensorInfolist_.begin(); sensorInfo != auxSensorInfolist_.end(); ++sensorInfo) {
52         uint32_t actualLevSize = static_cast<uint32_t>(sensorInfo->second.size());
53         if (actualLevSize == 0 || actualLevSize == expectedLevSize) {
54             continue;
55         }
56         THERMAL_HILOGE(COMP_SVC, "sensor [%{public}s] aux lev size mismatch", sensorInfo->first.c_str());
57         return false;
58     }
59     return true;
60 }
61 
UpdateThermalLevel(const TypeTempMap & typeTempInfo)62 void ThermalConfigSensorCluster::UpdateThermalLevel(const TypeTempMap& typeTempInfo)
63 {
64     std::vector<uint32_t> levelList;
65 
66     CalculateSensorLevel(typeTempInfo, levelList);
67 
68     if (levelList.empty()) {
69         return;
70     }
71 
72     latestLevel_ = *std::max_element(levelList.begin(), levelList.end());
73     THERMAL_HILOGD(COMP_SVC, "final latestLevel = %{public}u", latestLevel_);
74 }
75 
CalculateSensorLevel(const TypeTempMap & typeTempInfo,std::vector<uint32_t> & levelList)76 void ThermalConfigSensorCluster::CalculateSensorLevel(const TypeTempMap& typeTempInfo,
77     std::vector<uint32_t>& levelList)
78 {
79     if (sensorInfolist_.empty()) {
80         return;
81     }
82 
83     for (auto sensorInfo = sensorInfolist_.begin(); sensorInfo != sensorInfolist_.end(); ++sensorInfo) {
84         auto iter = typeTempInfo.find(sensorInfo->first);
85         if (iter == typeTempInfo.end()) {
86             continue;
87         }
88         uint32_t level = latestLevel_;
89         if (descFlag_) {
90             DescJudgment(sensorInfo->second, iter->second, level);
91             CheckExtraCondition(typeTempInfo, level);
92             levelList.push_back(level);
93         } else {
94             AscJudgment(sensorInfo->second, iter->second, level);
95             CheckExtraCondition(typeTempInfo, level);
96             levelList.push_back(level);
97         }
98     }
99 }
100 
AscJudgment(std::vector<LevelItem> & levItems,int32_t curTemp,uint32_t & level)101 void ThermalConfigSensorCluster::AscJudgment(std::vector<LevelItem>& levItems, int32_t curTemp, uint32_t& level)
102 {
103     if (level > 0 && level < levItems.size()) {
104         int32_t curDownTemp = levItems.at(level - 1).thresholdClr;
105         int32_t nextUptemp = levItems.at(level).threshold;
106         if (curTemp >= nextUptemp) {
107             for (uint32_t i = level; i < levItems.size(); i++) {
108                 if (curTemp < levItems.at(i).threshold) {
109                     break;
110                 }
111                 level = levItems.at(i).level;
112             }
113         } else if (curTemp < curDownTemp) {
114             for (uint32_t i = level; i >= 1; i--) {
115                 if (curTemp >= levItems.at(i - 1).thresholdClr) {
116                     break;
117                 }
118                 level = levItems.at(i - 1).level - 1;
119             }
120         }
121     } else if (level == levItems.size()) {
122         int32_t curDownTemp = levItems.at(level - 1).thresholdClr;
123         if (curTemp < curDownTemp) {
124             for (uint32_t i = level; i >= 1; i--) {
125                 if (curTemp < levItems.at(i - 1).thresholdClr) {
126                     level = levItems.at(i - 1).level - 1;
127                 } else {
128                     break;
129                 }
130             }
131         }
132     } else {
133         int32_t nextUptemp = levItems.at(level).threshold;
134         if (curTemp >= nextUptemp) {
135             for (uint32_t i = level; i < levItems.size(); i++) {
136                 if (curTemp >= levItems.at(i).threshold) {
137                     level = levItems.at(i).level;
138                 } else {
139                     break;
140                 }
141             }
142         }
143     }
144 }
145 
DescJudgment(std::vector<LevelItem> & levItems,int32_t curTemp,uint32_t & level)146 void ThermalConfigSensorCluster::DescJudgment(std::vector<LevelItem>& levItems, int32_t curTemp, uint32_t& level)
147 {
148     if (level != 0 && level < levItems.size()) {
149         int32_t curDownTemp = levItems.at(level - 1).thresholdClr;
150         int32_t nextUptemp = levItems.at(level).threshold;
151         if (curTemp <= nextUptemp) {
152             for (uint32_t i = level; i < levItems.size(); i++) {
153                 if (curTemp > levItems.at(i).threshold) {
154                     break;
155                 }
156                 level = levItems.at(i).level;
157             }
158         } else if (curTemp > curDownTemp) {
159             for (uint32_t i = level; i >= 1; i--) {
160                 if (curTemp <= levItems.at(i - 1).thresholdClr) {
161                     break;
162                 }
163                 level = levItems.at(i - 1).level - 1;
164             }
165         }
166     } else if (level == levItems.size()) {
167         int32_t curDownTemp = levItems.at(level - 1).thresholdClr;
168         if (curTemp > curDownTemp) {
169             for (uint32_t i = level; i >= 1; i--) {
170                 if (curTemp > levItems.at(i - 1).thresholdClr) {
171                     level = levItems.at(i - 1).level - 1;
172                 } else {
173                     break;
174                 }
175             }
176         }
177     } else {
178         int32_t nextUptemp = levItems.at(level).threshold;
179         if (curTemp <= nextUptemp) {
180             for (uint32_t i = level; i < levItems.size(); i++) {
181                 if (curTemp <= levItems.at(i).threshold) {
182                     level = levItems.at(i).level;
183                 } else {
184                     break;
185                 }
186             }
187         }
188     }
189 }
190 
CheckExtraCondition(const TypeTempMap & typeTempInfo,uint32_t & level)191 void ThermalConfigSensorCluster::CheckExtraCondition(const TypeTempMap& typeTempInfo, uint32_t& level)
192 {
193     if (auxFlag_) {
194         if (!IsAuxSensorTrigger(typeTempInfo, level)) {
195             THERMAL_HILOGD(COMP_SVC, "aux sensor isn't satisfied, fallback");
196         }
197     }
198 
199     if (rateFlag_) {
200         if (!IsTempRateTrigger(level)) {
201             THERMAL_HILOGD(COMP_SVC, "temp rise rate isn't satisfied, fallback");
202         }
203     }
204 }
205 
IsTempRateTrigger(uint32_t & level)206 bool ThermalConfigSensorCluster::IsTempRateTrigger(uint32_t& level)
207 {
208     if (level == 0) {
209         return true;
210     }
211     const auto& rateMap = g_service->GetSubscriber()->GetSensorsRate();
212     for (auto sensorInfo = sensorInfolist_.begin(); sensorInfo != sensorInfolist_.end(); ++sensorInfo) {
213         auto rateIter = rateMap.find(sensorInfo->first);
214         if (rateIter == rateMap.end()) {
215             continue;
216         }
217         for (const auto& levItem : sensorInfo->second) {
218             if (levItem.level != level) {
219                 continue;
220             }
221             if (rateIter->second > levItem.tempRiseRate) {
222                 continue;
223             } else {
224                 level = 0;
225                 return false;
226             }
227         }
228     }
229     return true;
230 }
231 
IsAuxSensorTrigger(const TypeTempMap & typeTempInfo,uint32_t & level)232 bool ThermalConfigSensorCluster::IsAuxSensorTrigger(const TypeTempMap& typeTempInfo, uint32_t& level)
233 {
234     if (level == 0) {
235         return true;
236     }
237     for (auto sensorInfo = auxSensorInfolist_.begin(); sensorInfo != auxSensorInfolist_.end(); ++sensorInfo) {
238         auto auxIter = typeTempInfo.find(sensorInfo->first);
239         if (auxIter == typeTempInfo.end()) {
240             continue;
241         }
242         int32_t lowerTemp = sensorInfo->second.at(level - 1).lowerTemp;
243         int32_t upperTemp = sensorInfo->second.at(level - 1).upperTemp;
244         if (auxIter->second >= lowerTemp && auxIter->second <= upperTemp) {
245             continue;
246         } else {
247             level = 0;
248             return false;
249         }
250     }
251     return true;
252 }
253 
GetCurrentLevel()254 uint32_t ThermalConfigSensorCluster::GetCurrentLevel()
255 {
256     return latestLevel_;
257 }
258 
SetSensorLevelInfo(SensorInfoMap & sensorInfolist)259 void ThermalConfigSensorCluster::SetSensorLevelInfo(SensorInfoMap& sensorInfolist)
260 {
261     sensorInfolist_ = sensorInfolist;
262 }
263 
SetAuxSensorLevelInfo(AuxSensorInfoMap & auxSensorInfolist)264 void ThermalConfigSensorCluster::SetAuxSensorLevelInfo(AuxSensorInfoMap& auxSensorInfolist)
265 {
266     auxSensorInfolist_ = auxSensorInfolist;
267 }
268 
SetDescFlag(bool descflag)269 void ThermalConfigSensorCluster::SetDescFlag(bool descflag)
270 {
271     descFlag_ = descflag;
272 }
273 
SetAuxFlag(bool auxflag)274 void ThermalConfigSensorCluster::SetAuxFlag(bool auxflag)
275 {
276     auxFlag_ = auxflag;
277 }
278 
SetRateFlag(bool rateFlag)279 void ThermalConfigSensorCluster::SetRateFlag(bool rateFlag)
280 {
281     rateFlag_ =  rateFlag;
282 }
283 } // namespace PowerMgr
284 } // namespace OHOS
285