1 /*
2 * Copyright (c) 2021-2022 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_service.h"
17
18 #include "file_ex.h"
19 #include "if_system_ability_manager.h"
20 #include "iservice_registry.h"
21 #include "securec.h"
22 #include "system_ability_definition.h"
23 #include <algorithm>
24 #include <fcntl.h>
25 #include <ipc_skeleton.h>
26 #include <unistd.h>
27
28 #include "constants.h"
29 #include "thermal_common.h"
30 #include "thermal_mgr_dumper.h"
31 #include "thermal_srv_config_parser.h"
32 #include "watchdog.h"
33
34 namespace OHOS {
35 namespace PowerMgr {
36 namespace {
37 std::string VENDOR_CONFIG = "/vendor/etc/thermal_config/thermal_service_config.xml";
38 std::string SYSTEM_CONFIG = "/system/etc/thermal_config/thermal_service_config.xml";
39 constexpr const char* THMERMAL_SERVICE_NAME = "ThermalService";
40 constexpr const char* HDI_SERVICE_NAME = "thermal_interface_service";
41 constexpr uint32_t RETRY_TIME = 1000;
42 auto g_service = DelayedSpSingleton<ThermalService>::GetInstance();
43 const bool G_REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(g_service.GetRefPtr());
44 } // namespace
ThermalService()45 ThermalService::ThermalService() : SystemAbility(POWER_MANAGER_THERMAL_SERVICE_ID, true) {}
46
~ThermalService()47 ThermalService::~ThermalService() {}
48
OnStart()49 void ThermalService::OnStart()
50 {
51 int time = 100;
52 THERMAL_HILOGD(COMP_SVC, "Enter");
53 if (ready_) {
54 THERMAL_HILOGE(COMP_SVC, "OnStart is ready, nothing to do");
55 return;
56 }
57
58 std::this_thread::sleep_for(std::chrono::milliseconds(time));
59
60 if (!(Init())) {
61 THERMAL_HILOGE(COMP_SVC, "OnStart call init fail");
62 return;
63 }
64
65 AddSystemAbilityListener(COMMON_EVENT_SERVICE_ID);
66 if (!Publish(DelayedSpSingleton<ThermalService>::GetInstance())) {
67 THERMAL_HILOGE(COMP_SVC, "OnStart register to system ability manager failed.");
68 return;
69 }
70 ready_ = true;
71 THERMAL_HILOGD(COMP_SVC, "OnStart and add system ability success");
72 }
73
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)74 void ThermalService::OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
75 {
76 THERMAL_HILOGI(COMP_SVC, "systemAbilityId=%{public}d, deviceId=%{private}s", systemAbilityId, deviceId.c_str());
77 if (systemAbilityId == COMMON_EVENT_SERVICE_ID) {
78 InitStateMachine();
79 }
80 }
81
Init()82 bool ThermalService::Init()
83 {
84 THERMAL_HILOGD(COMP_SVC, "Enter");
85 std::this_thread::sleep_for(std::chrono::milliseconds(TIME_TO_SLEEP));
86
87 if (!eventRunner_) {
88 eventRunner_ = AppExecFwk::EventRunner::Create(THMERMAL_SERVICE_NAME);
89 if (eventRunner_ == nullptr) {
90 THERMAL_HILOGE(COMP_SVC, "Init failed due to create EventRunner");
91 return false;
92 }
93 }
94
95 if (!handler_) {
96 handler_ = std::make_shared<ThermalsrvEventHandler>(eventRunner_, g_service);
97 if (handler_ == nullptr) {
98 THERMAL_HILOGE(COMP_SVC, "Init failed due to create handler error");
99 return false;
100 }
101 HiviewDFX::Watchdog::GetInstance().AddThread("ThermalsrvEventHandler", handler_);
102 }
103
104 if (!CreateConfigModule()) {
105 return false;
106 }
107
108 RegisterHdiStatusListener();
109 if (!InitModules()) {
110 return false;
111 }
112 THERMAL_HILOGD(COMP_SVC, "Init success");
113 return true;
114 }
115
CreateConfigModule()116 bool ThermalService::CreateConfigModule()
117 {
118 if (!baseInfo_) {
119 baseInfo_ = std::make_shared<ThermalConfigBaseInfo>();
120 if (baseInfo_ == nullptr) {
121 THERMAL_HILOGE(COMP_SVC, "failed to create base info");
122 return false;
123 }
124 }
125
126 if (!state_) {
127 state_ = std::make_shared<StateMachine>();
128 if (state_ == nullptr) {
129 THERMAL_HILOGE(COMP_SVC, "failed to create state machine");
130 return false;
131 }
132 }
133
134 if (!actionMgr_) {
135 actionMgr_ = std::make_shared<ThermalActionManager>();
136 if (actionMgr_ == nullptr) {
137 THERMAL_HILOGE(COMP_SVC, "failed to create action manager");
138 return false;
139 }
140 }
141
142 if (cluster_ == nullptr) {
143 cluster_ = std::make_shared<ThermalConfigSensorCluster>();
144 if (cluster_ == nullptr) {
145 THERMAL_HILOGE(COMP_SVC, "failed to create cluster");
146 return false;
147 }
148 }
149
150 if (!policy_) {
151 policy_ = std::make_shared<ThermalPolicy>();
152 if (policy_ == nullptr) {
153 THERMAL_HILOGE(COMP_SVC, "failed to create thermal policy");
154 return false;
155 }
156 }
157 return true;
158 }
159
InitModules()160 bool ThermalService::InitModules()
161 {
162 if (!ThermalSrvConfigParser::GetInstance().ThermalSrvConfigInit(VENDOR_CONFIG)) {
163 THERMAL_HILOGE(COMP_SVC, "thermal service config init fail:VENDOR_CONFIG");
164 if (!ThermalSrvConfigParser::GetInstance().ThermalSrvConfigInit(SYSTEM_CONFIG)) {
165 THERMAL_HILOGE(COMP_SVC, "thermal service config init fail:SYSTEM_CONFIG");
166 return false;
167 }
168 isSimulation_ = true;
169 }
170
171 if (popup_ == nullptr) {
172 popup_ = std::make_shared<ActionPopup>(POPUP_ACTION_NAME);
173 }
174
175 if (!InitThermalObserver()) {
176 THERMAL_HILOGE(COMP_SVC, "thermal observer start fail");
177 return false;
178 }
179
180 if (!InitActionManager()) {
181 THERMAL_HILOGE(COMP_SVC, "action manager init fail");
182 return false;
183 }
184
185 if (!InitThermalPolicy()) {
186 THERMAL_HILOGE(COMP_SVC, "thermal policy start fail");
187 return false;
188 }
189 return true;
190 }
191
InitThermalObserver()192 bool ThermalService::InitThermalObserver()
193 {
194 if (!InitBaseInfo()) {
195 return false;
196 }
197
198 THERMAL_HILOGD(COMP_SVC, "Enter");
199 if (observer_ == nullptr) {
200 observer_ = std::make_shared<ThermalObserver>(g_service);
201 if (!(observer_->Init())) {
202 THERMAL_HILOGE(COMP_SVC, "InitThermalObserver: thermal observer start fail");
203 return false;
204 }
205 }
206 if (info_ == nullptr) {
207 info_ = std::make_shared<ThermalSensorInfo>();
208 }
209 THERMAL_HILOGI(COMP_SVC, "InitThermalObserver: Init Success");
210 return true;
211 }
212
InitBaseInfo()213 bool ThermalService::InitBaseInfo()
214 {
215 THERMAL_HILOGD(COMP_SVC, "Enter");
216 if (!baseInfo_->Init()) {
217 THERMAL_HILOGE(COMP_SVC, "InitBaseInfo: base info init failed");
218 return false;
219 }
220 return true;
221 }
222
InitStateMachine()223 bool ThermalService::InitStateMachine()
224 {
225 THERMAL_HILOGD(COMP_SVC, "Enter");
226 if (!state_->Init()) {
227 THERMAL_HILOGE(COMP_SVC, "InitStateMachine: state machine init failed");
228 return false;
229 }
230 return true;
231 }
232
InitActionManager()233 bool ThermalService::InitActionManager()
234 {
235 THERMAL_HILOGD(COMP_SVC, "Enter");
236 if (!actionMgr_->Init()) {
237 THERMAL_HILOGE(COMP_SVC, "InitActionManager: action manager init failed");
238 return false;
239 }
240 return true;
241 }
242
InitThermalPolicy()243 bool ThermalService::InitThermalPolicy()
244 {
245 THERMAL_HILOGD(COMP_SVC, "Enter");
246 if (!policy_->Init()) {
247 THERMAL_HILOGE(COMP_SVC, "InitThermalPolicy: policy init failed");
248 return false;
249 }
250 return true;
251 }
252
OnStop()253 void ThermalService::OnStop()
254 {
255 THERMAL_HILOGD(COMP_SVC, "Enter");
256 if (!ready_) {
257 return;
258 }
259 eventRunner_.reset();
260 handler_.reset();
261 ready_ = false;
262 RemoveSystemAbilityListener(COMMON_EVENT_SERVICE_ID);
263 if (thermalInterface_) {
264 thermalInterface_->Unregister();
265 thermalInterface_ = nullptr;
266 }
267 if (hdiServiceMgr_) {
268 hdiServiceMgr_->UnregisterServiceStatusListener(hdiServStatListener_);
269 hdiServiceMgr_ = nullptr;
270 }
271 }
272
SubscribeThermalTempCallback(const std::vector<std::string> & typeList,const sptr<IThermalTempCallback> & callback)273 bool ThermalService::SubscribeThermalTempCallback(
274 const std::vector<std::string>& typeList, const sptr<IThermalTempCallback>& callback)
275 {
276 THERMAL_HILOGD(COMP_SVC, "Enter");
277 auto uid = IPCSkeleton::GetCallingUid();
278 THERMAL_HILOGI(COMP_SVC, "uid %{public}d", uid);
279 observer_->SubscribeThermalTempCallback(typeList, callback);
280 return true;
281 }
282
UnSubscribeThermalTempCallback(const sptr<IThermalTempCallback> & callback)283 bool ThermalService::UnSubscribeThermalTempCallback(const sptr<IThermalTempCallback>& callback)
284 {
285 THERMAL_HILOGD(COMP_SVC, "Enter");
286 auto uid = IPCSkeleton::GetCallingUid();
287 THERMAL_HILOGI(COMP_SVC, "uid %{public}d", uid);
288 observer_->UnSubscribeThermalTempCallback(callback);
289 return true;
290 }
291
GetThermalSrvSensorInfo(const SensorType & type,ThermalSrvSensorInfo & sensorInfo)292 bool ThermalService::GetThermalSrvSensorInfo(const SensorType& type, ThermalSrvSensorInfo& sensorInfo)
293 {
294 THERMAL_HILOGD(COMP_SVC, "Enter");
295 if (!(observer_->GetThermalSrvSensorInfo(type, sensorInfo))) {
296 THERMAL_HILOGI(COMP_SVC, "failed to get temp for sensor type");
297 return false;
298 }
299 return true;
300 }
301
SubscribeThermalLevelCallback(const sptr<IThermalLevelCallback> & callback)302 bool ThermalService::SubscribeThermalLevelCallback(const sptr<IThermalLevelCallback>& callback)
303 {
304 THERMAL_HILOGD(COMP_SVC, "Enter");
305 auto uid = IPCSkeleton::GetCallingUid();
306 THERMAL_HILOGI(COMP_SVC, "uid %{public}d", uid);
307 actionMgr_->SubscribeThermalLevelCallback(callback);
308 return true;
309 }
310
UnSubscribeThermalLevelCallback(const sptr<IThermalLevelCallback> & callback)311 bool ThermalService::UnSubscribeThermalLevelCallback(const sptr<IThermalLevelCallback>& callback)
312 {
313 THERMAL_HILOGD(COMP_SVC, "Enter");
314 auto uid = IPCSkeleton::GetCallingUid();
315 THERMAL_HILOGI(COMP_SVC, "uid %{public}d", uid);
316 actionMgr_->UnSubscribeThermalLevelCallback(callback);
317 return true;
318 }
319
SubscribeThermalActionCallback(const std::vector<std::string> & actionList,const std::string & desc,const sptr<IThermalActionCallback> & callback)320 bool ThermalService::SubscribeThermalActionCallback(
321 const std::vector<std::string>& actionList, const std::string& desc, const sptr<IThermalActionCallback>& callback)
322 {
323 THERMAL_HILOGD(COMP_SVC, "Enter");
324 auto pid = IPCSkeleton::GetCallingPid();
325 auto uid = IPCSkeleton::GetCallingUid();
326 THERMAL_HILOGI(COMP_SVC, "pid %{public}d", pid);
327 THERMAL_HILOGI(COMP_SVC, "uid %{public}d", uid);
328 observer_->SubscribeThermalActionCallback(actionList, desc, callback);
329 return true;
330 }
331
UnSubscribeThermalActionCallback(const sptr<IThermalActionCallback> & callback)332 bool ThermalService::UnSubscribeThermalActionCallback(const sptr<IThermalActionCallback>& callback)
333 {
334 THERMAL_HILOGD(COMP_SVC, "Enter");
335 auto pid = IPCSkeleton::GetCallingPid();
336 auto uid = IPCSkeleton::GetCallingUid();
337 THERMAL_HILOGI(COMP_SVC, "pid %{public}d", pid);
338 THERMAL_HILOGI(COMP_SVC, "uid %{public}d", uid);
339 observer_->UnSubscribeThermalActionCallback(callback);
340 return true;
341 }
342
GetThermalLevel(ThermalLevel & level)343 bool ThermalService::GetThermalLevel(ThermalLevel& level)
344 {
345 uint32_t levelValue = actionMgr_->GetThermalLevel();
346 level = static_cast<ThermalLevel>(levelValue);
347 return true;
348 }
349
GetThermalInfo()350 bool ThermalService::GetThermalInfo()
351 {
352 THERMAL_HILOGD(COMP_SVC, "Enter");
353 HdfThermalCallbackInfo thermalInfo;
354 bool ret = false;
355 if (thermalInterface_ == nullptr) {
356 thermalInterface_ = IThermalInterface::Get();
357 if (thermalInterface_ == nullptr) {
358 THERMAL_HILOGD(COMP_SVC, "thermalInterface_ is nullptr");
359 return ret;
360 }
361 }
362
363 if (thermalInterface_ != nullptr) {
364 int32_t res = thermalInterface_->GetThermalZoneInfo(thermalInfo);
365 HandleThermalCallbackEvent(thermalInfo);
366 if (!res) {
367 ret = true;
368 }
369 }
370 return ret;
371 }
372
SetScene(const std::string & scene)373 bool ThermalService::SetScene(const std::string& scene)
374 {
375 scene_ = scene;
376 return true;
377 }
378
SendEvent(int32_t event,int64_t delayTime)379 void ThermalService::SendEvent(int32_t event, int64_t delayTime)
380 {
381 THERMAL_RETURN_IF_WITH_LOG(handler_ == nullptr, "handler is nullptr");
382 handler_->RemoveEvent(event);
383 handler_->SendEvent(event, 0, delayTime);
384 }
385
HandleEvent(int event)386 void ThermalService::HandleEvent(int event)
387 {
388 THERMAL_HILOGD(COMP_SVC, "Enter");
389 switch (event) {
390 case ThermalsrvEventHandler::SEND_REGISTER_THERMAL_HDI_CALLBACK: {
391 RegisterThermalHdiCallback();
392 break;
393 }
394 case ThermalsrvEventHandler::SEND_RETRY_REGISTER_HDI_STATUS_LISTENER: {
395 RegisterHdiStatusListener();
396 break;
397 }
398 case ThermalsrvEventHandler::SEND_ACTION_HUB_LISTENER: {
399 policy_->FindSubscribeActionValue();
400 break;
401 }
402 default:
403 break;
404 }
405 }
406
RegisterHdiStatusListener()407 void ThermalService::RegisterHdiStatusListener()
408 {
409 THERMAL_HILOGD(COMP_SVC, "Enter");
410 hdiServiceMgr_ = IServiceManager::Get();
411 if (hdiServiceMgr_ == nullptr) {
412 SendEvent(ThermalsrvEventHandler::SEND_RETRY_REGISTER_HDI_STATUS_LISTENER, RETRY_TIME);
413 THERMAL_HILOGW(COMP_SVC, "hdi service manager is nullptr, \
414 Try again after %{public}u second",
415 RETRY_TIME);
416 return;
417 }
418
419 hdiServStatListener_ = new HdiServiceStatusListener(
420 HdiServiceStatusListener::StatusCallback([&](const OHOS::HDI::ServiceManager::V1_0::ServiceStatus& status) {
421 THERMAL_RETURN_IF(status.serviceName != HDI_SERVICE_NAME || status.deviceClass != DEVICE_CLASS_DEFAULT)
422
423 if (status.status == SERVIE_STATUS_START) {
424 SendEvent(ThermalsrvEventHandler::SEND_REGISTER_THERMAL_HDI_CALLBACK, 0);
425 THERMAL_HILOGD(COMP_SVC, "thermal interface service start");
426 } else if (status.status == SERVIE_STATUS_STOP && thermalInterface_) {
427 thermalInterface_->Unregister();
428 thermalInterface_ = nullptr;
429 THERMAL_HILOGW(COMP_SVC, "thermal interface service, unregister interface");
430 }
431 }));
432
433 int32_t status = hdiServiceMgr_->RegisterServiceStatusListener(hdiServStatListener_, DEVICE_CLASS_DEFAULT);
434 if (status != ERR_OK) {
435 THERMAL_HILOGW(COMP_SVC, "Register hdi failed, \
436 Try again after %{public}u second",
437 RETRY_TIME);
438 SendEvent(ThermalsrvEventHandler::SEND_RETRY_REGISTER_HDI_STATUS_LISTENER, RETRY_TIME);
439 }
440 }
441
RegisterThermalHdiCallback()442 void ThermalService::RegisterThermalHdiCallback()
443 {
444 THERMAL_HILOGD(COMP_SVC, "Enter");
445 if (serviceSubscriber_ == nullptr) {
446 serviceSubscriber_ = std::make_shared<ThermalServiceSubscriber>();
447 THERMAL_RETURN_IF_WITH_LOG(!(serviceSubscriber_->Init()), "thermal service suvscriber start fail");
448 }
449
450 THERMAL_HILOGD(COMP_SVC, "register thermal hdi callback");
451 if (thermalInterface_ == nullptr) {
452 thermalInterface_ = IThermalInterface::Get();
453 THERMAL_RETURN_IF_WITH_LOG(thermalInterface_ == nullptr, "failed to get thermal hdi interface");
454 }
455
456 sptr<IThermalCallback> callback = new ThermalCallback();
457 ThermalCallback::ThermalEventCallback eventCb =
458 std::bind(&ThermalService::HandleThermalCallbackEvent, this, std::placeholders::_1);
459 ThermalCallback::RegisterThermalEvent(eventCb);
460 int32_t ret = thermalInterface_->Register(callback);
461 THERMAL_HILOGI(COMP_SVC, "register thermal hdi callback end, ret: %{public}d", ret);
462 }
463
HandleThermalCallbackEvent(const HdfThermalCallbackInfo & event)464 int32_t ThermalService::HandleThermalCallbackEvent(const HdfThermalCallbackInfo& event)
465 {
466 TypeTempMap typeTempMap;
467 if (!event.info.empty()) {
468 for (auto iter = event.info.begin(); iter != event.info.end(); iter++) {
469 typeTempMap.insert(std::make_pair(iter->type, iter->temp));
470 }
471 }
472 serviceSubscriber_->OnTemperatureChanged(typeTempMap);
473 return ERR_OK;
474 }
475
ShellDump(const std::vector<std::string> & args,uint32_t argc)476 std::string ThermalService::ShellDump(const std::vector<std::string>& args, uint32_t argc)
477 {
478 auto uid = IPCSkeleton::GetCallingUid();
479 if (uid >= APP_FIRST_UID) {
480 THERMAL_HILOGE(COMP_FWK, "Request failed, %{public}d permission check failed", uid);
481 return nullptr;
482 }
483
484 std::lock_guard<std::mutex> lock(mutex_);
485 pid_t pid = IPCSkeleton::GetCallingPid();
486 THERMAL_HILOGI(COMP_SVC, "PID: %{public}d", pid);
487 std::string result;
488 bool ret = ThermalMgrDumper::Dump(args, result);
489 THERMAL_HILOGI(COMP_SVC, "ThermalMgrDumper :%{public}d", ret);
490 return result;
491 }
492
Dump(int fd,const std::vector<std::u16string> & args)493 int32_t ThermalService::Dump(int fd, const std::vector<std::u16string>& args)
494 {
495 THERMAL_HILOGD(COMP_SVC, "Enter");
496 std::vector<std::string> argsInStr;
497 std::transform(args.begin(), args.end(), std::back_inserter(argsInStr), [](const std::u16string& arg) {
498 std::string ret = Str16ToStr8(arg);
499 THERMAL_HILOGI(COMP_SVC, "arg: %{public}s", ret.c_str());
500 return ret;
501 });
502 std::string result;
503 ThermalMgrDumper::Dump(argsInStr, result);
504 if (!SaveStringToFd(fd, result)) {
505 THERMAL_HILOGE(COMP_SVC, "ThermalService::Dump failed, save to fd failed.");
506 THERMAL_HILOGE(COMP_SVC, "Dump Info:\n");
507 THERMAL_HILOGE(COMP_SVC, "%{public}s", result.c_str());
508 return ERR_OK;
509 }
510 return ERR_OK;
511 }
512 } // namespace PowerMgr
513 } // namespace OHOS
514