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