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 "system_suspend_controller.h"
17 #ifdef HAS_HIVIEWDFX_HISYSEVENT_PART
18 #include "hisysevent.h"
19 #endif
20 #include "power_common.h"
21 #include "power_log.h"
22 #include "suspend/running_lock_hub.h"
23
24 namespace OHOS {
25 namespace PowerMgr {
26 namespace {
27 const std::string HDI_SERVICE_NAME = "power_interface_service";
28 constexpr uint32_t RETRY_TIME = 1000;
29 } // namespace
30 using namespace OHOS::HDI::Power::V1_2;
31
SystemSuspendController()32 SystemSuspendController::SystemSuspendController() {}
33
34 SystemSuspendController::~SystemSuspendController() = default;
35
RegisterHdiStatusListener()36 void SystemSuspendController::RegisterHdiStatusListener()
37 {
38 POWER_HILOGD(COMP_SVC, "power rigister Hdi status listener");
39 hdiServiceMgr_ = OHOS::HDI::ServiceManager::V1_0::IServiceManager::Get();
40 if (hdiServiceMgr_ == nullptr) {
41 FFRTTask retryTask = [this] {
42 RegisterHdiStatusListener();
43 };
44 POWER_HILOGW(COMP_SVC, "hdi service manager is nullptr");
45 FFRTUtils::SubmitDelayTask(retryTask, RETRY_TIME, queue_);
46 return;
47 }
48
49 hdiServStatListener_ = new HdiServiceStatusListener(
50 HdiServiceStatusListener::StatusCallback([&](const OHOS::HDI::ServiceManager::V1_0::ServiceStatus& status) {
51 RETURN_IF(status.serviceName != HDI_SERVICE_NAME || status.deviceClass != DEVICE_CLASS_DEFAULT);
52
53 if (status.status == SERVIE_STATUS_START) {
54 FFRTTask task = [this] {
55 RegisterPowerHdiCallback();
56 };
57 FFRTUtils::SubmitTask(task);
58 POWER_HILOGI(COMP_SVC, "power interface service start");
59 } else if (status.status == SERVIE_STATUS_STOP && powerInterface_) {
60 powerInterface_ = nullptr;
61 POWER_HILOGW(COMP_SVC, "power interface service stop, unregister interface");
62 }
63 }));
64
65 int32_t status = hdiServiceMgr_->RegisterServiceStatusListener(hdiServStatListener_, DEVICE_CLASS_DEFAULT);
66 if (status != ERR_OK) {
67 FFRTTask retryTask = [this] {
68 RegisterHdiStatusListener();
69 };
70 POWER_HILOGW(COMP_SVC, "Register hdi failed");
71 FFRTUtils::SubmitDelayTask(retryTask, RETRY_TIME, queue_);
72 }
73 }
74
RegisterPowerHdiCallback()75 void SystemSuspendController::RegisterPowerHdiCallback()
76 {
77 POWER_HILOGD(COMP_SVC, "register power hdi callback");
78 if (powerInterface_ == nullptr) {
79 powerInterface_ = IPowerInterface::Get();
80 RETURN_IF_WITH_LOG(powerInterface_ == nullptr, "failed to get power hdi interface");
81 }
82 sptr<IPowerHdiCallback> callback = new PowerHdiCallback();
83 powerInterface_->RegisterCallback(callback);
84 POWER_HILOGD(COMP_SVC, "register power hdi callback end");
85 }
86
UnRegisterPowerHdiCallback()87 void SystemSuspendController::UnRegisterPowerHdiCallback()
88 {
89 POWER_HILOGD(COMP_SVC, "unregister power hdi callback");
90 if (powerInterface_ == nullptr) {
91 powerInterface_ = IPowerInterface::Get();
92 RETURN_IF_WITH_LOG(powerInterface_ == nullptr, "failed to get power hdi interface");
93 }
94 sptr<IPowerHdiCallback> callback = nullptr;
95 powerInterface_->RegisterCallback(callback);
96 POWER_HILOGD(COMP_SVC, "unregister power hdi callback end");
97 }
98
SetSuspendTag(const std::string& tag)99 void SystemSuspendController::SetSuspendTag(const std::string& tag)
100 {
101 if (powerInterface_ == nullptr) {
102 POWER_HILOGE(COMP_SVC, "The hdf interface is null");
103 return;
104 }
105 #ifdef HAS_HIVIEWDFX_HISYSEVENT_PART
106 HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::POWER, "SET_SUSPEND_TAG", HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
107 "TAG", tag);
108 #endif
109 powerInterface_->SetSuspendTag(tag);
110 }
111
AllowAutoSleep()112 void SystemSuspendController::AllowAutoSleep()
113 {
114 allowSleepTask_ = true;
115 }
116
DisallowAutoSleep()117 void SystemSuspendController::DisallowAutoSleep()
118 {
119 allowSleepTask_ = false;
120 }
121
Suspend( const std::function<void()>& onSuspend, const std::function<void()>& onWakeup, bool force)122 void SystemSuspendController::Suspend(
123 const std::function<void()>& onSuspend, const std::function<void()>& onWakeup, bool force)
124 {
125 POWER_HILOGI(COMP_SVC, "The hdf interface, force=%{public}u", static_cast<uint32_t>(force));
126 if (powerInterface_ == nullptr) {
127 POWER_HILOGE(COMP_SVC, "The hdf interface is null");
128 return;
129 }
130 #ifdef HAS_HIVIEWDFX_HISYSEVENT_PART
131 HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::POWER, "DO_SUSPEND", HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
132 "TYPE", static_cast<int32_t>(1));
133 #endif
134 if (force) {
135 powerInterface_->ForceSuspend();
136 } else if (allowSleepTask_.load()) {
137 powerInterface_->StartSuspend();
138 }
139 }
140
Wakeup()141 void SystemSuspendController::Wakeup()
142 {
143 if (powerInterface_ == nullptr) {
144 POWER_HILOGE(COMP_SVC, "The hdf interface is null");
145 return;
146 }
147 #ifdef HAS_HIVIEWDFX_HISYSEVENT_PART
148 HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::POWER, "DO_SUSPEND", HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
149 "TYPE", static_cast<int32_t>(0));
150 #endif
151 powerInterface_->StopSuspend();
152 }
153
Hibernate()154 bool SystemSuspendController::Hibernate()
155 {
156 POWER_HILOGI(COMP_SVC, "SystemSuspendController hibernate begin.");
157 if (powerInterface_ == nullptr) {
158 POWER_HILOGE(COMP_SVC, "The hdf interface is null");
159 return false;
160 }
161 #ifdef HAS_HIVIEWDFX_HISYSEVENT_PART
162 HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::POWER, "DO_HIBERNATE",
163 HiviewDFX::HiSysEvent::EventType::BEHAVIOR);
164 #endif
165 int32_t ret = powerInterface_->Hibernate();
166 if (ret != HDF_SUCCESS) {
167 POWER_HILOGE(COMP_SVC, "SystemSuspendController hibernate failed.");
168 return false;
169 }
170 POWER_HILOGI(COMP_SVC, "SystemSuspendController hibernate end.");
171 return true;
172 }
173
FillRunningLockInfo(const RunningLockParam& param)174 OHOS::HDI::Power::V1_2::RunningLockInfo SystemSuspendController::FillRunningLockInfo(const RunningLockParam& param)
175 {
176 OHOS::HDI::Power::V1_2::RunningLockInfo filledInfo {};
177 filledInfo.name = param.name;
178 filledInfo.type = static_cast<OHOS::HDI::Power::V1_2::RunningLockType>(param.type);
179 filledInfo.timeoutMs = param.timeoutMs;
180 filledInfo.uid = param.uid;
181 filledInfo.pid = param.pid;
182 return filledInfo;
183 }
184
AcquireRunningLock(const RunningLockParam& param)185 int32_t SystemSuspendController::AcquireRunningLock(const RunningLockParam& param)
186 {
187 int32_t status = RUNNINGLOCK_FAILURE;
188 if (powerInterface_ == nullptr) {
189 POWER_HILOGE(COMP_SVC, "The hdf interface is null");
190 return status;
191 }
192 OHOS::HDI::Power::V1_2::RunningLockInfo filledInfo = FillRunningLockInfo(param);
193 status = powerInterface_->HoldRunningLockExt(filledInfo,
194 param.lockid, param.bundleName);
195 return status;
196 }
197
ReleaseRunningLock(const RunningLockParam& param)198 int32_t SystemSuspendController::ReleaseRunningLock(const RunningLockParam& param)
199 {
200 int32_t status = RUNNINGLOCK_FAILURE;
201 if (powerInterface_ == nullptr) {
202 POWER_HILOGE(COMP_SVC, "The hdf interface is null");
203 return status;
204 }
205 OHOS::HDI::Power::V1_2::RunningLockInfo filledInfo = FillRunningLockInfo(param);
206 status = powerInterface_->UnholdRunningLockExt(filledInfo,
207 param.lockid, param.bundleName);
208 return status;
209 }
210
Dump(std::string& info)211 void SystemSuspendController::Dump(std::string& info)
212 {
213 if (powerInterface_ == nullptr) {
214 POWER_HILOGE(COMP_SVC, "The hdf interface is null");
215 return;
216 }
217 powerInterface_->PowerDump(info);
218 }
219
GetWakeupReason(std::string& reason)220 void SystemSuspendController::GetWakeupReason(std::string& reason)
221 {
222 if (powerInterface_ == nullptr) {
223 POWER_HILOGE(COMP_SVC, "The hdf interface is null");
224 return;
225 }
226 powerInterface_->GetWakeupReason(reason);
227 }
228
OnSuspend()229 int32_t SystemSuspendController::PowerHdfCallback::OnSuspend()
230 {
231 if (onSuspend_ != nullptr) {
232 onSuspend_();
233 }
234 return 0;
235 }
236
OnWakeup()237 int32_t SystemSuspendController::PowerHdfCallback::OnWakeup()
238 {
239 if (onWakeup_ != nullptr) {
240 onWakeup_();
241 }
242 return 0;
243 }
244
SetListener( std::function<void()>& suspend, std::function<void()>& wakeup)245 void SystemSuspendController::PowerHdfCallback::SetListener(
246 std::function<void()>& suspend, std::function<void()>& wakeup)
247 {
248 onSuspend_ = suspend;
249 onWakeup_ = wakeup;
250 }
251 } // namespace PowerMgr
252 } // namespace OHOS
253