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