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_observer.h"
17 
18 #include <datetime_ex.h>
19 
20 #include "ithermal_temp_callback.h"
21 #include "constants.h"
22 #include "string_operation.h"
23 #include "thermal_config_base_info.h"
24 #include "thermal_common.h"
25 #include "thermal_service.h"
26 #include "ffrt_utils.h"
27 
28 namespace OHOS {
29 namespace PowerMgr {
30 namespace {
31 }
ThermalObserver(const wptr<ThermalService>& tms)32 ThermalObserver::ThermalObserver(const wptr<ThermalService>& tms) : tms_(tms) {};
~ThermalObserver()33 ThermalObserver::~ThermalObserver() {};
34 
Init()35 bool ThermalObserver::Init()
36 {
37     if (sensorTempCBDeathRecipient_ == nullptr) {
38         sensorTempCBDeathRecipient_ = new SensorTempCallbackDeathRecipient();
39     }
40 
41     if (actionCBDeathRecipient_ == nullptr) {
42         actionCBDeathRecipient_ = new ActionCallbackDeathRecipient();
43     }
44 
45     InitSensorTypeMap();
46     THERMAL_HILOGI(COMP_SVC, "ThermalObserver init succ");
47     return true;
48 }
49 
InitSensorTypeMap()50 void ThermalObserver::InitSensorTypeMap()
51 {
52     auto tms = ThermalService::GetInstance();
53     std::vector<std::string> sensorType(TYPE_MAX_SIZE);
54     auto baseInfo = tms->GetBaseinfoObj();
55     if (baseInfo == nullptr) return;
56     auto typeList = baseInfo->GetSensorsType();
57 
58     THERMAL_HILOGD(COMP_SVC, "sensorType size = %{public}zu", typeList.size());
59     if (typeList.size() <= TYPE_MAX_SIZE) {
60         typeList.resize(TYPE_MAX_SIZE);
61     } else {
62         return;
63     }
64 
65     if (!typeList.empty()) {
66         for (uint32_t i = 0; i < typeList.size(); i++) {
67             THERMAL_HILOGI(COMP_SVC, "InitSensorTypeMap id=%{public}u sensorType=%{public}s", i, typeList[i].c_str());
68             sensorType[i] = typeList[i];
69         }
70     }
71     typeMap_.clear();
72     typeMap_.insert(std::make_pair(SensorType::SOC, sensorType[ARG_0]));
73     typeMap_.insert(std::make_pair(SensorType::BATTERY, sensorType[ARG_1]));
74     typeMap_.insert(std::make_pair(SensorType::SHELL, sensorType[ARG_2]));
75     typeMap_.insert(std::make_pair(SensorType::SENSOR1, sensorType[ARG_3]));
76     typeMap_.insert(std::make_pair(SensorType::SENSOR2, sensorType[ARG_4]));
77     typeMap_.insert(std::make_pair(SensorType::SENSOR3, sensorType[ARG_5]));
78     typeMap_.insert(std::make_pair(SensorType::SENSOR4, sensorType[ARG_6]));
79     typeMap_.insert(std::make_pair(SensorType::SENSOR5, sensorType[ARG_7]));
80     typeMap_.insert(std::make_pair(SensorType::SENSOR6, sensorType[ARG_8]));
81     typeMap_.insert(std::make_pair(SensorType::SENSOR7, sensorType[ARG_9]));
82 }
83 
SetRegisterCallback(Callback& callback)84 void ThermalObserver::SetRegisterCallback(Callback& callback)
85 {
86     callback_ = callback;
87 }
88 
SubscribeThermalTempCallback(const std::vector<std::string>& typeList, const sptr<IThermalTempCallback>& callback)89 void ThermalObserver::SubscribeThermalTempCallback(const std::vector<std::string>& typeList,
90     const sptr<IThermalTempCallback>& callback)
91 {
92     std::lock_guard<std::mutex> lock(mutexTempCallback_);
93     THERMAL_RETURN_IF(callback == nullptr);
94     auto object = callback->AsObject();
95     THERMAL_RETURN_IF(object == nullptr);
96     auto retIt = sensorTempListeners_.insert(callback);
97     if (retIt.second) {
98         object->AddDeathRecipient(sensorTempCBDeathRecipient_);
99         callbackTypeMap_.insert(std::make_pair(callback, typeList));
100         THERMAL_HILOGI(COMP_SVC, "add new temp listener, listeners.size=%{public}zu", sensorTempListeners_.size());
101     } else {
102         THERMAL_HILOGW(COMP_SVC, "subscribe failed, temp callback duplicate subscription!");
103     }
104 }
105 
UnSubscribeThermalTempCallback(const sptr<IThermalTempCallback>& callback)106 void ThermalObserver::UnSubscribeThermalTempCallback(const sptr<IThermalTempCallback>& callback)
107 {
108     std::lock_guard lock(mutexTempCallback_);
109     THERMAL_RETURN_IF(callback == nullptr);
110     auto object = callback->AsObject();
111     THERMAL_RETURN_IF(object == nullptr);
112     auto callbackIter = callbackTypeMap_.find(callback);
113     if (callbackIter != callbackTypeMap_.end()) {
114         callbackTypeMap_.erase(callbackIter);
115     }
116     size_t eraseNum = sensorTempListeners_.erase(callback);
117     if (eraseNum != 0) {
118         object->RemoveDeathRecipient(sensorTempCBDeathRecipient_);
119     }
120     THERMAL_HILOGI(COMP_SVC, "erase temp listener, listeners.size=%{public}zu, eraseNum=%{public}zu",
121         sensorTempListeners_.size(), eraseNum);
122 }
123 
SubscribeThermalActionCallback(const std::vector<std::string>& actionList, const std::string& desc, const sptr<IThermalActionCallback>& callback)124 void ThermalObserver::SubscribeThermalActionCallback(const std::vector<std::string>& actionList,
125     const std::string& desc, const sptr<IThermalActionCallback>& callback)
126 {
127     std::lock_guard<std::mutex> lock(mutexActionCallback_);
128     THERMAL_RETURN_IF(callback == nullptr);
129     auto object = callback->AsObject();
130     THERMAL_RETURN_IF(object == nullptr);
131     auto retIt = actionListeners_.insert(callback);
132     if (retIt.second) {
133         object->AddDeathRecipient(actionCBDeathRecipient_);
134         callbackActionMap_.insert(std::make_pair(callback, actionList));
135         THERMAL_HILOGI(COMP_SVC, "add new action listener, listeners.size=%{public}zu", actionListeners_.size());
136         IThermalActionCallback::ActionCallbackMap actionCbMap;
137         DecisionActionValue(actionList, actionCbMap, actionCache_);
138         callback->OnThermalActionChanged(actionCbMap);
139         THERMAL_HILOGI(COMP_SVC, "current action callback completed");
140     } else {
141         THERMAL_HILOGW(COMP_SVC, "subscribe failed, action callback duplicate subscription!");
142     }
143 }
144 
UnSubscribeThermalActionCallback(const sptr<IThermalActionCallback>& callback)145 void ThermalObserver::UnSubscribeThermalActionCallback(const sptr<IThermalActionCallback>& callback)
146 {
147     std::lock_guard lock(mutexActionCallback_);
148     THERMAL_RETURN_IF(callback == nullptr);
149     auto object = callback->AsObject();
150     THERMAL_RETURN_IF(object == nullptr);
151     auto callbackIter = callbackActionMap_.find(callback);
152     if (callbackIter != callbackActionMap_.end()) {
153         callbackActionMap_.erase(callbackIter);
154     }
155     size_t eraseNum = actionListeners_.erase(callback);
156     if (eraseNum != 0) {
157         object->RemoveDeathRecipient(actionCBDeathRecipient_);
158     }
159     THERMAL_HILOGI(COMP_SVC, "erase action listener, listeners.size=%{public}zu, eraseNum=%{public}zu",
160         actionListeners_.size(), eraseNum);
161 }
162 
PrintAction()163 void ThermalObserver::PrintAction()
164 {
165     std::string thermalActionLog;
166     for (auto actionIter = actionMap_.begin(); actionIter != actionMap_.end(); ++actionIter) {
167         thermalActionLog.append(actionIter->first).append("=").append(actionIter->second).append("|");
168     }
169     THERMAL_HILOGI(COMP_SVC, "sub {%{public}zu|%{public}zu} pol {%{public}s}",
170         sensorTempListeners_.size(), actionListeners_.size(), policyState_.c_str());
171     THERMAL_HILOGI(COMP_SVC, "exec act {%{public}s}", thermalActionLog.c_str());
172 }
173 
FindSubscribeActionValue()174 void ThermalObserver::FindSubscribeActionValue()
175 {
176     std::lock_guard lock(mutexActionCallback_);
177     if (actionMap_.empty()) {
178         THERMAL_HILOGD(COMP_SVC, "no action");
179         return;
180     }
181     PrintAction();
182     actionCache_ = actionMap_;
183     if (actionListeners_.empty()) {
184         THERMAL_HILOGD(COMP_SVC, "no subscribe");
185         actionMap_.clear();
186         return;
187     }
188 
189     IThermalActionCallback::ActionCallbackMap newActionCbMap;
190     for (auto& listener : actionListeners_) {
191         auto actionIter = callbackActionMap_.find(listener);
192         if (actionIter != callbackActionMap_.end()) {
193             THERMAL_HILOGD(COMP_SVC, "find callback.");
194             DecisionActionValue(actionIter->second, newActionCbMap, actionMap_);
195         }
196 
197         listener->OnThermalActionChanged(newActionCbMap);
198     }
199     actionMap_.clear();
200 }
201 
DecisionActionValue(const std::vector<std::string>& actionList, IThermalActionCallback::ActionCallbackMap& filteredMap)202 void ThermalObserver::DecisionActionValue(const std::vector<std::string>& actionList,
203     IThermalActionCallback::ActionCallbackMap& filteredMap)
204 {
205     DecisionActionValue(actionList, filteredMap, actionMap_);
206 }
207 
DecisionActionValue(const std::vector<std::string>& actionList, IThermalActionCallback::ActionCallbackMap& filteredMap, const std::map<std::string, std::string>& actionMap)208 void ThermalObserver::DecisionActionValue(const std::vector<std::string>& actionList,
209     IThermalActionCallback::ActionCallbackMap& filteredMap, const std::map<std::string, std::string>& actionMap)
210 {
211     std::lock_guard lock(mutexActionMap_);
212     for (const auto& action : actionList) {
213         THERMAL_HILOGD(COMP_SVC, "subscribe action is %{public}s.", action.c_str());
214         for (auto actionIter = actionMap.begin(); actionIter != actionMap.end(); ++actionIter) {
215             THERMAL_HILOGD(COMP_SVC, "xml action is %{public}s.", actionIter->first.c_str());
216             if (action == actionIter->first) {
217                 filteredMap.insert(std::make_pair(action, actionIter->second));
218             }
219         }
220     }
221 }
222 
SetDecisionValue(const std::string& actionName, const std::string& actionValue)223 void ThermalObserver::SetDecisionValue(const std::string& actionName, const std::string& actionValue)
224 {
225     std::lock_guard lock(mutexActionMap_);
226     THERMAL_HILOGD(
227         COMP_SVC, "actionName = %{public}s, actionValue = %{public}s", actionName.c_str(), actionValue.c_str());
228     auto iter = actionMap_.find(actionName);
229     if (iter != actionMap_.end()) {
230         iter->second = actionValue;
231     } else {
232         actionMap_.insert(std::make_pair(actionName, actionValue));
233     }
234 }
235 
NotifySensorTempChanged(IThermalTempCallback::TempCallbackMap& tempCbMap)236 void ThermalObserver::NotifySensorTempChanged(IThermalTempCallback::TempCallbackMap& tempCbMap)
237 {
238     std::lock_guard lockTempCallback(mutexTempCallback_);
239     static std::map<std::string, int32_t> preSensor;
240     IThermalTempCallback::TempCallbackMap newTempCbMap;
241     THERMAL_HILOGD(COMP_SVC,
242         "listeners.size = %{public}zu, callbackTypeMap.size = %{public}zu",
243         sensorTempListeners_.size(), callbackTypeMap_.size());
244     if (sensorTempListeners_.empty()) {
245         return;
246     }
247     for (auto& listener : sensorTempListeners_) {
248         auto callbackIter = callbackTypeMap_.find(listener);
249         if (callbackIter != callbackTypeMap_.end()) {
250             THERMAL_HILOGD(COMP_SVC, "find callback");
251             for (auto type : callbackIter->second) {
252                 std::lock_guard lockCallbackInfo(mutexCallbackInfo_);
253                 if (preSensor[type] != tempCbMap[type]) {
254                     newTempCbMap.insert(std::make_pair(type, tempCbMap[type]));
255                     preSensor[type] = tempCbMap[type];
256                 }
257             }
258         }
259         listener->OnThermalTempChanged(newTempCbMap);
260     }
261 }
262 
OnReceivedSensorInfo(const TypeTempMap& info)263 void ThermalObserver::OnReceivedSensorInfo(const TypeTempMap& info)
264 {
265     {
266         std::lock_guard lock(mutexCallbackInfo_);
267         callbackinfo_ = info;
268     }
269     THERMAL_HILOGD(COMP_SVC, "callbackinfo_ size = %{public}zu", callbackinfo_.size());
270 
271     if (callback_ != nullptr) {
272         callback_(callbackinfo_);
273     }
274 
275     NotifySensorTempChanged(callbackinfo_);
276 }
277 
GetThermalSrvSensorInfo(const SensorType& type, ThermalSrvSensorInfo& sensorInfo)278 bool ThermalObserver::GetThermalSrvSensorInfo(const SensorType& type, ThermalSrvSensorInfo& sensorInfo)
279 {
280     THERMAL_HILOGD(COMP_SVC, "typeMap_=%{public}s", typeMap_[type].c_str());
281 
282     std::lock_guard lock(mutexCallbackInfo_);
283     auto iter = callbackinfo_.find(typeMap_[type]);
284     if (iter != callbackinfo_.end()) {
285         THERMAL_HILOGD(COMP_SVC, "set temp for sensor");
286         sensorInfo.SetType(typeMap_[type]);
287         if (iter->second == INVALID_TEMP) {
288             return false;
289         } else {
290             sensorInfo.SetTemp(iter->second);
291         }
292         return true;
293     } else {
294         THERMAL_HILOGD(COMP_SVC, "set invalid temp for sensor");
295         sensorInfo.SetType(typeMap_[type]);
296         sensorInfo.SetTemp(INVALID_TEMP);
297         return false;
298     }
299     return false;
300 }
301 
GetTemp(const SensorType& type)302 int32_t ThermalObserver::GetTemp(const SensorType& type)
303 {
304     ThermalSrvSensorInfo info;
305     GetThermalSrvSensorInfo(type, info);
306     return info.GetTemp();
307 }
308 
OnRemoteDied(const wptr<IRemoteObject>& remote)309 void ThermalObserver::SensorTempCallbackDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
310 {
311     if (remote == nullptr || remote.promote() == nullptr) {
312         return;
313     }
314     THERMAL_HILOGI(COMP_SVC, "ThermalSensorTemp::OnRemoteDied remote");
315     auto pms = ThermalService::GetInstance();
316     if (pms == nullptr) {
317         return;
318     }
319     sptr<IThermalTempCallback> callback = iface_cast<IThermalTempCallback>(remote.promote());
320     FFRTTask task = [pms, callback] { pms->UnSubscribeThermalTempCallback(callback); };
321     FFRTUtils::SubmitTask(task);
322 }
323 
OnRemoteDied(const wptr<IRemoteObject>& remote)324 void ThermalObserver::ActionCallbackDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
325 {
326     if (remote == nullptr || remote.promote() == nullptr) {
327         return;
328     }
329     THERMAL_HILOGI(COMP_SVC, "ThermalAction::OnRemoteDied remote");
330     auto pms = ThermalService::GetInstance();
331     if (pms == nullptr) {
332         return;
333     }
334     sptr<IThermalActionCallback> callback = iface_cast<IThermalActionCallback>(remote.promote());
335     FFRTTask task = [pms, callback] { pms->UnSubscribeThermalActionCallback(callback); };
336     FFRTUtils::SubmitTask(task);
337 }
338 } // namespace PowerMgr
339 } // namespace OHOS
340