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