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