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