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