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 std::lock_guard lock(mutex_);
112 allowSleepTask_ = true;
113 }
114
DisallowAutoSleep()115 void SystemSuspendController::DisallowAutoSleep()
116 {
117 std::lock_guard lock(mutex_);
118 allowSleepTask_ = false;
119 }
120
Suspend(const std::function<void ()> & onSuspend,const std::function<void ()> & onWakeup,bool force)121 void SystemSuspendController::Suspend(
122 const std::function<void()>& onSuspend, const std::function<void()>& onWakeup, bool force)
123 {
124 std::lock_guard lock(mutex_);
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 HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::POWER, "DO_SUSPEND", HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
131 "TYPE", static_cast<int32_t>(1));
132 if (force) {
133 powerInterface_->ForceSuspend();
134 } else if (allowSleepTask_.load()) {
135 powerInterface_->StartSuspend();
136 }
137 }
138
Wakeup()139 void SystemSuspendController::Wakeup()
140 {
141 std::lock_guard lock(mutex_);
142 if (powerInterface_ == nullptr) {
143 POWER_HILOGE(COMP_SVC, "The hdf interface is null");
144 return;
145 }
146 HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::POWER, "DO_SUSPEND", HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
147 "TYPE", static_cast<int32_t>(0));
148 powerInterface_->StopSuspend();
149 }
150
Hibernate()151 bool SystemSuspendController::Hibernate()
152 {
153 POWER_HILOGI(COMP_SVC, "SystemSuspendController hibernate begin.");
154 if (powerInterface_ == nullptr) {
155 POWER_HILOGE(COMP_SVC, "The hdf interface is null");
156 return false;
157 }
158 int32_t ret = powerInterface_->Hibernate();
159 if (ret != HDF_SUCCESS) {
160 POWER_HILOGE(COMP_SVC, "SystemSuspendController hibernate failed.");
161 return false;
162 }
163 POWER_HILOGI(COMP_SVC, "SystemSuspendController hibernate end.");
164 return true;
165 }
166
FillRunningLockInfo(const RunningLockParam & param)167 OHOS::HDI::Power::V1_2::RunningLockInfo SystemSuspendController::FillRunningLockInfo(const RunningLockParam& param)
168 {
169 OHOS::HDI::Power::V1_2::RunningLockInfo filledInfo {};
170 filledInfo.name = param.name;
171 filledInfo.type = static_cast<OHOS::HDI::Power::V1_2::RunningLockType>(param.type);
172 filledInfo.timeoutMs = param.timeoutMs;
173 filledInfo.uid = param.uid;
174 filledInfo.pid = param.pid;
175 return filledInfo;
176 }
177
AcquireRunningLock(const RunningLockParam & param)178 int32_t SystemSuspendController::AcquireRunningLock(const RunningLockParam& param)
179 {
180 int32_t status = RUNNINGLOCK_FAILURE;
181 if (powerInterface_ == nullptr) {
182 POWER_HILOGE(COMP_SVC, "The hdf interface is null");
183 return status;
184 }
185 OHOS::HDI::Power::V1_2::RunningLockInfo filledInfo = FillRunningLockInfo(param);
186 status = powerInterface_->HoldRunningLockExt(filledInfo,
187 param.lockid, param.bundleName);
188 return status;
189 }
190
ReleaseRunningLock(const RunningLockParam & param)191 int32_t SystemSuspendController::ReleaseRunningLock(const RunningLockParam& param)
192 {
193 int32_t status = RUNNINGLOCK_FAILURE;
194 if (powerInterface_ == nullptr) {
195 POWER_HILOGE(COMP_SVC, "The hdf interface is null");
196 return status;
197 }
198 OHOS::HDI::Power::V1_2::RunningLockInfo filledInfo = FillRunningLockInfo(param);
199 status = powerInterface_->UnholdRunningLockExt(filledInfo,
200 param.lockid, param.bundleName);
201 return status;
202 }
203
Dump(std::string & info)204 void SystemSuspendController::Dump(std::string& info)
205 {
206 if (powerInterface_ == nullptr) {
207 POWER_HILOGE(COMP_SVC, "The hdf interface is null");
208 return;
209 }
210 powerInterface_->PowerDump(info);
211 }
212
GetWakeupReason(std::string & reason)213 void SystemSuspendController::GetWakeupReason(std::string& reason)
214 {
215 if (powerInterface_ == nullptr) {
216 POWER_HILOGE(COMP_SVC, "The hdf interface is null");
217 return;
218 }
219 powerInterface_->GetWakeupReason(reason);
220 }
221
OnSuspend()222 int32_t SystemSuspendController::PowerHdfCallback::OnSuspend()
223 {
224 if (onSuspend_ != nullptr) {
225 onSuspend_();
226 }
227 return 0;
228 }
229
OnWakeup()230 int32_t SystemSuspendController::PowerHdfCallback::OnWakeup()
231 {
232 if (onWakeup_ != nullptr) {
233 onWakeup_();
234 }
235 return 0;
236 }
237
SetListener(std::function<void ()> & suspend,std::function<void ()> & wakeup)238 void SystemSuspendController::PowerHdfCallback::SetListener(
239 std::function<void()>& suspend, std::function<void()>& wakeup)
240 {
241 onSuspend_ = suspend;
242 onWakeup_ = wakeup;
243 }
244 } // namespace PowerMgr
245 } // namespace OHOS
246