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 {
177 std::lock_guard lock(mutexActionMap_);
178 if (actionMap_.empty()) {
179 THERMAL_HILOGD(COMP_SVC, "no action");
180 return;
181 }
182 PrintAction();
183 actionCache_ = actionMap_;
184 actionMap_.clear();
185 }
186
187 std::lock_guard lock(mutexActionCallback_);
188 IThermalActionCallback::ActionCallbackMap newActionCbMap;
189 for (auto& listener : actionListeners_) {
190 auto actionIter = callbackActionMap_.find(listener);
191 if (actionIter != callbackActionMap_.end()) {
192 THERMAL_HILOGD(COMP_SVC, "find callback.");
193 DecisionActionValue(actionIter->second, newActionCbMap, actionCache_);
194 }
195
196 listener->OnThermalActionChanged(newActionCbMap);
197 }
198 }
199
DecisionActionValue(const std::vector<std::string> & actionList,IThermalActionCallback::ActionCallbackMap & filteredMap)200 void ThermalObserver::DecisionActionValue(const std::vector<std::string>& actionList,
201 IThermalActionCallback::ActionCallbackMap& filteredMap)
202 {
203 DecisionActionValue(actionList, filteredMap, actionMap_);
204 }
205
DecisionActionValue(const std::vector<std::string> & actionList,IThermalActionCallback::ActionCallbackMap & filteredMap,const std::map<std::string,std::string> & actionMap)206 void ThermalObserver::DecisionActionValue(const std::vector<std::string>& actionList,
207 IThermalActionCallback::ActionCallbackMap& filteredMap, const std::map<std::string, std::string>& actionMap)
208 {
209 std::lock_guard lock(mutexActionMap_);
210 for (const auto& action : actionList) {
211 THERMAL_HILOGD(COMP_SVC, "subscribe action is %{public}s.", action.c_str());
212 for (auto actionIter = actionMap.begin(); actionIter != actionMap.end(); ++actionIter) {
213 THERMAL_HILOGD(COMP_SVC, "xml action is %{public}s.", actionIter->first.c_str());
214 if (action == actionIter->first) {
215 filteredMap.insert(std::make_pair(action, actionIter->second));
216 }
217 }
218 }
219 }
220
SetDecisionValue(const std::string & actionName,const std::string & actionValue)221 void ThermalObserver::SetDecisionValue(const std::string& actionName, const std::string& actionValue)
222 {
223 std::lock_guard lock(mutexActionMap_);
224 THERMAL_HILOGD(
225 COMP_SVC, "actionName = %{public}s, actionValue = %{public}s", actionName.c_str(), actionValue.c_str());
226 auto iter = actionMap_.find(actionName);
227 if (iter != actionMap_.end()) {
228 iter->second = actionValue;
229 } else {
230 actionMap_.insert(std::make_pair(actionName, actionValue));
231 }
232 }
233
NotifySensorTempChanged(IThermalTempCallback::TempCallbackMap & tempCbMap)234 void ThermalObserver::NotifySensorTempChanged(IThermalTempCallback::TempCallbackMap& tempCbMap)
235 {
236 std::lock_guard lockTempCallback(mutexTempCallback_);
237 static std::map<std::string, int32_t> preSensor;
238 IThermalTempCallback::TempCallbackMap newTempCbMap;
239 THERMAL_HILOGD(COMP_SVC,
240 "listeners.size = %{public}zu, callbackTypeMap.size = %{public}zu",
241 sensorTempListeners_.size(), callbackTypeMap_.size());
242 if (sensorTempListeners_.empty()) {
243 return;
244 }
245 for (auto& listener : sensorTempListeners_) {
246 auto callbackIter = callbackTypeMap_.find(listener);
247 if (callbackIter != callbackTypeMap_.end()) {
248 THERMAL_HILOGD(COMP_SVC, "find callback");
249 for (auto type : callbackIter->second) {
250 std::lock_guard lockCallbackInfo(mutexCallbackInfo_);
251 if (preSensor[type] != tempCbMap[type]) {
252 newTempCbMap.insert(std::make_pair(type, tempCbMap[type]));
253 preSensor[type] = tempCbMap[type];
254 }
255 }
256 }
257 listener->OnThermalTempChanged(newTempCbMap);
258 }
259 }
260
OnReceivedSensorInfo(const TypeTempMap & info)261 void ThermalObserver::OnReceivedSensorInfo(const TypeTempMap& info)
262 {
263 {
264 std::lock_guard lock(mutexCallbackInfo_);
265 callbackinfo_ = info;
266 }
267 THERMAL_HILOGD(COMP_SVC, "callbackinfo_ size = %{public}zu", callbackinfo_.size());
268
269 if (callback_ != nullptr) {
270 callback_(callbackinfo_);
271 }
272
273 NotifySensorTempChanged(callbackinfo_);
274 }
275
GetThermalSrvSensorInfo(const SensorType & type,ThermalSrvSensorInfo & sensorInfo)276 bool ThermalObserver::GetThermalSrvSensorInfo(const SensorType& type, ThermalSrvSensorInfo& sensorInfo)
277 {
278 THERMAL_HILOGD(COMP_SVC, "typeMap_=%{public}s", typeMap_[type].c_str());
279
280 std::lock_guard lock(mutexCallbackInfo_);
281 auto iter = callbackinfo_.find(typeMap_[type]);
282 if (iter != callbackinfo_.end()) {
283 THERMAL_HILOGD(COMP_SVC, "set temp for sensor");
284 sensorInfo.SetType(typeMap_[type]);
285 if (iter->second == INVALID_TEMP) {
286 return false;
287 } else {
288 sensorInfo.SetTemp(iter->second);
289 }
290 return true;
291 } else {
292 THERMAL_HILOGD(COMP_SVC, "set invalid temp for sensor");
293 sensorInfo.SetType(typeMap_[type]);
294 sensorInfo.SetTemp(INVALID_TEMP);
295 return false;
296 }
297 return false;
298 }
299
GetTemp(const SensorType & type)300 int32_t ThermalObserver::GetTemp(const SensorType& type)
301 {
302 ThermalSrvSensorInfo info;
303 GetThermalSrvSensorInfo(type, info);
304 return info.GetTemp();
305 }
306
OnRemoteDied(const wptr<IRemoteObject> & remote)307 void ThermalObserver::SensorTempCallbackDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
308 {
309 if (remote == nullptr || remote.promote() == nullptr) {
310 return;
311 }
312 THERMAL_HILOGI(COMP_SVC, "ThermalSensorTemp::OnRemoteDied remote");
313 auto pms = ThermalService::GetInstance();
314 if (pms == nullptr) {
315 return;
316 }
317 sptr<IThermalTempCallback> callback = iface_cast<IThermalTempCallback>(remote.promote());
318 FFRTTask task = [pms, callback] { pms->UnSubscribeThermalTempCallback(callback); };
319 FFRTUtils::SubmitTask(task);
320 }
321
OnRemoteDied(const wptr<IRemoteObject> & remote)322 void ThermalObserver::ActionCallbackDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
323 {
324 if (remote == nullptr || remote.promote() == nullptr) {
325 return;
326 }
327 THERMAL_HILOGI(COMP_SVC, "ThermalAction::OnRemoteDied remote");
328 auto pms = ThermalService::GetInstance();
329 if (pms == nullptr) {
330 return;
331 }
332 sptr<IThermalActionCallback> callback = iface_cast<IThermalActionCallback>(remote.promote());
333 FFRTTask task = [pms, callback] { pms->UnSubscribeThermalActionCallback(callback); };
334 FFRTUtils::SubmitTask(task);
335 }
336 } // namespace PowerMgr
337 } // namespace OHOS
338