• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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