1 /*
2  * Copyright (c) 2021-2023 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 <thread>
27 #include <unistd.h>
28 
29 #ifdef HAS_THERMAL_CONFIG_POLICY_PART
30 #include "config_policy_utils.h"
31 #endif
32 #include "constants.h"
33 #include "ffrt_utils.h"
34 #include "permission.h"
35 #include "sysparam.h"
36 #include "thermal_common.h"
37 #include "thermal_mgr_dumper.h"
38 #include "xcollie/watchdog.h"
39 
40 namespace OHOS {
41 namespace PowerMgr {
42 sptr<ThermalService> ThermalService::instance_ = nullptr;
43 std::mutex ThermalService::singletonMutex_;
44 namespace {
45 const std::string THERMAL_SERVICE_CONFIG_PATH = "etc/thermal_config/thermal_service_config.xml";
46 const std::string VENDOR_THERMAL_SERVICE_CONFIG_PATH = "/vendor/etc/thermal_config/thermal_service_config.xml";
47 const std::string SYSTEM_THERMAL_SERVICE_CONFIG_PATH = "/system/etc/thermal_config/thermal_service_config.xml";
48 constexpr const char* HDI_SERVICE_NAME = "thermal_interface_service";
49 FFRTQueue g_queue("thermal_service");
50 constexpr uint32_t RETRY_TIME = 1000;
51 auto g_service = ThermalService::GetInstance();
52 const bool G_REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(g_service.GetRefPtr());
53 SysParam::BootCompletedCallback g_bootCompletedCallback;
54 } // namespace
55 std::atomic_bool ThermalService::isBootCompleted_ = false;
56 std::string ThermalService::scene_;
57 #ifdef HAS_THERMAL_AIRPLANE_MANAGER_PART
58 bool ThermalService::userAirplaneState_ = false;
59 bool ThermalService::isThermalAirplane_ = false;
60 #endif
ThermalService()61 ThermalService::ThermalService() : SystemAbility(POWER_MANAGER_THERMAL_SERVICE_ID, true) {}
62 
~ThermalService()63 ThermalService::~ThermalService() {}
64 
GetInstance()65 sptr<ThermalService> ThermalService::GetInstance()
66 {
67     if (instance_ == nullptr) {
68         std::lock_guard<std::mutex> lock(singletonMutex_);
69         if (instance_ == nullptr) {
70             instance_ = new ThermalService();
71         }
72     }
73     return instance_;
74 }
75 
OnStart()76 void ThermalService::OnStart()
77 {
78     THERMAL_HILOGD(COMP_SVC, "Enter");
79     if (ready_) {
80         THERMAL_HILOGE(COMP_SVC, "OnStart is ready, nothing to do");
81         return;
82     }
83 
84     if (!(Init())) {
85         THERMAL_HILOGE(COMP_SVC, "OnStart call init fail");
86         return;
87     }
88 
89     AddSystemAbilityListener(COMMON_EVENT_SERVICE_ID);
90     if (!Publish(ThermalService::GetInstance())) {
91         THERMAL_HILOGE(COMP_SVC, "OnStart register to system ability manager failed.");
92         return;
93     }
94     RegisterBootCompletedCallback();
95     ready_ = true;
96     THERMAL_HILOGD(COMP_SVC, "OnStart and add system ability success");
97 }
98 
RegisterBootCompletedCallback()99 void ThermalService::RegisterBootCompletedCallback()
100 {
101     g_bootCompletedCallback = []() {
102         isBootCompleted_ = true;
103     };
104     SysParam::RegisterBootCompletedCallback(g_bootCompletedCallback);
105 }
106 
OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId)107 void ThermalService::OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
108 {
109     THERMAL_HILOGI(COMP_SVC, "systemAbilityId=%{public}d, deviceId=%{private}s", systemAbilityId, deviceId.c_str());
110     if (systemAbilityId == COMMON_EVENT_SERVICE_ID) {
111         InitStateMachine();
112 #ifdef HAS_THERMAL_AIRPLANE_MANAGER_PART
113         SubscribeCommonEvent();
114 #endif
115     }
116 }
117 
118 #ifdef HAS_THERMAL_AIRPLANE_MANAGER_PART
SubscribeCommonEvent()119 bool ThermalService::SubscribeCommonEvent()
120 {
121     using namespace OHOS::EventFwk;
122     bool result = false;
123     MatchingSkills matchingSkills;
124     matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_AIRPLANE_MODE_CHANGED);
125     CommonEventSubscribeInfo subscribeInfo(matchingSkills);
126     subscribeInfo.SetThreadMode(CommonEventSubscribeInfo::ThreadMode::COMMON);
127     if (!subscriberPtr_) {
128         subscriberPtr_ = std::make_shared<AirplaneCommonEventSubscriber>(subscribeInfo);
129     }
130     result = CommonEventManager::SubscribeCommonEvent(subscriberPtr_);
131     if (!result) {
132         THERMAL_HILOGE(COMP_SVC, "Subscribe CommonEvent failed");
133     } else {
134         THERMAL_HILOGD(COMP_SVC, "Subscribe CommonEvent success");
135     }
136     return result;
137 }
138 
OnReceiveEvent(const OHOS::EventFwk::CommonEventData &data)139 void AirplaneCommonEventSubscriber::OnReceiveEvent(const OHOS::EventFwk::CommonEventData &data)
140 {
141     if (!ThermalService::isThermalAirplane_) {
142         int32_t code = data.GetCode();
143         ThermalService::userAirplaneState_ = static_cast<bool>(code);
144         THERMAL_HILOGD(COMP_SVC, "user %{public}s Airplane mode",
145             ThermalService::userAirplaneState_ ? "open" : "close");
146     } else {
147         ThermalService::isThermalAirplane_ = false;
148         THERMAL_HILOGD(COMP_SVC, "thermal change Airplane mode");
149     }
150 }
151 #endif
152 
Init()153 bool ThermalService::Init()
154 {
155     THERMAL_HILOGD(COMP_SVC, "Enter");
156     if (!CreateConfigModule()) {
157         return false;
158     }
159     if (!InitModules()) {
160         return false;
161     }
162     RegisterHdiStatusListener();
163     THERMAL_HILOGD(COMP_SVC, "Init success");
164     return true;
165 }
166 
CreateConfigModule()167 bool ThermalService::CreateConfigModule()
168 {
169     if (!baseInfo_) {
170         baseInfo_ = std::make_shared<ThermalConfigBaseInfo>();
171         if (baseInfo_ == nullptr) {
172             THERMAL_HILOGE(COMP_SVC, "failed to create base info");
173             return false;
174         }
175     }
176 
177     if (!state_) {
178         state_ = std::make_shared<StateMachine>();
179         if (state_ == nullptr) {
180             THERMAL_HILOGE(COMP_SVC, "failed to create state machine");
181             return false;
182         }
183     }
184 
185     if (!actionMgr_) {
186         actionMgr_ = std::make_shared<ThermalActionManager>();
187         if (actionMgr_ == nullptr) {
188             THERMAL_HILOGE(COMP_SVC, "failed to create action manager");
189             return false;
190         }
191     }
192 
193     if (!policy_) {
194         policy_ = std::make_shared<ThermalPolicy>();
195         if (policy_ == nullptr) {
196             THERMAL_HILOGE(COMP_SVC, "failed to create thermal policy");
197             return false;
198         }
199     }
200 
201     if (!fanFaultDetect_) {
202         fanFaultDetect_ = std::make_shared<FanFaultDetect>();
203         if (fanFaultDetect_ == nullptr) {
204             THERMAL_HILOGE(COMP_SVC, "failed to create fan fault detect");
205             return false;
206         }
207     }
208 
209     return true;
210 }
211 
InitConfigFile()212 bool ThermalService::InitConfigFile()
213 {
214     if (serviceConfigParsed) {
215         THERMAL_HILOGI(COMP_SVC, "system config file has parsed.");
216         return true;
217     }
218 #ifdef HAS_THERMAL_CONFIG_POLICY_PART
219     char buf[MAX_PATH_LEN];
220     char* path = GetOneCfgFile(THERMAL_SERVICE_CONFIG_PATH.c_str(), buf, MAX_PATH_LEN);
221     if (path != nullptr && *path != '\0') {
222         if (configParser_.ThermalSrvConfigInit(path)) {
223             THERMAL_HILOGD(COMP_SVC, "match pliocy config file");
224             return true;
225         }
226         THERMAL_HILOGE(COMP_SVC, "pliocy config file config init err");
227         return false;
228     }
229 #endif
230 
231     if (configParser_.ThermalSrvConfigInit(VENDOR_THERMAL_SERVICE_CONFIG_PATH)) {
232         THERMAL_HILOGD(COMP_SVC, "thermal service config init suc:VENDOR_CONFIG");
233         return true;
234     }
235 
236     if (configParser_.ThermalSrvConfigInit(SYSTEM_THERMAL_SERVICE_CONFIG_PATH)) {
237         THERMAL_HILOGD(COMP_SVC, "thermal service config init suc:SYSTEM_CONFIG");
238         return true;
239     }
240 
241     return false;
242 }
243 
244 
InitConfigModule()245 bool ThermalService::InitConfigModule()
246 {
247     THERMAL_HILOGD(COMP_SVC, "InitVendor Enter");
248     if (!CreateConfigModule()) {
249         THERMAL_HILOGD(COMP_SVC, "CreateConfigModule fail");
250     }
251 
252     if (!configParser_.ThermalSrvConfigInit(SYSTEM_THERMAL_SERVICE_CONFIG_PATH)) {
253         THERMAL_HILOGE(COMP_SVC, "system thermal service config init failed.");
254         return false;
255     }
256     serviceConfigParsed = true;
257 
258     THERMAL_HILOGE(COMP_SVC, "system thermal service config init suc.");
259     return true;
260 }
261 
InitModules()262 bool ThermalService::InitModules()
263 {
264     if (!InitConfigFile()) {
265         return false;
266     }
267 
268     if (popup_ == nullptr) {
269         popup_ = std::make_shared<ActionPopup>(POPUP_ACTION_NAME);
270     }
271 
272     if (!InitThermalObserver()) {
273         THERMAL_HILOGE(COMP_SVC, "thermal observer start fail");
274         return false;
275     }
276 
277     if (!InitActionManager()) {
278         THERMAL_HILOGE(COMP_SVC, "action manager init fail");
279         return false;
280     }
281 
282     if (!InitThermalPolicy()) {
283         THERMAL_HILOGE(COMP_SVC, "thermal policy start fail");
284         return false;
285     }
286 
287     if (!InitThermalSubscriber()) {
288         THERMAL_HILOGE(COMP_SVC, "thermal subscriber init fail");
289         return false;
290     }
291     return true;
292 }
293 
InitThermalObserver()294 bool ThermalService::InitThermalObserver()
295 {
296     if (!InitBaseInfo()) {
297         return false;
298     }
299 
300     THERMAL_HILOGD(COMP_SVC, "Enter");
301     if (observer_ == nullptr) {
302         observer_ = std::make_shared<ThermalObserver>();
303         if (!(observer_->Init())) {
304             THERMAL_HILOGE(COMP_SVC, "InitThermalObserver: thermal observer start fail");
305             return false;
306         }
307     }
308     if (info_ == nullptr) {
309         info_ = std::make_shared<ThermalSensorInfo>();
310     }
311     THERMAL_HILOGI(COMP_SVC, "InitThermalObserver: Init Success");
312     return true;
313 }
314 
InitBaseInfo()315 bool ThermalService::InitBaseInfo()
316 {
317     THERMAL_HILOGD(COMP_SVC, "Enter");
318     if (!baseInfo_->Init()) {
319         THERMAL_HILOGE(COMP_SVC, "InitBaseInfo: base info init failed");
320         return false;
321     }
322     return true;
323 }
324 
InitStateMachine()325 bool ThermalService::InitStateMachine()
326 {
327     THERMAL_HILOGD(COMP_SVC, "Enter");
328     if (!state_->Init()) {
329         THERMAL_HILOGE(COMP_SVC, "InitStateMachine: state machine init failed");
330         return false;
331     }
332     return true;
333 }
334 
InitActionManager()335 bool ThermalService::InitActionManager()
336 {
337     THERMAL_HILOGD(COMP_SVC, "Enter");
338     if (!actionMgr_->Init()) {
339         THERMAL_HILOGE(COMP_SVC, "InitActionManager: action manager init failed");
340         return false;
341     }
342     return true;
343 }
344 
InitThermalPolicy()345 bool ThermalService::InitThermalPolicy()
346 {
347     THERMAL_HILOGD(COMP_SVC, "Enter");
348     if (!policy_->Init()) {
349         THERMAL_HILOGE(COMP_SVC, "InitThermalPolicy: policy init failed");
350         return false;
351     }
352     return true;
353 }
354 
InitThermalSubscriber()355 bool ThermalService::InitThermalSubscriber()
356 {
357     if (serviceSubscriber_ == nullptr) {
358         serviceSubscriber_ = std::make_shared<ThermalServiceSubscriber>();
359         if (!(serviceSubscriber_->Init())) {
360             THERMAL_HILOGE(COMP_SVC, "InitThermalSubscriber: thermal subscriber init failed");
361             return false;
362         }
363     }
364     return true;
365 }
366 
OnStop()367 void ThermalService::OnStop()
368 {
369     THERMAL_HILOGD(COMP_SVC, "Enter");
370     if (!ready_) {
371         return;
372     }
373     ready_ = false;
374     isBootCompleted_ = false;
375     RemoveSystemAbilityListener(COMMON_EVENT_SERVICE_ID);
376     if (thermalInterface_) {
377         thermalInterface_->Unregister();
378         thermalInterface_->UnregisterFanCallback();
379         thermalInterface_ = nullptr;
380     }
381     if (hdiServiceMgr_) {
382         hdiServiceMgr_->UnregisterServiceStatusListener(hdiServStatListener_);
383         hdiServiceMgr_ = nullptr;
384     }
385 #ifdef HAS_THERMAL_AIRPLANE_MANAGER_PART
386     if (!OHOS::EventFwk::CommonEventManager::UnSubscribeCommonEvent(subscriberPtr_)) {
387         THERMAL_HILOGE(COMP_SVC, "Thermal Onstop unregister to commonevent manager failed!");
388     } else {
389         THERMAL_HILOGD(COMP_SVC, "Thermal Onstop unregister to commonevent manager success!");
390     }
391 #endif
392 }
393 
SubscribeThermalTempCallback( const std::vector<std::string>& typeList, const sptr<IThermalTempCallback>& callback)394 bool ThermalService::SubscribeThermalTempCallback(
395     const std::vector<std::string>& typeList, const sptr<IThermalTempCallback>& callback)
396 {
397     if (!Permission::IsSystem()) {
398         return false;
399     }
400     auto uid = IPCSkeleton::GetCallingUid();
401     THERMAL_HILOGI(COMP_SVC, "%{public}s is called by uid=%{public}d", __func__, uid);
402     observer_->SubscribeThermalTempCallback(typeList, callback);
403     return true;
404 }
405 
UnSubscribeThermalTempCallback(const sptr<IThermalTempCallback>& callback)406 bool ThermalService::UnSubscribeThermalTempCallback(const sptr<IThermalTempCallback>& callback)
407 {
408     if (!Permission::IsSystem()) {
409         return false;
410     }
411     auto uid = IPCSkeleton::GetCallingUid();
412     THERMAL_HILOGI(COMP_SVC, "%{public}s is called by uid=%{public}d", __func__, uid);
413     observer_->UnSubscribeThermalTempCallback(callback);
414     return true;
415 }
416 
GetThermalSrvSensorInfo(const SensorType& type, ThermalSrvSensorInfo& sensorInfo)417 bool ThermalService::GetThermalSrvSensorInfo(const SensorType& type, ThermalSrvSensorInfo& sensorInfo)
418 {
419     THERMAL_HILOGD(COMP_SVC, "Enter");
420     if (!(observer_->GetThermalSrvSensorInfo(type, sensorInfo))) {
421         THERMAL_HILOGW(COMP_SVC, "failed to get sensor temp, type enum: %{public}u", static_cast<uint32_t>(type));
422         return false;
423     }
424     return true;
425 }
426 
SubscribeThermalLevelCallback(const sptr<IThermalLevelCallback>& callback)427 bool ThermalService::SubscribeThermalLevelCallback(const sptr<IThermalLevelCallback>& callback)
428 {
429     auto uid = IPCSkeleton::GetCallingUid();
430     THERMAL_HILOGI(COMP_SVC, "%{public}s is called by uid=%{public}d", __func__, uid);
431     actionMgr_->SubscribeThermalLevelCallback(callback);
432     return true;
433 }
434 
UnSubscribeThermalLevelCallback(const sptr<IThermalLevelCallback>& callback)435 bool ThermalService::UnSubscribeThermalLevelCallback(const sptr<IThermalLevelCallback>& callback)
436 {
437     auto uid = IPCSkeleton::GetCallingUid();
438     THERMAL_HILOGI(COMP_SVC, "%{public}s is called by uid=%{public}d", __func__, uid);
439     actionMgr_->UnSubscribeThermalLevelCallback(callback);
440     return true;
441 }
442 
SubscribeThermalActionCallback( const std::vector<std::string>& actionList, const std::string& desc, const sptr<IThermalActionCallback>& callback)443 bool ThermalService::SubscribeThermalActionCallback(
444     const std::vector<std::string>& actionList, const std::string& desc, const sptr<IThermalActionCallback>& callback)
445 {
446     if (!Permission::IsSystem()) {
447         return false;
448     }
449     auto pid = IPCSkeleton::GetCallingPid();
450     auto uid = IPCSkeleton::GetCallingUid();
451     THERMAL_HILOGI(COMP_SVC, "%{public}s is called by pid=%{public}d, uid=%{public}d", __func__, pid, uid);
452     observer_->SubscribeThermalActionCallback(actionList, desc, callback);
453     return true;
454 }
455 
UnSubscribeThermalActionCallback(const sptr<IThermalActionCallback>& callback)456 bool ThermalService::UnSubscribeThermalActionCallback(const sptr<IThermalActionCallback>& callback)
457 {
458     if (!Permission::IsSystem()) {
459         return false;
460     }
461     auto pid = IPCSkeleton::GetCallingPid();
462     auto uid = IPCSkeleton::GetCallingUid();
463     THERMAL_HILOGI(COMP_SVC, "%{public}s is called by pid=%{public}d, uid=%{public}d", __func__, pid, uid);
464     observer_->UnSubscribeThermalActionCallback(callback);
465     return true;
466 }
467 
GetThermalLevel(ThermalLevel& level)468 bool ThermalService::GetThermalLevel(ThermalLevel& level)
469 {
470     uint32_t levelValue = actionMgr_->GetThermalLevel();
471     level = static_cast<ThermalLevel>(levelValue);
472     return true;
473 }
474 
GetThermalInfo()475 bool ThermalService::GetThermalInfo()
476 {
477     THERMAL_HILOGD(COMP_SVC, "Enter");
478     HdfThermalCallbackInfo thermalInfo;
479     bool ret = false;
480     if (thermalInterface_ == nullptr) {
481         thermalInterface_ = IThermalInterface::Get();
482         if (thermalInterface_ == nullptr) {
483             THERMAL_HILOGD(COMP_SVC, "thermalInterface_ is nullptr");
484             return ret;
485         }
486     }
487 
488     if (thermalInterface_ != nullptr) {
489         int32_t res = thermalInterface_->GetThermalZoneInfo(thermalInfo);
490         HandleThermalCallbackEvent(thermalInfo);
491         if (!res) {
492             ret = true;
493         }
494     }
495     return ret;
496 }
497 
SetScene(const std::string& scene)498 bool ThermalService::SetScene(const std::string& scene)
499 {
500     if (!Permission::IsSystem()) {
501         return false;
502     }
503     scene_ = scene;
504     return true;
505 }
506 
UpdateThermalState(const std::string& tag, const std::string& val, bool isImmed)507 bool ThermalService::UpdateThermalState(const std::string& tag, const std::string& val, bool isImmed)
508 {
509     if (!Permission::IsSystem()) {
510         return false;
511     }
512     THERMAL_HILOGI(COMP_SVC, "tag %{public}s, val %{public}s", tag.c_str(), val.c_str());
513     std::lock_guard<std::mutex> lock(mutex_);
514     state_->UpdateState(tag, val);
515     if (isImmed) {
516         policy_->ExecutePolicy();
517     }
518     return true;
519 }
520 
RegisterHdiStatusListener()521 void ThermalService::RegisterHdiStatusListener()
522 {
523     THERMAL_HILOGD(COMP_SVC, "Enter");
524     hdiServiceMgr_ = IServiceManager::Get();
525     if (hdiServiceMgr_ == nullptr) {
526         FFRTTask retryTask = [this] {
527             return RegisterHdiStatusListener();
528         };
529         FFRTUtils::SubmitDelayTask(retryTask, RETRY_TIME, g_queue);
530         THERMAL_HILOGW(COMP_SVC, "hdi service manager is nullptr, try again after %{public}u ms", RETRY_TIME);
531         return;
532     }
533 
534     hdiServStatListener_ = new HdiServiceStatusListener(
535         HdiServiceStatusListener::StatusCallback([&](const OHOS::HDI::ServiceManager::V1_0::ServiceStatus& status) {
536             THERMAL_RETURN_IF(status.serviceName != HDI_SERVICE_NAME || status.deviceClass != DEVICE_CLASS_DEFAULT)
537 
538             if (status.status == SERVIE_STATUS_START) {
539                 FFRTTask task = [this] {
540                     RegisterThermalHdiCallback();
541                     RegisterFanHdiCallback();
542                 };
543                 FFRTUtils::SubmitTask(task);
544                 THERMAL_HILOGD(COMP_SVC, "thermal interface service start");
545             } else if (status.status == SERVIE_STATUS_STOP && thermalInterface_) {
546                 thermalInterface_->Unregister();
547                 thermalInterface_->UnregisterFanCallback();
548                 thermalInterface_ = nullptr;
549                 THERMAL_HILOGW(COMP_SVC, "thermal interface service, unregister interface");
550             }
551         }));
552 
553     int32_t status = hdiServiceMgr_->RegisterServiceStatusListener(hdiServStatListener_, DEVICE_CLASS_DEFAULT);
554     if (status != ERR_OK) {
555         THERMAL_HILOGW(COMP_SVC, "Register hdi failed, try again after %{public}u ms", RETRY_TIME);
556         FFRTTask retryTask = [this] {
557             return RegisterHdiStatusListener();
558         };
559         FFRTUtils::SubmitDelayTask(retryTask, RETRY_TIME, g_queue);
560     }
561 }
562 
RegisterThermalHdiCallback()563 void ThermalService::RegisterThermalHdiCallback()
564 {
565     THERMAL_HILOGD(COMP_SVC, "register thermal hdi callback");
566     if (thermalInterface_ == nullptr) {
567         thermalInterface_ = IThermalInterface::Get();
568         THERMAL_RETURN_IF_WITH_LOG(thermalInterface_ == nullptr, "failed to get thermal hdi interface");
569     }
570 
571     sptr<IThermalCallback> callback = new ThermalCallback();
572     ThermalCallback::ThermalEventCallback eventCb =
573         [this](const HdfThermalCallbackInfo& event) -> int32_t { return this->HandleThermalCallbackEvent(event); };
574     ThermalCallback::RegisterThermalEvent(eventCb);
575     int32_t ret = thermalInterface_->Register(callback);
576     THERMAL_HILOGI(COMP_SVC, "register thermal hdi callback end, ret: %{public}d", ret);
577 }
578 
UnRegisterThermalHdiCallback()579 void ThermalService::UnRegisterThermalHdiCallback()
580 {
581     if (thermalInterface_ == nullptr) {
582         FFRTTask retryTask = [this] {
583             return UnRegisterThermalHdiCallback();
584         };
585         FFRTUtils::SubmitDelayTask(retryTask, RETRY_TIME, g_queue);
586         THERMAL_HILOGW(COMP_SVC, "thermalInterface_ is nullptr, try again after %{public}u ms", RETRY_TIME);
587         return;
588     }
589     int32_t ret = thermalInterface_->Unregister();
590     THERMAL_HILOGI(COMP_SVC, "unregister thermal hdi callback end, ret: %{public}d", ret);
591 }
592 
HandleThermalCallbackEvent(const HdfThermalCallbackInfo& event)593 int32_t ThermalService::HandleThermalCallbackEvent(const HdfThermalCallbackInfo& event)
594 {
595 #ifndef THERMAL_USER_VERSION
596     if (!isTempReport_) {
597         return ERR_OK;
598     }
599 #endif
600     TypeTempMap typeTempMap;
601     if (!event.info.empty()) {
602         for (auto iter = event.info.begin(); iter != event.info.end(); iter++) {
603             typeTempMap.insert(std::make_pair(iter->type, iter->temp));
604         }
605     }
606     std::lock_guard<std::mutex> lock(mutex_);
607     serviceSubscriber_->OnTemperatureChanged(typeTempMap);
608     return ERR_OK;
609 }
610 
HandleTempEmulation(const TypeTempMap& typeTempMap)611 bool ThermalService::HandleTempEmulation(const TypeTempMap& typeTempMap)
612 {
613     if (isTempReport_) {
614         return false;
615     }
616     std::lock_guard<std::mutex> lock(mutex_);
617     serviceSubscriber_->OnTemperatureChanged(typeTempMap);
618     return true;
619 }
620 
RegisterFanHdiCallback()621 void ThermalService::RegisterFanHdiCallback()
622 {
623     if (!fanFaultDetect_->HasFanConfig()) {
624         return;
625     }
626 
627     if (thermalInterface_ == nullptr) {
628         thermalInterface_ = IThermalInterface::Get();
629         THERMAL_RETURN_IF_WITH_LOG(thermalInterface_ == nullptr, "failed to get thermal hdi interface");
630     }
631 
632     sptr<IFanCallback> callback = new FanCallback();
633     FanCallback::FanEventCallback eventCb =
634         [this](const HdfThermalCallbackInfo& event) -> int32_t { return this->HandleFanCallbackEvent(event); };
635     FanCallback::RegisterFanEvent(eventCb);
636     int32_t ret = thermalInterface_->RegisterFanCallback(callback);
637     THERMAL_HILOGI(COMP_SVC, "register fan hdi callback end, ret: %{public}d", ret);
638 
639     return;
640 }
641 
HandleFanCallbackEvent(const HdfThermalCallbackInfo& event)642 int32_t ThermalService::HandleFanCallbackEvent(const HdfThermalCallbackInfo& event)
643 {
644     FanSensorInfo report;
645     if (!event.info.empty()) {
646         for (auto iter = event.info.begin(); iter != event.info.end(); iter++) {
647             report.insert(std::make_pair(iter->type, iter->temp));
648         }
649     }
650 
651     fanFaultDetect_->OnFanSensorInfoChanged(report);
652     return ERR_OK;
653 }
654 
ShellDump(const std::vector<std::string>& args, uint32_t argc)655 std::string ThermalService::ShellDump(const std::vector<std::string>& args, uint32_t argc)
656 {
657     if (!Permission::IsSystem() || !isBootCompleted_) {
658         return "";
659     }
660     std::lock_guard<std::mutex> lock(mutex_);
661     pid_t pid = IPCSkeleton::GetCallingPid();
662     THERMAL_HILOGI(COMP_SVC, "PID: %{public}d", pid);
663     std::string result;
664     bool ret = ThermalMgrDumper::Dump(args, result);
665     THERMAL_HILOGI(COMP_SVC, "ThermalMgrDumper :%{public}d", ret);
666     return result;
667 }
668 
Dump(int fd, const std::vector<std::u16string>& args)669 int32_t ThermalService::Dump(int fd, const std::vector<std::u16string>& args)
670 {
671     if (!isBootCompleted_) {
672         return ERR_NO_INIT;
673     }
674     if (!Permission::IsSystem()) {
675         return ERR_PERMISSION_DENIED;
676     }
677     std::vector<std::string> argsInStr;
678     std::transform(args.begin(), args.end(), std::back_inserter(argsInStr), [](const std::u16string& arg) {
679         std::string ret = Str16ToStr8(arg);
680         THERMAL_HILOGI(COMP_SVC, "arg: %{public}s", ret.c_str());
681         return ret;
682     });
683     std::string result;
684     ThermalMgrDumper::Dump(argsInStr, result);
685     if (!SaveStringToFd(fd, result)) {
686         THERMAL_HILOGE(COMP_SVC, "ThermalService::Dump failed, save to fd failed.");
687         THERMAL_HILOGE(COMP_SVC, "Dump Info:\n");
688         THERMAL_HILOGE(COMP_SVC, "%{public}s", result.c_str());
689         return ERR_OK;
690     }
691     return ERR_OK;
692 }
693 
EnableMock(const std::string& actionName, void* mockObject)694 void ThermalService::EnableMock(const std::string& actionName, void* mockObject)
695 {
696     std::lock_guard<std::mutex> lock(mutex_);
697     actionMgr_->EnableMock(actionName, mockObject);
698 }
699 
DestroyInstance()700 void ThermalService::DestroyInstance()
701 {
702     std::lock_guard<std::mutex> lock(singletonMutex_);
703     if (instance_) {
704         instance_.clear();
705         instance_ = nullptr;
706     }
707 }
708 } // namespace PowerMgr
709 } // namespace OHOS
710