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