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