1094332d3Sopenharmony_ci/*
2094332d3Sopenharmony_ci * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License.
5094332d3Sopenharmony_ci * You may obtain a copy of the License at
6094332d3Sopenharmony_ci *
7094332d3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8094332d3Sopenharmony_ci *
9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and
13094332d3Sopenharmony_ci * limitations under the License.
14094332d3Sopenharmony_ci */
15094332d3Sopenharmony_ci
16094332d3Sopenharmony_ci#include "power_interface_impl.h"
17094332d3Sopenharmony_ci
18094332d3Sopenharmony_ci#include "errors.h"
19094332d3Sopenharmony_ci#include "hdf_device_desc.h"
20094332d3Sopenharmony_ci#include "hdf_remote_service.h"
21094332d3Sopenharmony_ci#include "hdf_sbuf.h"
22094332d3Sopenharmony_ci#include "pubdef.h"
23094332d3Sopenharmony_ci#include "running_lock_impl.h"
24094332d3Sopenharmony_ci#include "securec.h"
25094332d3Sopenharmony_ci#include "unique_fd.h"
26094332d3Sopenharmony_ci#include "power_hdf_log.h"
27094332d3Sopenharmony_ci#include "power_xcollie.h"
28094332d3Sopenharmony_ci#include "v1_2/power_types.h"
29094332d3Sopenharmony_ci#include <atomic>
30094332d3Sopenharmony_ci#include <chrono>
31094332d3Sopenharmony_ci#include <condition_variable>
32094332d3Sopenharmony_ci#include <cstdlib>
33094332d3Sopenharmony_ci#include <file_ex.h>
34094332d3Sopenharmony_ci#include <hdf_base.h>
35094332d3Sopenharmony_ci#include <iproxy_broker.h>
36094332d3Sopenharmony_ci#include <iremote_object.h>
37094332d3Sopenharmony_ci#include <mutex>
38094332d3Sopenharmony_ci#include <sys/eventfd.h>
39094332d3Sopenharmony_ci#include <sys/stat.h>
40094332d3Sopenharmony_ci#include <sys/types.h>
41094332d3Sopenharmony_ci#include <thread>
42094332d3Sopenharmony_ci#include <unistd.h>
43094332d3Sopenharmony_ci
44094332d3Sopenharmony_ci#ifdef DRIVER_PERIPHERAL_POWER_WAKEUP_CAUSE_PATH
45094332d3Sopenharmony_ci#include "power_config.h"
46094332d3Sopenharmony_ci#endif
47094332d3Sopenharmony_ci#ifdef DRIVERS_PERIPHERAL_POWER_ENABLE_S4
48094332d3Sopenharmony_ci#include "hibernate.h"
49094332d3Sopenharmony_ci#endif
50094332d3Sopenharmony_ci
51094332d3Sopenharmony_cinamespace OHOS {
52094332d3Sopenharmony_cinamespace HDI {
53094332d3Sopenharmony_cinamespace Power {
54094332d3Sopenharmony_cinamespace V1_2 {
55094332d3Sopenharmony_cistatic constexpr const int32_t MAX_FILE_LENGTH = 32 * 1024 * 1024;
56094332d3Sopenharmony_cistatic constexpr const char * const SUSPEND_STATE = "mem";
57094332d3Sopenharmony_cistatic constexpr const char * const SUSPEND_STATE_PATH = "/sys/power/state";
58094332d3Sopenharmony_cistatic constexpr const char * const LOCK_PATH = "/sys/power/wake_lock";
59094332d3Sopenharmony_cistatic constexpr const char * const UNLOCK_PATH = "/sys/power/wake_unlock";
60094332d3Sopenharmony_cistatic constexpr const char * const WAKEUP_COUNT_PATH = "/sys/power/wakeup_count";
61094332d3Sopenharmony_ci#ifdef FASTER_RETRY_OF_SLEEP
62094332d3Sopenharmony_cistatic constexpr std::chrono::milliseconds DEFAULT_WAIT_TIME(100); // 100ms for phone and tablet
63094332d3Sopenharmony_ci#elif defined(SLOWER_RETRY_OF_SLEEP)
64094332d3Sopenharmony_cistatic constexpr std::chrono::milliseconds DEFAULT_WAIT_TIME(500); // 500ms for PC
65094332d3Sopenharmony_ci#else
66094332d3Sopenharmony_cistatic constexpr std::chrono::milliseconds DEFAULT_WAIT_TIME(1000); // 1000ms
67094332d3Sopenharmony_ci#endif
68094332d3Sopenharmony_cistatic constexpr std::chrono::milliseconds MAX_WAIT_TIME(1000 * 60); // 1min
69094332d3Sopenharmony_cistatic constexpr int32_t WAIT_TIME_FACTOR = 2;
70094332d3Sopenharmony_cistatic std::chrono::milliseconds waitTime_(DEFAULT_WAIT_TIME);
71094332d3Sopenharmony_cistatic std::mutex g_mutex;
72094332d3Sopenharmony_cistatic std::mutex g_suspendMutex;
73094332d3Sopenharmony_cistatic std::condition_variable g_suspendCv;
74094332d3Sopenharmony_cistatic std::unique_ptr<std::thread> g_daemon;
75094332d3Sopenharmony_cistatic std::atomic_bool g_suspending;
76094332d3Sopenharmony_cistatic std::atomic_bool g_suspendRetry;
77094332d3Sopenharmony_cistatic sptr<IPowerHdiCallback> g_callback;
78094332d3Sopenharmony_cistatic UniqueFd wakeupCountFd;
79094332d3Sopenharmony_cistatic PowerHdfState g_powerState {PowerHdfState::AWAKE};
80094332d3Sopenharmony_cistatic void AutoSuspendLoop();
81094332d3Sopenharmony_cistatic int32_t DoSuspend();
82094332d3Sopenharmony_cistatic void LoadStringFd(int32_t fd, std::string &content);
83094332d3Sopenharmony_cistatic std::string ReadWakeCount();
84094332d3Sopenharmony_cistatic bool WriteWakeCount(const std::string &count);
85094332d3Sopenharmony_cistatic void NotifyCallback(int code);
86094332d3Sopenharmony_cinamespace {
87094332d3Sopenharmony_cisptr<PowerInterfaceImpl::PowerDeathRecipient> g_deathRecipient = nullptr;
88094332d3Sopenharmony_cibool g_isHdiStart = false;
89094332d3Sopenharmony_ci} // namespace
90094332d3Sopenharmony_ci
91094332d3Sopenharmony_ciextern "C" IPowerInterface *PowerInterfaceImplGetInstance(void)
92094332d3Sopenharmony_ci{
93094332d3Sopenharmony_ci    using OHOS::HDI::Power::V1_2::PowerInterfaceImpl;
94094332d3Sopenharmony_ci    PowerInterfaceImpl *service = new (std::nothrow) PowerInterfaceImpl();
95094332d3Sopenharmony_ci    if (service == nullptr) {
96094332d3Sopenharmony_ci        return nullptr;
97094332d3Sopenharmony_ci    }
98094332d3Sopenharmony_ci
99094332d3Sopenharmony_ci    if (service->Init() != HDF_SUCCESS) {
100094332d3Sopenharmony_ci        delete service;
101094332d3Sopenharmony_ci        return nullptr;
102094332d3Sopenharmony_ci    }
103094332d3Sopenharmony_ci    return service;
104094332d3Sopenharmony_ci}
105094332d3Sopenharmony_ci
106094332d3Sopenharmony_ciint32_t PowerInterfaceImpl::Init()
107094332d3Sopenharmony_ci{
108094332d3Sopenharmony_ci#ifdef DRIVER_PERIPHERAL_POWER_WAKEUP_CAUSE_PATH
109094332d3Sopenharmony_ci    auto& powerConfig = PowerConfig::GetInstance();
110094332d3Sopenharmony_ci    powerConfig.ParseConfig();
111094332d3Sopenharmony_ci#endif
112094332d3Sopenharmony_ci
113094332d3Sopenharmony_ci#ifdef DRIVERS_PERIPHERAL_POWER_ENABLE_S4
114094332d3Sopenharmony_ci    Hibernate::GetInstance().Init();
115094332d3Sopenharmony_ci#endif
116094332d3Sopenharmony_ci    return HDF_SUCCESS;
117094332d3Sopenharmony_ci}
118094332d3Sopenharmony_ci
119094332d3Sopenharmony_ciint32_t PowerInterfaceImpl::RegisterCallback(const sptr<IPowerHdiCallback> &ipowerHdiCallback)
120094332d3Sopenharmony_ci{
121094332d3Sopenharmony_ci    std::lock_guard<std::mutex> lock(g_mutex);
122094332d3Sopenharmony_ci    if (!g_isHdiStart) {
123094332d3Sopenharmony_ci        g_callback = ipowerHdiCallback;
124094332d3Sopenharmony_ci        if (g_callback == nullptr) {
125094332d3Sopenharmony_ci            UnRegister();
126094332d3Sopenharmony_ci            return HDF_SUCCESS;
127094332d3Sopenharmony_ci        }
128094332d3Sopenharmony_ci        g_deathRecipient = new PowerDeathRecipient(this);
129094332d3Sopenharmony_ci        if (g_deathRecipient == nullptr) {
130094332d3Sopenharmony_ci            return HDF_FAILURE;
131094332d3Sopenharmony_ci        }
132094332d3Sopenharmony_ci        AddPowerDeathRecipient(g_callback);
133094332d3Sopenharmony_ci        g_isHdiStart = true;
134094332d3Sopenharmony_ci    }
135094332d3Sopenharmony_ci
136094332d3Sopenharmony_ci    return HDF_SUCCESS;
137094332d3Sopenharmony_ci}
138094332d3Sopenharmony_ci
139094332d3Sopenharmony_ciint32_t PowerInterfaceImpl::UnRegister()
140094332d3Sopenharmony_ci{
141094332d3Sopenharmony_ci    HDF_LOGI("UnRegister");
142094332d3Sopenharmony_ci    RemovePowerDeathRecipient(g_callback);
143094332d3Sopenharmony_ci    g_callback = nullptr;
144094332d3Sopenharmony_ci    g_isHdiStart = false;
145094332d3Sopenharmony_ci    return HDF_SUCCESS;
146094332d3Sopenharmony_ci}
147094332d3Sopenharmony_ci
148094332d3Sopenharmony_ciint32_t PowerInterfaceImpl::RegisterRunningLockCallback(const sptr<IPowerRunningLockCallback>
149094332d3Sopenharmony_ci    &iPowerRunningLockCallback)
150094332d3Sopenharmony_ci{
151094332d3Sopenharmony_ci    if (iPowerRunningLockCallback != nullptr) {
152094332d3Sopenharmony_ci        UnRegisterRunningLockCallback();
153094332d3Sopenharmony_ci    }
154094332d3Sopenharmony_ci    RunningLockImpl::RegisterRunningLockCallback(iPowerRunningLockCallback);
155094332d3Sopenharmony_ci    return HDF_SUCCESS;
156094332d3Sopenharmony_ci}
157094332d3Sopenharmony_ci
158094332d3Sopenharmony_ciint32_t PowerInterfaceImpl::UnRegisterRunningLockCallback()
159094332d3Sopenharmony_ci{
160094332d3Sopenharmony_ci    RunningLockImpl::UnRegisterRunningLockCallback();
161094332d3Sopenharmony_ci    return HDF_SUCCESS;
162094332d3Sopenharmony_ci}
163094332d3Sopenharmony_ci
164094332d3Sopenharmony_ciint32_t PowerInterfaceImpl::StartSuspend()
165094332d3Sopenharmony_ci{
166094332d3Sopenharmony_ci    HDF_LOGI("start suspend");
167094332d3Sopenharmony_ci    std::lock_guard<std::mutex> lock(g_mutex);
168094332d3Sopenharmony_ci    g_suspendRetry = true;
169094332d3Sopenharmony_ci    if (g_suspending) {
170094332d3Sopenharmony_ci        g_powerState = PowerHdfState::INACTIVE;
171094332d3Sopenharmony_ci        g_suspendCv.notify_one();
172094332d3Sopenharmony_ci        return HDF_SUCCESS;
173094332d3Sopenharmony_ci    }
174094332d3Sopenharmony_ci    g_suspending = true;
175094332d3Sopenharmony_ci    g_daemon = std::make_unique<std::thread>(&AutoSuspendLoop);
176094332d3Sopenharmony_ci    g_daemon->detach();
177094332d3Sopenharmony_ci    return HDF_SUCCESS;
178094332d3Sopenharmony_ci}
179094332d3Sopenharmony_ci
180094332d3Sopenharmony_civoid AutoSuspendLoop()
181094332d3Sopenharmony_ci{
182094332d3Sopenharmony_ci    auto suspendLock = std::unique_lock(g_suspendMutex);
183094332d3Sopenharmony_ci    while (true) {
184094332d3Sopenharmony_ci        std::this_thread::sleep_for(waitTime_);
185094332d3Sopenharmony_ci        const std::string wakeupCount = ReadWakeCount();
186094332d3Sopenharmony_ci        if (wakeupCount.empty()) {
187094332d3Sopenharmony_ci            continue;
188094332d3Sopenharmony_ci        }
189094332d3Sopenharmony_ci        if (!g_suspendRetry) {
190094332d3Sopenharmony_ci            g_suspendCv.wait(suspendLock);
191094332d3Sopenharmony_ci        }
192094332d3Sopenharmony_ci        if (!WriteWakeCount(wakeupCount)) {
193094332d3Sopenharmony_ci            continue;
194094332d3Sopenharmony_ci        }
195094332d3Sopenharmony_ci
196094332d3Sopenharmony_ci        NotifyCallback(CMD_ON_SUSPEND);
197094332d3Sopenharmony_ci        g_powerState = PowerHdfState::SLEEP;
198094332d3Sopenharmony_ci        DoSuspend();
199094332d3Sopenharmony_ci        g_powerState = PowerHdfState::AWAKE;
200094332d3Sopenharmony_ci        NotifyCallback(CMD_ON_WAKEUP);
201094332d3Sopenharmony_ci    }
202094332d3Sopenharmony_ci    g_suspending = false;
203094332d3Sopenharmony_ci    g_suspendRetry = false;
204094332d3Sopenharmony_ci}
205094332d3Sopenharmony_ci
206094332d3Sopenharmony_ci#ifdef DRIVER_PERIPHERAL_POWER_SUSPEND_WITH_TAG
207094332d3Sopenharmony_cistatic constexpr const int32_t MAX_RETRY_COUNT = 5;
208094332d3Sopenharmony_cistatic int32_t g_ulsr_loop = 0;
209094332d3Sopenharmony_cistatic std::string g_suspendTag;
210094332d3Sopenharmony_ciint32_t PowerInterfaceImpl::SetSuspendTag(const std::string &tag)
211094332d3Sopenharmony_ci{
212094332d3Sopenharmony_ci    HDF_LOGI("Set suspend tag: %{public}s", tag.c_str());
213094332d3Sopenharmony_ci    g_suspendTag = tag;
214094332d3Sopenharmony_ci    g_ulsr_loop = 0;
215094332d3Sopenharmony_ci    return HDF_SUCCESS;
216094332d3Sopenharmony_ci}
217094332d3Sopenharmony_ci
218094332d3Sopenharmony_ciint32_t DoSuspendWithTag()
219094332d3Sopenharmony_ci{
220094332d3Sopenharmony_ci    UniqueFd suspendStateFd(TEMP_FAILURE_RETRY(open(SUSPEND_STATE_PATH, O_RDWR | O_CLOEXEC)));
221094332d3Sopenharmony_ci    if (suspendStateFd < 0) {
222094332d3Sopenharmony_ci        return HDF_FAILURE;
223094332d3Sopenharmony_ci    }
224094332d3Sopenharmony_ci
225094332d3Sopenharmony_ci    g_ulsr_loop++;
226094332d3Sopenharmony_ci    bool ret = SaveStringToFd(suspendStateFd, g_suspendTag);
227094332d3Sopenharmony_ci    if (!ret) {
228094332d3Sopenharmony_ci        waitTime_ = std::min(waitTime_ * WAIT_TIME_FACTOR, MAX_WAIT_TIME);
229094332d3Sopenharmony_ci        HDF_LOGE("SaveStringToFd fail, tag:%{public}s loop:%{public}d", g_suspendTag.c_str(), g_ulsr_loop);
230094332d3Sopenharmony_ci        if (g_ulsr_loop >= MAX_RETRY_COUNT) {
231094332d3Sopenharmony_ci            HDF_LOGE("DoSuspendWithTag fail: %{public}s", g_suspendTag.c_str());
232094332d3Sopenharmony_ci            g_suspendTag.clear();
233094332d3Sopenharmony_ci            waitTime_ = DEFAULT_WAIT_TIME;
234094332d3Sopenharmony_ci            return HDF_FAILURE;
235094332d3Sopenharmony_ci        }
236094332d3Sopenharmony_ci        return HDF_SUCCESS;
237094332d3Sopenharmony_ci    }
238094332d3Sopenharmony_ci    HDF_LOGI("Do Suspend %{public}d: echo %{public}s > /sys/power/state", g_ulsr_loop, g_suspendTag.c_str());
239094332d3Sopenharmony_ci    g_suspendTag.clear();
240094332d3Sopenharmony_ci    waitTime_ = DEFAULT_WAIT_TIME;
241094332d3Sopenharmony_ci    return HDF_SUCCESS;
242094332d3Sopenharmony_ci}
243094332d3Sopenharmony_ci#else
244094332d3Sopenharmony_ciint32_t PowerInterfaceImpl::SetSuspendTag(const std::string &tag)
245094332d3Sopenharmony_ci{
246094332d3Sopenharmony_ci    return HDF_SUCCESS;
247094332d3Sopenharmony_ci}
248094332d3Sopenharmony_ci#endif
249094332d3Sopenharmony_ci
250094332d3Sopenharmony_ciint32_t DoSuspend()
251094332d3Sopenharmony_ci{
252094332d3Sopenharmony_ci    std::lock_guard<std::mutex> lock(g_mutex);
253094332d3Sopenharmony_ci
254094332d3Sopenharmony_ci#ifdef DRIVER_PERIPHERAL_POWER_SUSPEND_WITH_TAG
255094332d3Sopenharmony_ci    if (!g_suspendTag.empty()) {
256094332d3Sopenharmony_ci        return DoSuspendWithTag();
257094332d3Sopenharmony_ci    }
258094332d3Sopenharmony_ci#endif
259094332d3Sopenharmony_ci
260094332d3Sopenharmony_ci    UniqueFd suspendStateFd(TEMP_FAILURE_RETRY(open(SUSPEND_STATE_PATH, O_RDWR | O_CLOEXEC)));
261094332d3Sopenharmony_ci    if (suspendStateFd < 0) {
262094332d3Sopenharmony_ci        return HDF_FAILURE;
263094332d3Sopenharmony_ci    }
264094332d3Sopenharmony_ci    bool ret = SaveStringToFd(suspendStateFd, SUSPEND_STATE);
265094332d3Sopenharmony_ci    if (!ret) {
266094332d3Sopenharmony_ci        HDF_LOGE("DoSuspend fail");
267094332d3Sopenharmony_ci        waitTime_ = std::min(waitTime_ * WAIT_TIME_FACTOR, MAX_WAIT_TIME);
268094332d3Sopenharmony_ci        return HDF_FAILURE;
269094332d3Sopenharmony_ci    }
270094332d3Sopenharmony_ci    waitTime_ = DEFAULT_WAIT_TIME;
271094332d3Sopenharmony_ci    return HDF_SUCCESS;
272094332d3Sopenharmony_ci}
273094332d3Sopenharmony_ci
274094332d3Sopenharmony_civoid NotifyCallback(int code)
275094332d3Sopenharmony_ci{
276094332d3Sopenharmony_ci    if (g_callback == nullptr) {
277094332d3Sopenharmony_ci        return;
278094332d3Sopenharmony_ci    }
279094332d3Sopenharmony_ci    switch (code) {
280094332d3Sopenharmony_ci        case CMD_ON_SUSPEND:
281094332d3Sopenharmony_ci            g_callback->OnSuspend();
282094332d3Sopenharmony_ci            break;
283094332d3Sopenharmony_ci        case CMD_ON_WAKEUP:
284094332d3Sopenharmony_ci            g_callback->OnWakeup();
285094332d3Sopenharmony_ci            break;
286094332d3Sopenharmony_ci        default:
287094332d3Sopenharmony_ci            break;
288094332d3Sopenharmony_ci    }
289094332d3Sopenharmony_ci}
290094332d3Sopenharmony_ci
291094332d3Sopenharmony_ciint32_t PowerInterfaceImpl::StopSuspend()
292094332d3Sopenharmony_ci{
293094332d3Sopenharmony_ci    HDF_LOGI("stop suspend");
294094332d3Sopenharmony_ci    g_suspendRetry = false;
295094332d3Sopenharmony_ci    g_powerState = PowerHdfState::AWAKE;
296094332d3Sopenharmony_ci    return HDF_SUCCESS;
297094332d3Sopenharmony_ci}
298094332d3Sopenharmony_ci
299094332d3Sopenharmony_ciint32_t PowerInterfaceImpl::ForceSuspend()
300094332d3Sopenharmony_ci{
301094332d3Sopenharmony_ci    //force suspend changed into active suspend
302094332d3Sopenharmony_ci    HDF_LOGI("active suspend");
303094332d3Sopenharmony_ci    StartSuspend();
304094332d3Sopenharmony_ci    return HDF_SUCCESS;
305094332d3Sopenharmony_ci}
306094332d3Sopenharmony_ci
307094332d3Sopenharmony_ciint32_t PowerInterfaceImpl::Hibernate()
308094332d3Sopenharmony_ci{
309094332d3Sopenharmony_ci#ifdef DRIVERS_PERIPHERAL_POWER_ENABLE_S4
310094332d3Sopenharmony_ci    HDF_LOGI("hibernate begin.");
311094332d3Sopenharmony_ci    return Hibernate::GetInstance().DoHibernate();
312094332d3Sopenharmony_ci#else
313094332d3Sopenharmony_ci    HDF_LOGI("hdf hibernate interface not supported.");
314094332d3Sopenharmony_ci    return HDF_FAILURE;
315094332d3Sopenharmony_ci#endif
316094332d3Sopenharmony_ci}
317094332d3Sopenharmony_ci
318094332d3Sopenharmony_ciint32_t PowerInterfaceImpl::SuspendBlock(const std::string &name)
319094332d3Sopenharmony_ci{
320094332d3Sopenharmony_ci    std::lock_guard<std::mutex> lock(g_mutex);
321094332d3Sopenharmony_ci    if (name.empty()) {
322094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
323094332d3Sopenharmony_ci    }
324094332d3Sopenharmony_ci    UniqueFd fd(TEMP_FAILURE_RETRY(open(LOCK_PATH, O_RDWR | O_CLOEXEC)));
325094332d3Sopenharmony_ci    bool ret = SaveStringToFd(fd, name);
326094332d3Sopenharmony_ci    if (!ret) {
327094332d3Sopenharmony_ci        return HDF_FAILURE;
328094332d3Sopenharmony_ci    }
329094332d3Sopenharmony_ci    return HDF_SUCCESS;
330094332d3Sopenharmony_ci}
331094332d3Sopenharmony_ci
332094332d3Sopenharmony_ciint32_t PowerInterfaceImpl::SuspendUnblock(const std::string &name)
333094332d3Sopenharmony_ci{
334094332d3Sopenharmony_ci    std::lock_guard<std::mutex> lock(g_mutex);
335094332d3Sopenharmony_ci    if (name.empty()) {
336094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
337094332d3Sopenharmony_ci    }
338094332d3Sopenharmony_ci    UniqueFd fd(TEMP_FAILURE_RETRY(open(UNLOCK_PATH, O_RDWR | O_CLOEXEC)));
339094332d3Sopenharmony_ci    bool ret = SaveStringToFd(fd, name);
340094332d3Sopenharmony_ci    if (!ret) {
341094332d3Sopenharmony_ci        return HDF_FAILURE;
342094332d3Sopenharmony_ci    }
343094332d3Sopenharmony_ci    return HDF_SUCCESS;
344094332d3Sopenharmony_ci}
345094332d3Sopenharmony_ci
346094332d3Sopenharmony_ciint32_t PowerInterfaceImpl::AddPowerDeathRecipient(const sptr<IPowerHdiCallback> &callback)
347094332d3Sopenharmony_ci{
348094332d3Sopenharmony_ci    HDF_LOGI("AddPowerDeathRecipient");
349094332d3Sopenharmony_ci    const sptr<IRemoteObject> &remote = OHOS::HDI::hdi_objcast<IPowerHdiCallback>(callback);
350094332d3Sopenharmony_ci    bool result = remote->AddDeathRecipient(g_deathRecipient);
351094332d3Sopenharmony_ci    if (!result) {
352094332d3Sopenharmony_ci        HDF_LOGI("AddPowerDeathRecipient fail");
353094332d3Sopenharmony_ci        return HDF_FAILURE;
354094332d3Sopenharmony_ci    }
355094332d3Sopenharmony_ci    return HDF_SUCCESS;
356094332d3Sopenharmony_ci}
357094332d3Sopenharmony_ci
358094332d3Sopenharmony_ciint32_t PowerInterfaceImpl::RemovePowerDeathRecipient(const sptr<IPowerHdiCallback> &callback)
359094332d3Sopenharmony_ci{
360094332d3Sopenharmony_ci    HDF_LOGI("RemovePowerDeathRecipient");
361094332d3Sopenharmony_ci    const sptr<IRemoteObject> &remote = OHOS::HDI::hdi_objcast<IPowerHdiCallback>(callback);
362094332d3Sopenharmony_ci    bool result = remote->RemoveDeathRecipient(g_deathRecipient);
363094332d3Sopenharmony_ci    if (!result) {
364094332d3Sopenharmony_ci        HDF_LOGI("RemovePowerDeathRecipient fail");
365094332d3Sopenharmony_ci        return HDF_FAILURE;
366094332d3Sopenharmony_ci    }
367094332d3Sopenharmony_ci    return HDF_SUCCESS;
368094332d3Sopenharmony_ci}
369094332d3Sopenharmony_ci
370094332d3Sopenharmony_civoid PowerInterfaceImpl::PowerDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &object)
371094332d3Sopenharmony_ci{
372094332d3Sopenharmony_ci    HDF_LOGI("PowerDeathRecipient OnRemoteDied");
373094332d3Sopenharmony_ci    powerInterfaceImpl_->UnRegister();
374094332d3Sopenharmony_ci    RunningLockImpl::Clean();
375094332d3Sopenharmony_ci}
376094332d3Sopenharmony_ci
377094332d3Sopenharmony_civoid LoadStringFd(int32_t fd, std::string &content)
378094332d3Sopenharmony_ci{
379094332d3Sopenharmony_ci    if (fd <= 0) {
380094332d3Sopenharmony_ci        HDF_LOGW("invalid fd: %{public}d", fd);
381094332d3Sopenharmony_ci        return;
382094332d3Sopenharmony_ci    }
383094332d3Sopenharmony_ci
384094332d3Sopenharmony_ci    const int32_t fileLength = lseek(fd, 0, SEEK_END);
385094332d3Sopenharmony_ci    if (fileLength > MAX_FILE_LENGTH || fileLength <= 0) {
386094332d3Sopenharmony_ci        HDF_LOGW("invalid file length(%{public}d)!", fileLength);
387094332d3Sopenharmony_ci        return;
388094332d3Sopenharmony_ci    }
389094332d3Sopenharmony_ci    int32_t loc = lseek(fd, 0, SEEK_SET);
390094332d3Sopenharmony_ci    if (loc == -1) {
391094332d3Sopenharmony_ci        HDF_LOGE("lseek file to begin failed!");
392094332d3Sopenharmony_ci        return;
393094332d3Sopenharmony_ci    }
394094332d3Sopenharmony_ci    content.resize(fileLength);
395094332d3Sopenharmony_ci    const int32_t len = static_cast<int32_t>(read(fd, content.data(), fileLength));
396094332d3Sopenharmony_ci    if (len <= 0) {
397094332d3Sopenharmony_ci        HDF_LOGW("the length read from file is failed, len: %{public}d, fileLen: %{public}d", len, fileLength);
398094332d3Sopenharmony_ci        content.clear();
399094332d3Sopenharmony_ci    }
400094332d3Sopenharmony_ci}
401094332d3Sopenharmony_ci
402094332d3Sopenharmony_cistd::string ReadWakeCount()
403094332d3Sopenharmony_ci{
404094332d3Sopenharmony_ci    if (wakeupCountFd < 0) {
405094332d3Sopenharmony_ci        wakeupCountFd = UniqueFd(TEMP_FAILURE_RETRY(open(WAKEUP_COUNT_PATH, O_RDWR | O_CLOEXEC)));
406094332d3Sopenharmony_ci    }
407094332d3Sopenharmony_ci    std::string wakeupCount;
408094332d3Sopenharmony_ci    LoadStringFd(wakeupCountFd, wakeupCount);
409094332d3Sopenharmony_ci
410094332d3Sopenharmony_ci    return wakeupCount;
411094332d3Sopenharmony_ci}
412094332d3Sopenharmony_ci
413094332d3Sopenharmony_cibool WriteWakeCount(const std::string &count)
414094332d3Sopenharmony_ci{
415094332d3Sopenharmony_ci    if (wakeupCountFd < 0) {
416094332d3Sopenharmony_ci        wakeupCountFd = UniqueFd(TEMP_FAILURE_RETRY(open(WAKEUP_COUNT_PATH, O_RDWR | O_CLOEXEC)));
417094332d3Sopenharmony_ci    }
418094332d3Sopenharmony_ci    bool ret = SaveStringToFd(wakeupCountFd, count.c_str());
419094332d3Sopenharmony_ci    return ret;
420094332d3Sopenharmony_ci}
421094332d3Sopenharmony_ci
422094332d3Sopenharmony_cistatic void LoadSystemInfo(const std::string &path, std::string &info)
423094332d3Sopenharmony_ci{
424094332d3Sopenharmony_ci    UniqueFd fd(TEMP_FAILURE_RETRY(open(path.c_str(), O_RDWR | O_CLOEXEC)));
425094332d3Sopenharmony_ci    std::string str;
426094332d3Sopenharmony_ci    if (fd >= 0) {
427094332d3Sopenharmony_ci        bool ret = LoadStringFromFd(fd, str);
428094332d3Sopenharmony_ci        if (!ret) {
429094332d3Sopenharmony_ci            str = "# Failed to read";
430094332d3Sopenharmony_ci        }
431094332d3Sopenharmony_ci    } else {
432094332d3Sopenharmony_ci        str = "# Failed to open";
433094332d3Sopenharmony_ci    }
434094332d3Sopenharmony_ci    info.append(path);
435094332d3Sopenharmony_ci    info.append(": " + str + "\n");
436094332d3Sopenharmony_ci}
437094332d3Sopenharmony_ci
438094332d3Sopenharmony_ciint32_t PowerInterfaceImpl::PowerDump(std::string &info)
439094332d3Sopenharmony_ci{
440094332d3Sopenharmony_ci    std::string dumpInfo("");
441094332d3Sopenharmony_ci    LoadSystemInfo(SUSPEND_STATE_PATH, dumpInfo);
442094332d3Sopenharmony_ci    LoadSystemInfo(LOCK_PATH, dumpInfo);
443094332d3Sopenharmony_ci    LoadSystemInfo(UNLOCK_PATH, dumpInfo);
444094332d3Sopenharmony_ci    info = dumpInfo;
445094332d3Sopenharmony_ci
446094332d3Sopenharmony_ci    return HDF_SUCCESS;
447094332d3Sopenharmony_ci}
448094332d3Sopenharmony_ci
449094332d3Sopenharmony_ciint32_t PowerInterfaceImpl::HoldRunningLock(const RunningLockInfo &info)
450094332d3Sopenharmony_ci{
451094332d3Sopenharmony_ci    Power::PowerXCollie powerXcollie("Power_HoldRunningLock");
452094332d3Sopenharmony_ci    return RunningLockImpl::Hold(info, g_powerState);
453094332d3Sopenharmony_ci}
454094332d3Sopenharmony_ci
455094332d3Sopenharmony_ciint32_t PowerInterfaceImpl::UnholdRunningLock(const RunningLockInfo &info)
456094332d3Sopenharmony_ci{
457094332d3Sopenharmony_ci    Power::PowerXCollie powerXcollie("Power_UnholdRunningLock");
458094332d3Sopenharmony_ci    return RunningLockImpl::Unhold(info);
459094332d3Sopenharmony_ci}
460094332d3Sopenharmony_ci
461094332d3Sopenharmony_ciint32_t PowerInterfaceImpl::HoldRunningLockExt(const RunningLockInfo &info,
462094332d3Sopenharmony_ci    uint64_t lockid, const std::string &bundleName)
463094332d3Sopenharmony_ci{
464094332d3Sopenharmony_ci    Power::PowerXCollie powerXcollie("Power_HoldRunningLockExt");
465094332d3Sopenharmony_ci    return RunningLockImpl::HoldLock(info, g_powerState, lockid, bundleName);
466094332d3Sopenharmony_ci}
467094332d3Sopenharmony_ci
468094332d3Sopenharmony_ciint32_t PowerInterfaceImpl::UnholdRunningLockExt(const RunningLockInfo &info,
469094332d3Sopenharmony_ci    uint64_t lockid, const std::string &bundleName)
470094332d3Sopenharmony_ci{
471094332d3Sopenharmony_ci    Power::PowerXCollie powerXcollie("Power_UnholdRunningLockExt");
472094332d3Sopenharmony_ci    return RunningLockImpl::UnholdLock(info, lockid, bundleName);
473094332d3Sopenharmony_ci}
474094332d3Sopenharmony_ci
475094332d3Sopenharmony_ciint32_t PowerInterfaceImpl::GetWakeupReason(std::string &reason)
476094332d3Sopenharmony_ci{
477094332d3Sopenharmony_ci#ifdef DRIVER_PERIPHERAL_POWER_WAKEUP_CAUSE_PATH
478094332d3Sopenharmony_ci    auto& powerConfig = PowerConfig::GetInstance();
479094332d3Sopenharmony_ci    std::map<std::string, PowerConfig::PowerSceneConfig> sceneConfigMap= powerConfig.GetPowerSceneConfigMap();
480094332d3Sopenharmony_ci    std::map<std::string, PowerConfig::PowerSceneConfig>::iterator it = sceneConfigMap.find("wakeuo_cause");
481094332d3Sopenharmony_ci    if (it == sceneConfigMap.end()) {
482094332d3Sopenharmony_ci        HDF_LOGW("wakeuo_cause getPath does not exist");
483094332d3Sopenharmony_ci        return HDF_FAILURE;
484094332d3Sopenharmony_ci    }
485094332d3Sopenharmony_ci    std::string getPath = (it->second).getPath;
486094332d3Sopenharmony_ci    HDF_LOGI("getPath = %{public}s", getPath.c_str());
487094332d3Sopenharmony_ci
488094332d3Sopenharmony_ci    UniqueFd wakeupCauseFd(TEMP_FAILURE_RETRY(open(getPath.c_str(), O_RDONLY | O_CLOEXEC)));
489094332d3Sopenharmony_ci    if (wakeupCauseFd < 0) {
490094332d3Sopenharmony_ci        return HDF_FAILURE;
491094332d3Sopenharmony_ci    }
492094332d3Sopenharmony_ci    LoadStringFd(wakeupCauseFd, reason);
493094332d3Sopenharmony_ci    return HDF_SUCCESS;
494094332d3Sopenharmony_ci#else
495094332d3Sopenharmony_ci    HDF_LOGW("wakrup cause path not config");
496094332d3Sopenharmony_ci    return HDF_FAILURE;
497094332d3Sopenharmony_ci#endif
498094332d3Sopenharmony_ci}
499094332d3Sopenharmony_ci} // namespace V1_2
500094332d3Sopenharmony_ci} // namespace Power
501094332d3Sopenharmony_ci} // namespace HDI
502094332d3Sopenharmony_ci} // namespace OHOS
503