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