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     {
177         std::lock_guard lock(mutexActionMap_);
178         if (actionMap_.empty()) {
179             THERMAL_HILOGD(COMP_SVC, "no action");
180             return;
181         }
182         PrintAction();
183         actionCache_ = actionMap_;
184         actionMap_.clear();
185     }
186 
187     std::lock_guard lock(mutexActionCallback_);
188     IThermalActionCallback::ActionCallbackMap newActionCbMap;
189     for (auto& listener : actionListeners_) {
190         auto actionIter = callbackActionMap_.find(listener);
191         if (actionIter != callbackActionMap_.end()) {
192             THERMAL_HILOGD(COMP_SVC, "find callback.");
193             DecisionActionValue(actionIter->second, newActionCbMap, actionCache_);
194         }
195 
196         listener->OnThermalActionChanged(newActionCbMap);
197     }
198 }
199 
DecisionActionValue(const std::vector<std::string> & actionList,IThermalActionCallback::ActionCallbackMap & filteredMap)200 void ThermalObserver::DecisionActionValue(const std::vector<std::string>& actionList,
201     IThermalActionCallback::ActionCallbackMap& filteredMap)
202 {
203     DecisionActionValue(actionList, filteredMap, actionMap_);
204 }
205 
DecisionActionValue(const std::vector<std::string> & actionList,IThermalActionCallback::ActionCallbackMap & filteredMap,const std::map<std::string,std::string> & actionMap)206 void ThermalObserver::DecisionActionValue(const std::vector<std::string>& actionList,
207     IThermalActionCallback::ActionCallbackMap& filteredMap, const std::map<std::string, std::string>& actionMap)
208 {
209     std::lock_guard lock(mutexActionMap_);
210     for (const auto& action : actionList) {
211         THERMAL_HILOGD(COMP_SVC, "subscribe action is %{public}s.", action.c_str());
212         for (auto actionIter = actionMap.begin(); actionIter != actionMap.end(); ++actionIter) {
213             THERMAL_HILOGD(COMP_SVC, "xml action is %{public}s.", actionIter->first.c_str());
214             if (action == actionIter->first) {
215                 filteredMap.insert(std::make_pair(action, actionIter->second));
216             }
217         }
218     }
219 }
220 
SetDecisionValue(const std::string & actionName,const std::string & actionValue)221 void ThermalObserver::SetDecisionValue(const std::string& actionName, const std::string& actionValue)
222 {
223     std::lock_guard lock(mutexActionMap_);
224     THERMAL_HILOGD(
225         COMP_SVC, "actionName = %{public}s, actionValue = %{public}s", actionName.c_str(), actionValue.c_str());
226     auto iter = actionMap_.find(actionName);
227     if (iter != actionMap_.end()) {
228         iter->second = actionValue;
229     } else {
230         actionMap_.insert(std::make_pair(actionName, actionValue));
231     }
232 }
233 
NotifySensorTempChanged(IThermalTempCallback::TempCallbackMap & tempCbMap)234 void ThermalObserver::NotifySensorTempChanged(IThermalTempCallback::TempCallbackMap& tempCbMap)
235 {
236     std::lock_guard lockTempCallback(mutexTempCallback_);
237     static std::map<std::string, int32_t> preSensor;
238     IThermalTempCallback::TempCallbackMap newTempCbMap;
239     THERMAL_HILOGD(COMP_SVC,
240         "listeners.size = %{public}zu, callbackTypeMap.size = %{public}zu",
241         sensorTempListeners_.size(), callbackTypeMap_.size());
242     if (sensorTempListeners_.empty()) {
243         return;
244     }
245     for (auto& listener : sensorTempListeners_) {
246         auto callbackIter = callbackTypeMap_.find(listener);
247         if (callbackIter != callbackTypeMap_.end()) {
248             THERMAL_HILOGD(COMP_SVC, "find callback");
249             for (auto type : callbackIter->second) {
250                 std::lock_guard lockCallbackInfo(mutexCallbackInfo_);
251                 if (preSensor[type] != tempCbMap[type]) {
252                     newTempCbMap.insert(std::make_pair(type, tempCbMap[type]));
253                     preSensor[type] = tempCbMap[type];
254                 }
255             }
256         }
257         listener->OnThermalTempChanged(newTempCbMap);
258     }
259 }
260 
OnReceivedSensorInfo(const TypeTempMap & info)261 void ThermalObserver::OnReceivedSensorInfo(const TypeTempMap& info)
262 {
263     {
264         std::lock_guard lock(mutexCallbackInfo_);
265         callbackinfo_ = info;
266     }
267     THERMAL_HILOGD(COMP_SVC, "callbackinfo_ size = %{public}zu", callbackinfo_.size());
268 
269     if (callback_ != nullptr) {
270         callback_(callbackinfo_);
271     }
272 
273     NotifySensorTempChanged(callbackinfo_);
274 }
275 
GetThermalSrvSensorInfo(const SensorType & type,ThermalSrvSensorInfo & sensorInfo)276 bool ThermalObserver::GetThermalSrvSensorInfo(const SensorType& type, ThermalSrvSensorInfo& sensorInfo)
277 {
278     THERMAL_HILOGD(COMP_SVC, "typeMap_=%{public}s", typeMap_[type].c_str());
279 
280     std::lock_guard lock(mutexCallbackInfo_);
281     auto iter = callbackinfo_.find(typeMap_[type]);
282     if (iter != callbackinfo_.end()) {
283         THERMAL_HILOGD(COMP_SVC, "set temp for sensor");
284         sensorInfo.SetType(typeMap_[type]);
285         if (iter->second == INVALID_TEMP) {
286             return false;
287         } else {
288             sensorInfo.SetTemp(iter->second);
289         }
290         return true;
291     } else {
292         THERMAL_HILOGD(COMP_SVC, "set invalid temp for sensor");
293         sensorInfo.SetType(typeMap_[type]);
294         sensorInfo.SetTemp(INVALID_TEMP);
295         return false;
296     }
297     return false;
298 }
299 
GetTemp(const SensorType & type)300 int32_t ThermalObserver::GetTemp(const SensorType& type)
301 {
302     ThermalSrvSensorInfo info;
303     GetThermalSrvSensorInfo(type, info);
304     return info.GetTemp();
305 }
306 
OnRemoteDied(const wptr<IRemoteObject> & remote)307 void ThermalObserver::SensorTempCallbackDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
308 {
309     if (remote == nullptr || remote.promote() == nullptr) {
310         return;
311     }
312     THERMAL_HILOGI(COMP_SVC, "ThermalSensorTemp::OnRemoteDied remote");
313     auto pms = ThermalService::GetInstance();
314     if (pms == nullptr) {
315         return;
316     }
317     sptr<IThermalTempCallback> callback = iface_cast<IThermalTempCallback>(remote.promote());
318     FFRTTask task = [pms, callback] { pms->UnSubscribeThermalTempCallback(callback); };
319     FFRTUtils::SubmitTask(task);
320 }
321 
OnRemoteDied(const wptr<IRemoteObject> & remote)322 void ThermalObserver::ActionCallbackDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
323 {
324     if (remote == nullptr || remote.promote() == nullptr) {
325         return;
326     }
327     THERMAL_HILOGI(COMP_SVC, "ThermalAction::OnRemoteDied remote");
328     auto pms = ThermalService::GetInstance();
329     if (pms == nullptr) {
330         return;
331     }
332     sptr<IThermalActionCallback> callback = iface_cast<IThermalActionCallback>(remote.promote());
333     FFRTTask task = [pms, callback] { pms->UnSubscribeThermalActionCallback(callback); };
334     FFRTUtils::SubmitTask(task);
335 }
336 } // namespace PowerMgr
337 } // namespace OHOS
338