• 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_service_subscriber.h"
17 
18 #include <functional>
19 
20 #include "string_operation.h"
21 #include "thermal_service.h"
22 #include "thermal_common.h"
23 #include "constants.h"
24 namespace OHOS {
25 namespace PowerMgr {
26 namespace {
27 const int32_t SEC_MIN_NUM = 60;
28 const int32_t THERMAL_UPDATE_PERIOD = -5;
29 }
ThermalServiceSubscriber()30 ThermalServiceSubscriber::ThermalServiceSubscriber() { }
31 
Init()32 bool ThermalServiceSubscriber::Init()
33 {
34     auto tms = ThermalService::GetInstance();
35     historyCount_ = tms->GetBaseinfoObj()->GetHistoryTempCount();
36     uint32_t riseRateCount = tms->GetBaseinfoObj()->GetRiseRateCount();
37     rateCount_ = riseRateCount <= 0 ? rateCount_ : riseRateCount;
38     return true;
39 }
40 
OnTemperatureChanged(TypeTempMap typeTempMap)41 void ThermalServiceSubscriber::OnTemperatureChanged(TypeTempMap typeTempMap)
42 {
43     std::lock_guard<std::mutex> lock(mutex_);
44     if (typeTempMap.empty()) {
45         THERMAL_HILOGE(COMP_SVC, "failed to get sensor info: %{public}zu", typeTempMap.size());
46         return;
47     }
48 
49     if (!typeTempMap_.empty()) {
50         typeTempMap_.clear();
51     }
52 
53     for (auto it : typeTempMap) {
54         typeTempMap_[it.first] = it.second;
55     }
56     auto tms = ThermalService::GetInstance();
57     tms->GetSensorInfo()->SetTypeTempMap(typeTempMap_);
58     tms->GetSensorInfo()->NotifyObserver();
59 
60     SetHistoryTypeTempMap(typeTempMap_);
61     return;
62 }
63 
SetHistoryTypeTempMap(TypeTempMap typeTempMap)64 void ThermalServiceSubscriber::SetHistoryTypeTempMap(TypeTempMap typeTempMap)
65 {
66     THERMAL_HILOGD(COMP_SVC, "SetHistoryTypeTempMap: historyCount_=%{public}d, rateCount_=%{public}d",
67         historyCount_, rateCount_);
68     if (historyCount_ <= 1) {
69         return;
70     }
71 
72     for (auto itMap : typeTempMap) {
73         auto iter = typeHistoryMap_.find(itMap.first);
74         if (iter != typeHistoryMap_.end()) {
75             if (iter->second.size() >= historyCount_) {
76                 iter->second.pop_back();
77                 iter->second.push_front(itMap.second);
78             } else {
79                 iter->second.push_front(itMap.second);
80             }
81         } else {
82             std::deque<int32_t> historyTempList;
83             historyTempList.push_front(itMap.second);
84             typeHistoryMap_.insert(std::make_pair(itMap.first, historyTempList));
85         }
86     }
87 
88     for (auto history : typeHistoryMap_) {
89         const auto& item = history.second;
90         double rate = GetThermalRiseRate(item);
91 
92         auto iter = sensorsRateMap_.find(history.first);
93         if (iter != sensorsRateMap_.end()) {
94             if (iter->second.size() >= rateCount_) {
95                 iter->second.pop_front();
96                 iter->second.push_back(rate);
97             } else {
98                 iter->second.push_back(rate);
99             }
100         } else {
101             std::deque<double> historyRateList;
102             historyRateList.push_front(rate);
103             sensorsRateMap_.insert(std::make_pair(history.first, historyRateList));
104         }
105     }
106 }
107 
GetThermalRiseRate(const std::deque<int32_t> & tempQueue)108 double ThermalServiceSubscriber::GetThermalRiseRate(const std::deque<int32_t> &tempQueue)
109 {
110     if (tempQueue.size() < historyCount_) {
111         return 0;
112     }
113     int32_t tempQueueSize = static_cast<int32_t>(tempQueue.size());
114 
115     // yi: tempQueue[i]
116     int32_t time = 0;                   // xi
117     int32_t timeSum = 0;                // sum of xi
118     int32_t tempSum = 0;                // sum of yi
119     int32_t timeSquaredSum = 0;         // sum of xi * xi
120     int32_t timeTempMultiplySum = 0;    // sum of xi * yi
121 
122     for (int32_t timeIndex = 0; timeIndex < tempQueueSize; timeIndex++) {
123         time = timeIndex * THERMAL_UPDATE_PERIOD;
124         timeSum += time;
125         tempSum += tempQueue.at(timeIndex);
126         timeSquaredSum += time * time;
127         timeTempMultiplySum += time * tempQueue.at(timeIndex);
128         THERMAL_HILOGD(COMP_SVC, "GetThermalRiseRate: timeIndex=%{private}u, value=%{private}d", timeIndex,
129             tempQueue.at(timeIndex));
130     }
131     int32_t calcTime = tempQueueSize * timeSquaredSum - timeSum * timeSum;  // (n * sum(xi * xi)) - (sum(xi) * sum(xi))
132     if (calcTime == 0) {
133         return 0;
134     }
135     // (n * sum(xi * yi) - (sum(xi) * sum(yi))) / (n * sum(xi * xi)) - (sum(xi) * sum(xi))
136     double slopeRate = (double)(tempQueueSize * timeTempMultiplySum - timeSum * tempSum) / calcTime;
137 
138     return slopeRate * SEC_MIN_NUM;
139 }
140 } // namespace PowerMgr
141 } // namespace OHOS
142