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