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