1 /*
2 * Copyright (c) 2021 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 <fcntl.h>
19 #include <ipc_skeleton.h>
20 #include <unistd.h>
21 #include "file_ex.h"
22 #include "if_system_ability_manager.h"
23 #include "iservice_registry.h"
24 #include "securec.h"
25 #include "system_ability_definition.h"
26
27 #include "constants.h"
28 #include "thermal_mgr_dumper.h"
29 #include "thermal_srv_config_parser.h"
30 #include "thermal_common.h"
31
32 namespace OHOS {
33 namespace PowerMgr {
34 namespace {
35 std::string path = "/system/etc/thermal_config/thermal_service_config.xml";
36 constexpr const char *HDF_SERVICE_NAME = "thermal_interface_service";
37 const std::string THMERMAL_SERVICE_NAME = "ThermalService";
38 auto g_service = DelayedSpSingleton<ThermalService>::GetInstance();
39 constexpr int32_t STATUS_OK = 0;
40 const bool G_REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(g_service.GetRefPtr());
41 }
ThermalService()42 ThermalService::ThermalService() : SystemAbility(POWER_MANAGER_THERMAL_SERVICE_ID, true) {}
43
~ThermalService()44 ThermalService::~ThermalService() {}
45
OnStart()46 void ThermalService::OnStart()
47 {
48 int time = 100;
49 THERMAL_HILOGD(COMP_SVC, "Enter");
50 if (ready_) {
51 THERMAL_HILOGE(COMP_SVC, "OnStart is ready, nothing to do");
52 return;
53 }
54
55 std::this_thread::sleep_for(std::chrono::milliseconds(time));
56
57 if (!(Init())) {
58 THERMAL_HILOGE(COMP_SVC, "OnStart call init fail");
59 return;
60 }
61
62 if (!Publish(DelayedSpSingleton<ThermalService>::GetInstance())) {
63 THERMAL_HILOGE(COMP_SVC, "OnStart register to system ability manager failed.");
64 return;
65 }
66 ready_ = true;
67 THERMAL_HILOGD(COMP_SVC, "OnStart and add system ability success");
68 }
69
Init()70 bool ThermalService::Init()
71 {
72 THERMAL_HILOGD(COMP_SVC, "Enter");
73 std::this_thread::sleep_for(std::chrono::milliseconds(TIME_TO_SLEEP));
74
75 if (!eventRunner_) {
76 eventRunner_ = AppExecFwk::EventRunner::Create(THMERMAL_SERVICE_NAME);
77 if (eventRunner_ == nullptr) {
78 THERMAL_HILOGE(COMP_SVC, "Init failed due to create EventRunner");
79 return false;
80 }
81 }
82
83 if (!handler_) {
84 handler_ = std::make_shared<ThermalsrvEventHandler>(eventRunner_, g_service);
85 if (handler_ == nullptr) {
86 THERMAL_HILOGE(COMP_SVC, "Init failed due to create handler error");
87 return false;
88 }
89 }
90
91 if (!CreateConfigModule()) {
92 return false;
93 }
94
95 if (thermalInterface_ == nullptr) {
96 thermalInterface_ = IThermalInterface::Get();
97 if (thermalInterface_ == nullptr) {
98 THERMAL_HILOGE(COMP_SVC, "failed to get thermal hdf interface");
99 return false;
100 }
101 }
102
103 if (!RigisterHdfStatusListener()) {
104 THERMAL_HILOGE(COMP_SVC, "hdf status register fail");
105 return false;
106 }
107
108 if (!InitModules()) {
109 return false;
110 }
111 THERMAL_HILOGD(COMP_SVC, "Init success");
112 return true;
113 }
114
CreateConfigModule()115 bool ThermalService::CreateConfigModule()
116 {
117 if (!baseInfo_) {
118 baseInfo_ = std::make_shared<ThermalConfigBaseInfo>();
119 if (baseInfo_ == nullptr) {
120 THERMAL_HILOGE(COMP_SVC, "failed to create base info");
121 return false;
122 }
123 }
124
125 if (!state_) {
126 state_ = std::make_shared<StateMachine>();
127 if (state_ == nullptr) {
128 THERMAL_HILOGE(COMP_SVC, "failed to create state machine");
129 return false;
130 }
131 }
132
133 if (!actionMgr_) {
134 actionMgr_ = std::make_shared<ThermalActionManager>();
135 if (actionMgr_ == nullptr) {
136 THERMAL_HILOGE(COMP_SVC, "failed to create action manager");
137 return false;
138 }
139 }
140
141 if (cluster_ == nullptr) {
142 cluster_ = std::make_shared<ThermalConfigSensorCluster>();
143 if (cluster_ == nullptr) {
144 THERMAL_HILOGE(COMP_SVC, "failed to create cluster");
145 return false;
146 }
147 }
148
149 if (!policy_) {
150 policy_ = std::make_shared<ThermalPolicy>();
151 if (policy_ == nullptr) {
152 THERMAL_HILOGE(COMP_SVC, "failed to create thermal policy");
153 return false;
154 }
155 }
156 return true;
157 }
158
InitModules()159 bool ThermalService::InitModules()
160 {
161 if (!ThermalSrvConfigParser::GetInstance().ThermalSrvConfigInit(path)) {
162 THERMAL_HILOGE(COMP_SVC, "thermal service config init fail");
163 return false;
164 }
165
166 if (popup_ == nullptr) {
167 popup_ = std::make_shared<ActionPopup>();
168 }
169
170 if (!InitThermalObserver()) {
171 THERMAL_HILOGE(COMP_SVC, "thermal observer start fail");
172 return false;
173 }
174
175 if (!InitStateMachine()) {
176 THERMAL_HILOGE(COMP_SVC, "state machine init fail");
177 return false;
178 }
179
180 if (!InitActionManager()) {
181 THERMAL_HILOGE(COMP_SVC, "actiom 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_HILOGD(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 thermalInterface_->Unregister();
263 servmgr_->UnregisterServiceStatusListener(hdfListener_);
264 }
265
SubscribeThermalTempCallback(const std::vector<std::string> & typeList,const sptr<IThermalTempCallback> & callback)266 void ThermalService::SubscribeThermalTempCallback(const std::vector<std::string> &typeList,
267 const sptr<IThermalTempCallback> &callback)
268 {
269 THERMAL_HILOGD(COMP_SVC, "Enter");
270 auto uid = IPCSkeleton::GetCallingUid();
271 THERMAL_HILOGD(COMP_SVC, "uid %{public}d", uid);
272 observer_->SubscribeThermalTempCallback(typeList, callback);
273 }
274
UnSubscribeThermalTempCallback(const sptr<IThermalTempCallback> & callback)275 void ThermalService::UnSubscribeThermalTempCallback(const sptr<IThermalTempCallback> &callback)
276 {
277 THERMAL_HILOGD(COMP_SVC, "Enter");
278 auto uid = IPCSkeleton::GetCallingUid();
279 THERMAL_HILOGD(COMP_SVC, "uid %{public}d", uid);
280 observer_->UnSubscribeThermalTempCallback(callback);
281 }
282
GetThermalSrvSensorInfo(const SensorType & type,ThermalSrvSensorInfo & sensorInfo)283 bool ThermalService::GetThermalSrvSensorInfo(const SensorType &type, ThermalSrvSensorInfo& sensorInfo)
284 {
285 THERMAL_HILOGD(COMP_SVC, "Enter");
286 if (!(observer_->GetThermalSrvSensorInfo(type, sensorInfo))) {
287 THERMAL_HILOGD(COMP_SVC, "failed to get temp for sensor type");
288 return false;
289 }
290 return true;
291 }
292
SubscribeThermalLevelCallback(const sptr<IThermalLevelCallback> & callback)293 void ThermalService::SubscribeThermalLevelCallback(const sptr<IThermalLevelCallback> &callback)
294 {
295 THERMAL_HILOGD(COMP_SVC, "Enter");
296 auto uid = IPCSkeleton::GetCallingUid();
297 THERMAL_HILOGD(COMP_SVC, "uid %{public}d", uid);
298 actionMgr_->SubscribeThermalLevelCallback(callback);
299 }
300
UnSubscribeThermalLevelCallback(const sptr<IThermalLevelCallback> & callback)301 void ThermalService::UnSubscribeThermalLevelCallback(const sptr<IThermalLevelCallback> &callback)
302 {
303 THERMAL_HILOGD(COMP_SVC, "Enter");
304 auto uid = IPCSkeleton::GetCallingUid();
305 THERMAL_HILOGD(COMP_SVC, "uid %{public}d", uid);
306 actionMgr_->UnSubscribeThermalLevelCallback(callback);
307 }
308
GetThermalLevel(ThermalLevel & level)309 void ThermalService::GetThermalLevel(ThermalLevel& level)
310 {
311 uint32_t levelValue = actionMgr_->GetThermalLevel();
312 level = static_cast<ThermalLevel>(levelValue);
313 }
314
SendEvent(int32_t event,int64_t param,int64_t delayTime)315 void ThermalService::SendEvent(int32_t event, int64_t param, int64_t delayTime)
316 {
317 handler_->SendEvent(event, param, delayTime);
318 }
319
RemoveEvent(int32_t event)320 void ThermalService::RemoveEvent(int32_t event)
321 {
322 handler_->RemoveEvent(event);
323 }
324
HandleEvent(int event)325 void ThermalService::HandleEvent(int event)
326 {
327 THERMAL_HILOGD(COMP_SVC, "Enter");
328 switch (event) {
329 case ThermalsrvEventHandler::SEND_GET_THERMAL_HDF_SERVICE_MSG: {
330 int32_t ret = -1;
331 if (serviceSubscriber_ == nullptr) {
332 serviceSubscriber_ = std::make_shared<ThermalServiceSubscriber>();
333 if (!(serviceSubscriber_->Init())) {
334 THERMAL_HILOGE(COMP_SVC, "thermal service suvscriber start fail");
335 return;
336 }
337 }
338 sptr<IThermalCallback> g_callback = new ThermalCallbackImpl();
339 ThermalCallbackImpl::ThermalEventCallback eventCb =
340 std::bind(&ThermalService::HandleThermalCallbackEvent, this, std::placeholders::_1);
341 ThermalCallbackImpl::RegisterThermalEvent(eventCb);
342 ret = thermalInterface_->Register(g_callback);
343 if (ret != ERR_OK) {
344 THERMAL_HILOGE(COMP_SVC, "set hdf callback failed");
345 return;
346 }
347 break;
348 }
349 default:
350 break;
351 }
352 }
353
RigisterHdfStatusListener()354 bool ThermalService::RigisterHdfStatusListener()
355 {
356 THERMAL_HILOGD(COMP_SVC, "Enter");
357 servmgr_ = IServiceManager::Get();
358 if (servmgr_ == nullptr) {
359 THERMAL_HILOGE(COMP_SVC, "hdf service manager is nullptr");
360 return false;
361 }
362
363 hdfListener_ = new HdfServiceStatusListener(HdfServiceStatusListener::StatusCallback(
364 [&](const OHOS::HDI::ServiceManager::V1_0::ServiceStatus &status) {
365 if (status.serviceName != std::string(HDF_SERVICE_NAME)) {
366 THERMAL_HILOGE(COMP_SVC, "service name mismatch");
367 return;
368 }
369
370 if (status.deviceClass != DEVICE_CLASS_DEFAULT) {
371 THERMAL_HILOGE(COMP_SVC, "deviceClass mismatch");
372 return;
373 }
374
375 if (status.status == SERVIE_STATUS_START) {
376 thermalInterface_ = IThermalInterface::Get();
377 if (thermalInterface_ == nullptr) {
378 THERMAL_HILOGE(COMP_SVC, "failed to get thermal hdf interface");
379 return;
380 }
381 RemoveEvent(ThermalsrvEventHandler::SEND_GET_THERMAL_HDF_SERVICE_MSG);
382 SendEvent(ThermalsrvEventHandler::SEND_GET_THERMAL_HDF_SERVICE_MSG, 0, 0);
383 } else if (status.status == SERVIE_STATUS_STOP) {
384 thermalInterface_->Unregister();
385 return;
386 }
387 }));
388
389 int status = servmgr_->RegisterServiceStatusListener(hdfListener_, DEVICE_CLASS_DEFAULT);
390 if (status != STATUS_OK) {
391 THERMAL_HILOGE(COMP_SVC, "register failed");
392 return false;
393 }
394 return true;
395 }
396
HandleThermalCallbackEvent(const HdfThermalCallbackInfo & event)397 int32_t ThermalService::HandleThermalCallbackEvent(const HdfThermalCallbackInfo& event)
398 {
399 TypeTempMap typeTempMap;
400 if (!event.info.empty()) {
401 for (auto iter = event.info.begin(); iter != event.info.end(); iter++) {
402 typeTempMap.insert(std::make_pair(iter->type, iter->temp));
403 }
404 }
405 serviceSubscriber_->OnTemperatureChanged(typeTempMap);
406 return ERR_OK;
407 }
408
ShellDump(const std::vector<std::string> & args,uint32_t argc)409 std::string ThermalService::ShellDump(const std::vector<std::string>& args, uint32_t argc)
410 {
411 auto uid = IPCSkeleton::GetCallingUid();
412 if (uid >= APP_FIRST_UID) {
413 THERMAL_HILOGE(COMP_SVC, "Request failed, %{public}d permission check failed", uid);
414 return nullptr;
415 }
416 std::lock_guard<std::mutex> lock(mutex_);
417 pid_t pid = IPCSkeleton::GetCallingPid();
418 THERMAL_HILOGD(COMP_SVC, "PID: %{public}d!", pid);
419 std::string result;
420 bool ret = ThermalMgrDumper::Dump(args, result);
421 THERMAL_HILOGD(COMP_SVC, "ThermalMgrDumper :%{public}d", ret);
422 return result;
423 }
424 } // namespace PowerMgr
425 } // namespace OHOS
426
427