• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "constants.h"
30 #include "permission.h"
31 #include "sysparam.h"
32 #include "thermal_common.h"
33 #include "thermal_mgr_dumper.h"
34 #include "thermal_srv_config_parser.h"
35 #include "ffrt_utils.h"
36 #include "xcollie/watchdog.h"
37 
38 #include "config_policy_utils.h"
39 
40 namespace OHOS {
41 namespace PowerMgr {
42 namespace {
43 const std::string THERMAL_SERVICE_CONFIG_PATH = "etc/thermal_config/thermal_service_config.xml";
44 const std::string VENDOR_THERMAL_SERVICE_CONFIG_PATH = "/vendor/etc/thermal_config/thermal_service_config.xml";
45 const std::string SYSTEM_THERMAL_SERVICE_CONFIG_PATH = "/system/etc/thermal_config/thermal_service_config.xml";
46 constexpr const char* THMERMAL_SERVICE_NAME = "ThermalService";
47 constexpr const char* HDI_SERVICE_NAME = "thermal_interface_service";
48 FFRTQueue g_queue("thermal_service");
49 constexpr uint32_t RETRY_TIME = 1000;
50 auto g_service = DelayedSpSingleton<ThermalService>::GetInstance();
51 const bool G_REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(g_service.GetRefPtr());
52 SysParam::BootCompletedCallback g_bootCompletedCallback;
53 } // namespace
54 std::atomic_bool ThermalService::isBootCompleted_ = false;
ThermalService()55 ThermalService::ThermalService() : SystemAbility(POWER_MANAGER_THERMAL_SERVICE_ID, true) {}
56 
~ThermalService()57 ThermalService::~ThermalService() {}
58 
OnStart()59 void ThermalService::OnStart()
60 {
61     THERMAL_HILOGD(COMP_SVC, "Enter");
62     if (ready_) {
63         THERMAL_HILOGE(COMP_SVC, "OnStart is ready, nothing to do");
64         return;
65     }
66 
67     if (!(Init())) {
68         THERMAL_HILOGE(COMP_SVC, "OnStart call init fail");
69         return;
70     }
71 
72     AddSystemAbilityListener(COMMON_EVENT_SERVICE_ID);
73     if (!Publish(DelayedSpSingleton<ThermalService>::GetInstance())) {
74         THERMAL_HILOGE(COMP_SVC, "OnStart register to system ability manager failed.");
75         return;
76     }
77     RegisterBootCompletedCallback();
78     ready_ = true;
79     THERMAL_HILOGD(COMP_SVC, "OnStart and add system ability success");
80 }
81 
RegisterBootCompletedCallback()82 void ThermalService::RegisterBootCompletedCallback()
83 {
84     g_bootCompletedCallback = []() {
85         isBootCompleted_ = true;
86     };
87     SysParam::RegisterBootCompletedCallback(g_bootCompletedCallback);
88 }
89 
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)90 void ThermalService::OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
91 {
92     THERMAL_HILOGI(COMP_SVC, "systemAbilityId=%{public}d, deviceId=%{private}s", systemAbilityId, deviceId.c_str());
93     if (systemAbilityId == COMMON_EVENT_SERVICE_ID) {
94         InitStateMachine();
95     }
96 }
97 
Init()98 bool ThermalService::Init()
99 {
100     THERMAL_HILOGD(COMP_SVC, "Enter");
101     if (!CreateConfigModule()) {
102         return false;
103     }
104     if (!InitModules()) {
105         return false;
106     }
107     RegisterHdiStatusListener();
108     THERMAL_HILOGD(COMP_SVC, "Init success");
109     return true;
110 }
111 
CreateConfigModule()112 bool ThermalService::CreateConfigModule()
113 {
114     if (!baseInfo_) {
115         baseInfo_ = std::make_shared<ThermalConfigBaseInfo>();
116         if (baseInfo_ == nullptr) {
117             THERMAL_HILOGE(COMP_SVC, "failed to create base info");
118             return false;
119         }
120     }
121 
122     if (!state_) {
123         state_ = std::make_shared<StateMachine>();
124         if (state_ == nullptr) {
125             THERMAL_HILOGE(COMP_SVC, "failed to create state machine");
126             return false;
127         }
128     }
129 
130     if (!actionMgr_) {
131         actionMgr_ = std::make_shared<ThermalActionManager>();
132         if (actionMgr_ == nullptr) {
133             THERMAL_HILOGE(COMP_SVC, "failed to create action manager");
134             return false;
135         }
136     }
137 
138     if (!policy_) {
139         policy_ = std::make_shared<ThermalPolicy>();
140         if (policy_ == nullptr) {
141             THERMAL_HILOGE(COMP_SVC, "failed to create thermal policy");
142             return false;
143         }
144     }
145 
146     if (!fanFaultDetect_) {
147         fanFaultDetect_ = std::make_shared<FanFaultDetect>();
148         if (fanFaultDetect_ == nullptr) {
149             THERMAL_HILOGE(COMP_SVC, "failed to create fan fault detect");
150             return false;
151         }
152     }
153 
154     return true;
155 }
156 
InitConfigFile()157 bool ThermalService::InitConfigFile()
158 {
159     char buf[MAX_PATH_LEN];
160     char* path = GetOneCfgFile(THERMAL_SERVICE_CONFIG_PATH.c_str(), buf, MAX_PATH_LEN);
161     if (path != nullptr && *path != '\0') {
162         if (ThermalSrvConfigParser::GetInstance().ThermalSrvConfigInit(path)) {
163             THERMAL_HILOGD(COMP_SVC, "match pliocy config file");
164             return true;
165         }
166         THERMAL_HILOGE(COMP_SVC, "pliocy config file config init err");
167         return false;
168     }
169 
170     if (ThermalSrvConfigParser::GetInstance().ThermalSrvConfigInit(VENDOR_THERMAL_SERVICE_CONFIG_PATH)) {
171         THERMAL_HILOGD(COMP_SVC, "thermal service config init suc:VENDOR_CONFIG");
172         return true;
173     }
174 
175     if (ThermalSrvConfigParser::GetInstance().ThermalSrvConfigInit(SYSTEM_THERMAL_SERVICE_CONFIG_PATH)) {
176         THERMAL_HILOGD(COMP_SVC, "thermal service config init suc:SYSTEM_CONFIG");
177         return true;
178     }
179 
180     return false;
181 }
182 
183 
InitConfigModule()184 bool ThermalService::InitConfigModule()
185 {
186     THERMAL_HILOGD(COMP_SVC, "InitVendor Enter");
187     if (!CreateConfigModule()) {
188         THERMAL_HILOGD(COMP_SVC, "CreateConfigModule fail");
189     }
190 
191     if (!InitConfigFile()) {
192         return false;
193     }
194 
195     return true;
196 }
197 
InitModules()198 bool ThermalService::InitModules()
199 {
200     if (!InitConfigFile()) {
201         return false;
202     }
203 
204     if (popup_ == nullptr) {
205         popup_ = std::make_shared<ActionPopup>(POPUP_ACTION_NAME);
206     }
207 
208     if (!InitThermalObserver()) {
209         THERMAL_HILOGE(COMP_SVC, "thermal observer start fail");
210         return false;
211     }
212 
213     if (!InitActionManager()) {
214         THERMAL_HILOGE(COMP_SVC, "action manager init fail");
215         return false;
216     }
217 
218     if (!InitThermalPolicy()) {
219         THERMAL_HILOGE(COMP_SVC, "thermal policy start fail");
220         return false;
221     }
222     return true;
223 }
224 
InitThermalObserver()225 bool ThermalService::InitThermalObserver()
226 {
227     if (!InitBaseInfo()) {
228         return false;
229     }
230 
231     THERMAL_HILOGD(COMP_SVC, "Enter");
232     if (observer_ == nullptr) {
233         observer_ = std::make_shared<ThermalObserver>(g_service);
234         if (!(observer_->Init())) {
235             THERMAL_HILOGE(COMP_SVC, "InitThermalObserver: thermal observer start fail");
236             return false;
237         }
238     }
239     if (info_ == nullptr) {
240         info_ = std::make_shared<ThermalSensorInfo>();
241     }
242     THERMAL_HILOGI(COMP_SVC, "InitThermalObserver: Init Success");
243     return true;
244 }
245 
InitBaseInfo()246 bool ThermalService::InitBaseInfo()
247 {
248     THERMAL_HILOGD(COMP_SVC, "Enter");
249     if (!baseInfo_->Init()) {
250         THERMAL_HILOGE(COMP_SVC, "InitBaseInfo: base info init failed");
251         return false;
252     }
253     return true;
254 }
255 
InitStateMachine()256 bool ThermalService::InitStateMachine()
257 {
258     THERMAL_HILOGD(COMP_SVC, "Enter");
259     if (!state_->Init()) {
260         THERMAL_HILOGE(COMP_SVC, "InitStateMachine: state machine init failed");
261         return false;
262     }
263     return true;
264 }
265 
InitActionManager()266 bool ThermalService::InitActionManager()
267 {
268     THERMAL_HILOGD(COMP_SVC, "Enter");
269     if (!actionMgr_->Init()) {
270         THERMAL_HILOGE(COMP_SVC, "InitActionManager: action manager init failed");
271         return false;
272     }
273     return true;
274 }
275 
InitThermalPolicy()276 bool ThermalService::InitThermalPolicy()
277 {
278     THERMAL_HILOGD(COMP_SVC, "Enter");
279     if (!policy_->Init()) {
280         THERMAL_HILOGE(COMP_SVC, "InitThermalPolicy: policy init failed");
281         return false;
282     }
283     return true;
284 }
285 
OnStop()286 void ThermalService::OnStop()
287 {
288     THERMAL_HILOGD(COMP_SVC, "Enter");
289     if (!ready_) {
290         return;
291     }
292     ready_ = false;
293     isBootCompleted_ = false;
294     RemoveSystemAbilityListener(COMMON_EVENT_SERVICE_ID);
295     if (thermalInterface_) {
296         thermalInterface_->Unregister();
297         thermalInterface_->UnregisterFanCallback();
298         thermalInterface_ = nullptr;
299     }
300     if (hdiServiceMgr_) {
301         hdiServiceMgr_->UnregisterServiceStatusListener(hdiServStatListener_);
302         hdiServiceMgr_ = nullptr;
303     }
304 }
305 
SubscribeThermalTempCallback(const std::vector<std::string> & typeList,const sptr<IThermalTempCallback> & callback)306 bool ThermalService::SubscribeThermalTempCallback(
307     const std::vector<std::string>& typeList, const sptr<IThermalTempCallback>& callback)
308 {
309     if (!Permission::IsSystem()) {
310         return false;
311     }
312     THERMAL_HILOGD(COMP_SVC, "Enter");
313     auto uid = IPCSkeleton::GetCallingUid();
314     THERMAL_HILOGI(COMP_SVC, "uid %{public}d", uid);
315     observer_->SubscribeThermalTempCallback(typeList, callback);
316     return true;
317 }
318 
UnSubscribeThermalTempCallback(const sptr<IThermalTempCallback> & callback)319 bool ThermalService::UnSubscribeThermalTempCallback(const sptr<IThermalTempCallback>& callback)
320 {
321     if (!Permission::IsSystem()) {
322         return false;
323     }
324     THERMAL_HILOGD(COMP_SVC, "Enter");
325     auto uid = IPCSkeleton::GetCallingUid();
326     THERMAL_HILOGI(COMP_SVC, "uid %{public}d", uid);
327     observer_->UnSubscribeThermalTempCallback(callback);
328     return true;
329 }
330 
GetThermalSrvSensorInfo(const SensorType & type,ThermalSrvSensorInfo & sensorInfo)331 bool ThermalService::GetThermalSrvSensorInfo(const SensorType& type, ThermalSrvSensorInfo& sensorInfo)
332 {
333     THERMAL_HILOGD(COMP_SVC, "Enter");
334     if (!(observer_->GetThermalSrvSensorInfo(type, sensorInfo))) {
335         THERMAL_HILOGI(COMP_SVC, "failed to get temp for sensor type");
336         return false;
337     }
338     return true;
339 }
340 
SubscribeThermalLevelCallback(const sptr<IThermalLevelCallback> & callback)341 bool ThermalService::SubscribeThermalLevelCallback(const sptr<IThermalLevelCallback>& callback)
342 {
343     THERMAL_HILOGD(COMP_SVC, "Enter");
344     auto uid = IPCSkeleton::GetCallingUid();
345     THERMAL_HILOGI(COMP_SVC, "uid %{public}d", uid);
346     actionMgr_->SubscribeThermalLevelCallback(callback);
347     return true;
348 }
349 
UnSubscribeThermalLevelCallback(const sptr<IThermalLevelCallback> & callback)350 bool ThermalService::UnSubscribeThermalLevelCallback(const sptr<IThermalLevelCallback>& callback)
351 {
352     THERMAL_HILOGD(COMP_SVC, "Enter");
353     auto uid = IPCSkeleton::GetCallingUid();
354     THERMAL_HILOGI(COMP_SVC, "uid %{public}d", uid);
355     actionMgr_->UnSubscribeThermalLevelCallback(callback);
356     return true;
357 }
358 
SubscribeThermalActionCallback(const std::vector<std::string> & actionList,const std::string & desc,const sptr<IThermalActionCallback> & callback)359 bool ThermalService::SubscribeThermalActionCallback(
360     const std::vector<std::string>& actionList, const std::string& desc, const sptr<IThermalActionCallback>& callback)
361 {
362     if (!Permission::IsSystem()) {
363         return false;
364     }
365     THERMAL_HILOGD(COMP_SVC, "Enter");
366     auto pid = IPCSkeleton::GetCallingPid();
367     auto uid = IPCSkeleton::GetCallingUid();
368     THERMAL_HILOGI(COMP_SVC, "pid %{public}d", pid);
369     THERMAL_HILOGI(COMP_SVC, "uid %{public}d", uid);
370     observer_->SubscribeThermalActionCallback(actionList, desc, callback);
371     return true;
372 }
373 
UnSubscribeThermalActionCallback(const sptr<IThermalActionCallback> & callback)374 bool ThermalService::UnSubscribeThermalActionCallback(const sptr<IThermalActionCallback>& callback)
375 {
376     if (!Permission::IsSystem()) {
377         return false;
378     }
379     THERMAL_HILOGD(COMP_SVC, "Enter");
380     auto pid = IPCSkeleton::GetCallingPid();
381     auto uid = IPCSkeleton::GetCallingUid();
382     THERMAL_HILOGI(COMP_SVC, "pid %{public}d", pid);
383     THERMAL_HILOGI(COMP_SVC, "uid %{public}d", uid);
384     observer_->UnSubscribeThermalActionCallback(callback);
385     return true;
386 }
387 
GetThermalLevel(ThermalLevel & level)388 bool ThermalService::GetThermalLevel(ThermalLevel& level)
389 {
390     uint32_t levelValue = actionMgr_->GetThermalLevel();
391     level = static_cast<ThermalLevel>(levelValue);
392     return true;
393 }
394 
GetThermalInfo()395 bool ThermalService::GetThermalInfo()
396 {
397     THERMAL_HILOGD(COMP_SVC, "Enter");
398     HdfThermalCallbackInfo thermalInfo;
399     bool ret = false;
400     if (thermalInterface_ == nullptr) {
401         thermalInterface_ = IThermalInterface::Get();
402         if (thermalInterface_ == nullptr) {
403             THERMAL_HILOGD(COMP_SVC, "thermalInterface_ is nullptr");
404             return ret;
405         }
406     }
407 
408     if (thermalInterface_ != nullptr) {
409         int32_t res = thermalInterface_->GetThermalZoneInfo(thermalInfo);
410         HandleThermalCallbackEvent(thermalInfo);
411         if (!res) {
412             ret = true;
413         }
414     }
415     return ret;
416 }
417 
SetScene(const std::string & scene)418 bool ThermalService::SetScene(const std::string& scene)
419 {
420     if (!Permission::IsSystem()) {
421         return false;
422     }
423     scene_ = scene;
424     return true;
425 }
426 
RegisterHdiStatusListener()427 void ThermalService::RegisterHdiStatusListener()
428 {
429     THERMAL_HILOGD(COMP_SVC, "Enter");
430     hdiServiceMgr_ = IServiceManager::Get();
431     if (hdiServiceMgr_ == nullptr) {
432         FFRTTask retryTask = [this] {
433             return RegisterHdiStatusListener();
434         };
435         FFRTUtils::SubmitDelayTask(retryTask, RETRY_TIME, g_queue);
436         THERMAL_HILOGW(COMP_SVC, "hdi service manager is nullptr, try again after %{public}u ms", RETRY_TIME);
437         return;
438     }
439 
440     hdiServStatListener_ = new HdiServiceStatusListener(
441         HdiServiceStatusListener::StatusCallback([&](const OHOS::HDI::ServiceManager::V1_0::ServiceStatus& status) {
442             THERMAL_RETURN_IF(status.serviceName != HDI_SERVICE_NAME || status.deviceClass != DEVICE_CLASS_DEFAULT)
443 
444             if (status.status == SERVIE_STATUS_START) {
445                 FFRTTask task = [this] {
446                     RegisterThermalHdiCallback();
447                     RegisterFanHdiCallback();
448                 };
449                 FFRTUtils::SubmitTask(task);
450                 THERMAL_HILOGD(COMP_SVC, "thermal interface service start");
451             } else if (status.status == SERVIE_STATUS_STOP && thermalInterface_) {
452                 thermalInterface_->Unregister();
453                 thermalInterface_->UnregisterFanCallback();
454                 thermalInterface_ = nullptr;
455                 THERMAL_HILOGW(COMP_SVC, "thermal interface service, unregister interface");
456             }
457         }));
458 
459     int32_t status = hdiServiceMgr_->RegisterServiceStatusListener(hdiServStatListener_, DEVICE_CLASS_DEFAULT);
460     if (status != ERR_OK) {
461         THERMAL_HILOGW(COMP_SVC, "Register hdi failed, try again after %{public}u ms", RETRY_TIME);
462         FFRTTask retryTask = [this] {
463             return RegisterHdiStatusListener();
464         };
465         FFRTUtils::SubmitDelayTask(retryTask, RETRY_TIME, g_queue);
466     }
467 }
468 
RegisterThermalHdiCallback()469 void ThermalService::RegisterThermalHdiCallback()
470 {
471     THERMAL_HILOGD(COMP_SVC, "Enter");
472     if (serviceSubscriber_ == nullptr) {
473         serviceSubscriber_ = std::make_shared<ThermalServiceSubscriber>();
474         THERMAL_RETURN_IF_WITH_LOG(!(serviceSubscriber_->Init()), "thermal service suvscriber start fail");
475     }
476 
477     THERMAL_HILOGD(COMP_SVC, "register thermal hdi callback");
478     if (thermalInterface_ == nullptr) {
479         thermalInterface_ = IThermalInterface::Get();
480         THERMAL_RETURN_IF_WITH_LOG(thermalInterface_ == nullptr, "failed to get thermal hdi interface");
481     }
482 
483     sptr<IThermalCallback> callback = new ThermalCallback();
484     ThermalCallback::ThermalEventCallback eventCb =
485         std::bind(&ThermalService::HandleThermalCallbackEvent, this, std::placeholders::_1);
486     ThermalCallback::RegisterThermalEvent(eventCb);
487     int32_t ret = thermalInterface_->Register(callback);
488     THERMAL_HILOGI(COMP_SVC, "register thermal hdi callback end, ret: %{public}d", ret);
489 }
490 
HandleThermalCallbackEvent(const HdfThermalCallbackInfo & event)491 int32_t ThermalService::HandleThermalCallbackEvent(const HdfThermalCallbackInfo& event)
492 {
493     TypeTempMap typeTempMap;
494     if (!event.info.empty()) {
495         for (auto iter = event.info.begin(); iter != event.info.end(); iter++) {
496             typeTempMap.insert(std::make_pair(iter->type, iter->temp));
497         }
498     }
499     serviceSubscriber_->OnTemperatureChanged(typeTempMap);
500     return ERR_OK;
501 }
502 
RegisterFanHdiCallback()503 void ThermalService::RegisterFanHdiCallback()
504 {
505     if (!fanFaultDetect_->HasFanConfig()) {
506         return;
507     }
508 
509     if (thermalInterface_ == nullptr) {
510         thermalInterface_ = IThermalInterface::Get();
511         THERMAL_RETURN_IF_WITH_LOG(thermalInterface_ == nullptr, "failed to get thermal hdi interface");
512     }
513 
514     sptr<IFanCallback> callback = new FanCallback();
515     FanCallback::FanEventCallback eventCb =
516         std::bind(&ThermalService::HandleFanCallbackEvent, this, std::placeholders::_1);
517     FanCallback::RegisterFanEvent(eventCb);
518     int32_t ret = thermalInterface_->RegisterFanCallback(callback);
519     THERMAL_HILOGI(COMP_SVC, "register fan hdi callback end, ret: %{public}d", ret);
520 
521     return;
522 }
523 
HandleFanCallbackEvent(const HdfThermalCallbackInfo & event)524 int32_t ThermalService::HandleFanCallbackEvent(const HdfThermalCallbackInfo& event)
525 {
526     FanSensorInfo report;
527     if (!event.info.empty()) {
528         for (auto iter = event.info.begin(); iter != event.info.end(); iter++) {
529             report.insert(std::make_pair(iter->type, iter->temp));
530         }
531     }
532 
533     fanFaultDetect_->OnFanSensorInfoChanged(report);
534     return ERR_OK;
535 }
536 
ShellDump(const std::vector<std::string> & args,uint32_t argc)537 std::string ThermalService::ShellDump(const std::vector<std::string>& args, uint32_t argc)
538 {
539     if (!Permission::IsSystem() || !isBootCompleted_) {
540         return "";
541     }
542     std::lock_guard<std::mutex> lock(mutex_);
543     pid_t pid = IPCSkeleton::GetCallingPid();
544     THERMAL_HILOGI(COMP_SVC, "PID: %{public}d", pid);
545     std::string result;
546     bool ret = ThermalMgrDumper::Dump(args, result);
547     THERMAL_HILOGI(COMP_SVC, "ThermalMgrDumper :%{public}d", ret);
548     return result;
549 }
550 
Dump(int fd,const std::vector<std::u16string> & args)551 int32_t ThermalService::Dump(int fd, const std::vector<std::u16string>& args)
552 {
553     if (!isBootCompleted_) {
554         return ERR_NO_INIT;
555     }
556     if (!Permission::IsSystem()) {
557         return ERR_PERMISSION_DENIED;
558     }
559     std::vector<std::string> argsInStr;
560     std::transform(args.begin(), args.end(), std::back_inserter(argsInStr), [](const std::u16string& arg) {
561         std::string ret = Str16ToStr8(arg);
562         THERMAL_HILOGI(COMP_SVC, "arg: %{public}s", ret.c_str());
563         return ret;
564     });
565     std::string result;
566     ThermalMgrDumper::Dump(argsInStr, result);
567     if (!SaveStringToFd(fd, result)) {
568         THERMAL_HILOGE(COMP_SVC, "ThermalService::Dump failed, save to fd failed.");
569         THERMAL_HILOGE(COMP_SVC, "Dump Info:\n");
570         THERMAL_HILOGE(COMP_SVC, "%{public}s", result.c_str());
571         return ERR_OK;
572     }
573     return ERR_OK;
574 }
575 } // namespace PowerMgr
576 } // namespace OHOS
577