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