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