• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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 "power_interface_impl.h"
17 
18 #include "errors.h"
19 #include "hdf_device_desc.h"
20 #include "hdf_remote_service.h"
21 #include "hdf_sbuf.h"
22 #include "pubdef.h"
23 #include "running_lock_impl.h"
24 #include "securec.h"
25 #include "unique_fd.h"
26 #include "power_hdf_log.h"
27 #include "power_xcollie.h"
28 #include "v1_2/power_types.h"
29 #include <atomic>
30 #include <chrono>
31 #include <condition_variable>
32 #include <cstdlib>
33 #include <file_ex.h>
34 #include <hdf_base.h>
35 #include <iproxy_broker.h>
36 #include <iremote_object.h>
37 #include <mutex>
38 #include <sys/eventfd.h>
39 #include <sys/stat.h>
40 #include <sys/types.h>
41 #include <thread>
42 #include <unistd.h>
43 
44 #include "power_config.h"
45 #ifdef DRIVERS_PERIPHERAL_POWER_ENABLE_S4
46 #include "hibernate.h"
47 #endif
48 
49 namespace OHOS {
50 namespace HDI {
51 namespace Power {
52 namespace V1_3 {
53 using namespace OHOS::HDI::Power;
54 static constexpr const int32_t MAX_FILE_LENGTH = 32 * 1024 * 1024;
55 static constexpr const char * const SUSPEND_STATE = "mem";
56 static constexpr const char * const SUSPEND_STATE_PATH = "/sys/power/state";
57 static constexpr const char * const LOCK_PATH = "/sys/power/wake_lock";
58 static constexpr const char * const UNLOCK_PATH = "/sys/power/wake_unlock";
59 static constexpr const char * const WAKEUP_COUNT_PATH = "/sys/power/wakeup_count";
60 #ifdef FASTER_RETRY_OF_SLEEP
61 static constexpr std::chrono::milliseconds DEFAULT_WAIT_TIME(100); // 100ms for phone and tablet
62 #elif defined(SLOWER_RETRY_OF_SLEEP)
63 static constexpr std::chrono::milliseconds DEFAULT_WAIT_TIME(500); // 500ms for PC
64 #else
65 static constexpr std::chrono::milliseconds DEFAULT_WAIT_TIME(1000); // 1000ms
66 #endif
67 #ifdef FASTER_RETRY_OF_SLEEP
68 static constexpr std::chrono::milliseconds MAX_WAIT_TIME(5763); // 5763ms for phone and tablet
69 #else
70 static constexpr std::chrono::milliseconds MAX_WAIT_TIME(1000 * 60); // 1min
71 #endif
72 static constexpr int32_t WAIT_TIME_FACTOR = 2;
73 static std::chrono::milliseconds waitTime_(DEFAULT_WAIT_TIME);
74 static std::mutex g_mutex;
75 static std::mutex g_suspendMutex;
76 static std::condition_variable g_suspendCv;
77 static std::unique_ptr<std::thread> g_daemon;
78 static std::atomic_bool g_suspending;
79 static std::atomic_bool g_suspendRetry;
80 static UniqueFd wakeupCountFd;
81 static PowerHdfState g_powerState {PowerHdfState::AWAKE};
82 static void AutoSuspendLoop();
83 static int32_t DoSuspend();
84 static void LoadStringFd(int32_t fd, std::string &content);
85 static std::string ReadWakeCount();
86 static bool WriteWakeCount(const std::string &count);
87 static void NotifyCallback(int code);
88 // IPowerHdiCallback
89 static sptr<IPowerHdiCallback> g_callback = nullptr;
90 sptr<PowerInterfaceImpl::PowerDeathRecipient> g_deathRecipient = nullptr;
91 bool g_isHdiStart = false;
92 
93 #ifdef DRIVER_PERIPHERAL_POWER_SUSPEND_WITH_TAG
94 static constexpr const char * const WAKEUP_TAG_NONE = "";
95 static constexpr const int32_t MAX_RETRY_COUNT = 5;
96 static constexpr int32_t g_ulsr_loop = 0;
97 static std::string g_suspendTag = WAKEUP_TAG_NONE;
98 static std::string g_wakeupTag = WAKEUP_TAG_NONE;
99 // IPowerHdiCallbackExt
100 static sptr<V1_3::IPowerHdiCallbackExt> g_callbackExt = nullptr;
101 static sptr<PowerInterfaceImpl::PowerDeathRecipientExt> g_deathRecipientExt = nullptr;
102 static bool g_isPowerHdiExtReg = false;
103 #endif
104 
PowerInterfaceImplGetInstance(void)105 extern "C" V1_3::IPowerInterface *PowerInterfaceImplGetInstance(void)
106 {
107     using OHOS::HDI::Power::V1_3::PowerInterfaceImpl;
108     PowerInterfaceImpl *service = new (std::nothrow) PowerInterfaceImpl();
109     if (service == nullptr) {
110         return nullptr;
111     }
112 
113     if (service->Init() != HDF_SUCCESS) {
114         delete service;
115         return nullptr;
116     }
117     return service;
118 }
119 
Init()120 int32_t PowerInterfaceImpl::Init()
121 {
122     auto& powerConfig = PowerConfig::GetInstance();
123     powerConfig.ParseConfig();
124 #ifdef DRIVERS_PERIPHERAL_POWER_ENABLE_S4
125     Hibernate::GetInstance().Init();
126 #endif
127     return HDF_SUCCESS;
128 }
129 
RegisterCallback(const sptr<IPowerHdiCallback> & ipowerHdiCallback)130 int32_t PowerInterfaceImpl::RegisterCallback(const sptr<IPowerHdiCallback> &ipowerHdiCallback)
131 {
132     std::lock_guard<std::mutex> lock(g_mutex);
133     if (!g_isHdiStart) {
134         g_callback = ipowerHdiCallback;
135         if (g_callback == nullptr) {
136             UnRegister();
137             return HDF_SUCCESS;
138         }
139         g_deathRecipient = new PowerDeathRecipient(this);
140         if (g_deathRecipient == nullptr) {
141             return HDF_FAILURE;
142         }
143         const sptr<IRemoteObject>& remote = OHOS::HDI::hdi_objcast<IPowerHdiCallback>(g_callback);
144         AddPowerDeathRecipient(remote, g_deathRecipient);
145         g_isHdiStart = true;
146     }
147 
148     return HDF_SUCCESS;
149 }
150 
UnRegister()151 int32_t PowerInterfaceImpl::UnRegister()
152 {
153     HDF_LOGI("UnRegister");
154     const sptr<IRemoteObject>& remote = OHOS::HDI::hdi_objcast<IPowerHdiCallback>(g_callback);
155     RemovePowerDeathRecipient(remote, g_deathRecipient);
156     g_callback = nullptr;
157     g_isHdiStart = false;
158     return HDF_SUCCESS;
159 }
160 
RegisterRunningLockCallback(const sptr<IPowerRunningLockCallback> & iPowerRunningLockCallback)161 int32_t PowerInterfaceImpl::RegisterRunningLockCallback(const sptr<IPowerRunningLockCallback>
162     &iPowerRunningLockCallback)
163 {
164     if (iPowerRunningLockCallback != nullptr) {
165         UnRegisterRunningLockCallback();
166     }
167     RunningLockImpl::RegisterRunningLockCallback(iPowerRunningLockCallback);
168     return HDF_SUCCESS;
169 }
170 
UnRegisterRunningLockCallback()171 int32_t PowerInterfaceImpl::UnRegisterRunningLockCallback()
172 {
173     RunningLockImpl::UnRegisterRunningLockCallback();
174     return HDF_SUCCESS;
175 }
176 
StartSuspend()177 int32_t PowerInterfaceImpl::StartSuspend()
178 {
179     std::lock_guard<std::mutex> lock(g_mutex);
180     HDF_LOGI("staS3");
181     g_suspendRetry = true;
182     if (g_suspending) {
183         g_powerState = PowerHdfState::INACTIVE;
184         g_suspendCv.notify_one();
185         return HDF_SUCCESS;
186     }
187     g_suspending = true;
188     g_daemon = std::make_unique<std::thread>(&AutoSuspendLoop);
189     g_daemon->detach();
190     return HDF_SUCCESS;
191 }
192 
AutoSuspendLoop()193 void AutoSuspendLoop()
194 {
195     auto suspendLock = std::unique_lock(g_suspendMutex);
196 #ifdef DRIVERS_PERIPHERAL_POWER_HOST_SCHED_PRIORITY
197     struct sched_param param = { 0 };
198     param.sched_priority = 1; // thread priority:51
199     int32_t schRet = sched_setscheduler(0, SCHED_FIFO, &param);
200     if (schRet != 0) {
201         HDF_LOGI("power_host set SCHED_FIFO, schRet: %{public}d error: %{public}s", schRet, strerror(errno));
202     }
203 #endif
204     while (true) {
205         std::this_thread::sleep_for(waitTime_);
206         const std::string wakeupCount = ReadWakeCount();
207         if (wakeupCount.empty()) {
208             continue;
209         }
210         if (!g_suspendRetry) {
211             g_suspendCv.wait(suspendLock);
212         }
213         if (!WriteWakeCount(wakeupCount)) {
214             continue;
215         }
216 
217         NotifyCallback(CMD_ON_SUSPEND);
218         g_powerState = PowerHdfState::SLEEP;
219         DoSuspend();
220         g_powerState = PowerHdfState::AWAKE;
221         NotifyCallback(CMD_ON_WAKEUP);
222     }
223     g_suspending = false;
224     g_suspendRetry = false;
225 }
226 
227 #ifdef DRIVER_PERIPHERAL_POWER_SUSPEND_WITH_TAG
SetSuspendTag(const std::string & tag)228 int32_t PowerInterfaceImpl::SetSuspendTag(const std::string &tag)
229 {
230     HDF_LOGI("Set suspend tag: %{public}s", tag.c_str());
231     g_suspendTag = tag;
232     g_ulsr_loop = 0;
233     return HDF_SUCCESS;
234 }
235 
RegisterPowerCallbackExt(const sptr<V1_3::IPowerHdiCallbackExt> & ipowerHdiCallback)236 int32_t PowerInterfaceImpl::RegisterPowerCallbackExt(const sptr<V1_3::IPowerHdiCallbackExt> &ipowerHdiCallback)
237 {
238     std::lock_guard<std::mutex> lock(g_mutex);
239     HDF_LOGI("RegisterPowerCallbackExt, g_isPowerHdiExtReg:%{public}d", static_cast<int32_t>(g_isPowerHdiExtReg));
240     if (!g_isPowerHdiExtReg) {
241         if (ipowerHdiCallback == nullptr) {
242             return HDF_FAILURE;
243         }
244         g_deathRecipientExt = new PowerDeathRecipientExt(this);
245         if (g_deathRecipientExt == nullptr) {
246             return HDF_FAILURE;
247         }
248         g_callbackExt = ipowerHdiCallback;
249         const sptr<IRemoteObject> &remote = OHOS::HDI::hdi_objcast<V1_3::IPowerHdiCallbackExt>(g_callbackExt);
250         AddPowerDeathRecipient(remote, g_deathRecipientExt);
251         g_isPowerHdiExtReg = true;
252     }
253 
254     return HDF_SUCCESS;
255 }
256 
UnRegisterPowerCallbackExt(const sptr<V1_3::IPowerHdiCallbackExt> & ipowerHdiCallback)257 int32_t PowerInterfaceImpl::UnRegisterPowerCallbackExt(const sptr<V1_3::IPowerHdiCallbackExt> &ipowerHdiCallback)
258 {
259     std::lock_guard<std::mutex> lock(g_mutex);
260     HDF_LOGI("UnRegisterPowerCallbackExt, g_isPowerHdiExtReg:%{public}d", static_cast<int32_t>(g_isPowerHdiExtReg));
261     if (g_isPowerHdiExtReg) {
262         const sptr<IRemoteObject>& remote = OHOS::HDI::hdi_objcast<V1_3::IPowerHdiCallbackExt>(g_callbackExt);
263         RemovePowerDeathRecipient(remote, g_deathRecipientExt);
264         g_callbackExt = nullptr;
265         g_isPowerHdiExtReg = false;
266     }
267     return HDF_SUCCESS;
268 }
269 
OnRemoteDied(const wptr<IRemoteObject> & object)270 void PowerInterfaceImpl::PowerDeathRecipientExt::OnRemoteDied(const wptr<IRemoteObject>& object)
271 {
272     HDF_LOGI("PowerDeathRecipientExt OnRemoteDied");
273     powerInterfaceImpl_->UnRegisterPowerCallbackExt(g_callbackExt);
274     RunningLockImpl::Clean();
275 }
276 
DoSuspendWithTag()277 int32_t DoSuspendWithTag()
278 {
279     UniqueFd suspendStateFd(TEMP_FAILURE_RETRY(open(SUSPEND_STATE_PATH, O_RDWR | O_CLOEXEC)));
280     if (suspendStateFd < 0) {
281         return HDF_FAILURE;
282     }
283 
284     g_ulsr_loop++;
285     bool ret = SaveStringToFd(suspendStateFd, g_suspendTag);
286     if (!ret) {
287         waitTime_ = std::min(waitTime_ * WAIT_TIME_FACTOR, MAX_WAIT_TIME);
288         HDF_LOGE("SaveStringToFd fail, tag:%{public}s loop:%{public}d", g_suspendTag.c_str(), g_ulsr_loop);
289         if (g_ulsr_loop >= MAX_RETRY_COUNT) {
290             HDF_LOGE("DoSuspendWithTag fail: %{public}s", g_suspendTag.c_str());
291             g_suspendTag.clear();
292             waitTime_ = DEFAULT_WAIT_TIME;
293             return HDF_FAILURE;
294         }
295         return HDF_SUCCESS;
296     }
297     HDF_LOGI("Do Suspend %{public}d: echo %{public}s > /sys/power/state", g_ulsr_loop, g_suspendTag.c_str());
298     g_suspendTag.clear();
299     waitTime_ = DEFAULT_WAIT_TIME;
300     return HDF_SUCCESS;
301 }
302 #else
SetSuspendTag(const std::string & tag)303 int32_t PowerInterfaceImpl::SetSuspendTag(const std::string &tag)
304 {
305     HDF_LOGI("SetSuspendTag not supported");
306     return HDF_SUCCESS;
307 }
308 
RegisterPowerCallbackExt(const sptr<V1_3::IPowerHdiCallbackExt> & ipowerHdiCallback)309 int32_t PowerInterfaceImpl::RegisterPowerCallbackExt(const sptr<V1_3::IPowerHdiCallbackExt> &ipowerHdiCallback)
310 {
311     HDF_LOGI("RegisterPowerCallbackExt not supported");
312     (void)ipowerHdiCallback;
313     return HDF_SUCCESS;
314 }
315 
UnRegisterPowerCallbackExt(const sptr<V1_3::IPowerHdiCallbackExt> & ipowerHdiCallback)316 int32_t PowerInterfaceImpl::UnRegisterPowerCallbackExt(const sptr<V1_3::IPowerHdiCallbackExt> &ipowerHdiCallback)
317 {
318     HDF_LOGI("UnRegisterPowerCallbackExt not supported");
319     (void)ipowerHdiCallback;
320     return HDF_SUCCESS;
321 }
322 
OnRemoteDied(const wptr<IRemoteObject> & object)323 void PowerInterfaceImpl::PowerDeathRecipientExt::OnRemoteDied(const wptr<IRemoteObject>& object)
324 {
325     HDF_LOGI("PowerDeathRecipientExt not supported");
326 }
327 #endif
328 
DoSuspend()329 int32_t DoSuspend()
330 {
331 #ifdef DRIVER_PERIPHERAL_POWER_SUSPEND_WITH_TAG
332     if (!g_suspendTag.empty()) {
333         return DoSuspendWithTag();
334     }
335 #endif
336 
337     UniqueFd suspendStateFd(TEMP_FAILURE_RETRY(open(SUSPEND_STATE_PATH, O_RDWR | O_CLOEXEC)));
338     if (suspendStateFd < 0) {
339         HDF_LOGE("DoSuspend open suspendStateFd fail, error: %{public}s", strerror(errno));
340         return HDF_FAILURE;
341     }
342     HDF_LOGD("DoSuspend SaveStringToFd");
343     bool ret = SaveStringToFd(suspendStateFd, SUSPEND_STATE);
344     if (!ret) {
345         HDF_LOGE("S3 FA");
346         waitTime_ = std::min(waitTime_ * WAIT_TIME_FACTOR, MAX_WAIT_TIME);
347         return HDF_FAILURE;
348     }
349     waitTime_ = DEFAULT_WAIT_TIME;
350     return HDF_SUCCESS;
351 }
352 
NotifyCallback(int code)353 void NotifyCallback(int code)
354 {
355     if (g_callback == nullptr) {
356         return;
357     }
358     switch (code) {
359         case CMD_ON_SUSPEND: {
360             if (g_callback != nullptr) {
361                 g_callback->OnSuspend();
362             }
363 #ifdef DRIVER_PERIPHERAL_POWER_SUSPEND_WITH_TAG
364             if (g_callbackExt != nullptr) {
365                 g_callbackExt->OnSuspendWithTag(g_suspendTag);
366             }
367 #endif
368             break;
369         }
370         case CMD_ON_WAKEUP: {
371             if (g_callback != nullptr) {
372                 g_callback->OnWakeup();
373             }
374 #ifdef DRIVER_PERIPHERAL_POWER_SUSPEND_WITH_TAG
375             if (g_callbackExt != nullptr) {
376                 g_callbackExt->OnWakeupWithTag(g_wakeupTag);
377             }
378 #endif
379             break;
380         }
381         default:
382             break;
383     }
384 }
385 
StopSuspend()386 int32_t PowerInterfaceImpl::StopSuspend()
387 {
388     HDF_LOGI("stpS3");
389     g_suspendRetry = false;
390     g_powerState = PowerHdfState::AWAKE;
391     return HDF_SUCCESS;
392 }
393 
ForceSuspend()394 int32_t PowerInterfaceImpl::ForceSuspend()
395 {
396     //force suspend changed into active suspend
397     HDF_LOGI("active suspend");
398     StartSuspend();
399     return HDF_SUCCESS;
400 }
401 
Hibernate()402 int32_t PowerInterfaceImpl::Hibernate()
403 {
404 #ifdef DRIVERS_PERIPHERAL_POWER_ENABLE_S4
405     HDF_LOGI("hibernate begin.");
406     return Hibernate::GetInstance().DoHibernate();
407 #else
408     HDF_LOGI("hdf hibernate interface not supported.");
409     return HDF_FAILURE;
410 #endif
411 }
412 
SuspendBlock(const std::string & name)413 int32_t PowerInterfaceImpl::SuspendBlock(const std::string &name)
414 {
415     std::lock_guard<std::mutex> lock(g_mutex);
416     if (name.empty()) {
417         return HDF_ERR_INVALID_PARAM;
418     }
419     UniqueFd fd(TEMP_FAILURE_RETRY(open(LOCK_PATH, O_RDWR | O_CLOEXEC)));
420     bool ret = SaveStringToFd(fd, name);
421     if (!ret) {
422         return HDF_FAILURE;
423     }
424     return HDF_SUCCESS;
425 }
426 
SuspendUnblock(const std::string & name)427 int32_t PowerInterfaceImpl::SuspendUnblock(const std::string &name)
428 {
429     std::lock_guard<std::mutex> lock(g_mutex);
430     if (name.empty()) {
431         return HDF_ERR_INVALID_PARAM;
432     }
433     UniqueFd fd(TEMP_FAILURE_RETRY(open(UNLOCK_PATH, O_RDWR | O_CLOEXEC)));
434     bool ret = SaveStringToFd(fd, name);
435     if (!ret) {
436         return HDF_FAILURE;
437     }
438     return HDF_SUCCESS;
439 }
440 
AddPowerDeathRecipient(const sptr<IRemoteObject> & remote,const sptr<IRemoteObject::DeathRecipient> & recipient)441 int32_t PowerInterfaceImpl::AddPowerDeathRecipient(
442     const sptr<IRemoteObject>& remote, const sptr<IRemoteObject::DeathRecipient>& recipient)
443 {
444     if (remote == nullptr) {
445         return HDF_FAILURE;
446     }
447     HDF_LOGI("AddPowerDeathRecipient");
448     bool result = remote->AddDeathRecipient(recipient);
449     if (!result) {
450         HDF_LOGI("AddPowerDeathRecipient fail");
451         return HDF_FAILURE;
452     }
453     return HDF_SUCCESS;
454 }
455 
RemovePowerDeathRecipient(const sptr<IRemoteObject> & remote,const sptr<IRemoteObject::DeathRecipient> & recipient)456 int32_t PowerInterfaceImpl::RemovePowerDeathRecipient(
457     const sptr<IRemoteObject>& remote, const sptr<IRemoteObject::DeathRecipient>& recipient)
458 {
459     if (remote == nullptr) {
460         return HDF_FAILURE;
461     }
462     HDF_LOGI("RemovePowerDeathRecipient");
463     bool result = remote->RemoveDeathRecipient(recipient);
464     if (!result) {
465         HDF_LOGI("RemovePowerDeathRecipient fail");
466         return HDF_FAILURE;
467     }
468     return HDF_SUCCESS;
469 }
470 
OnRemoteDied(const wptr<IRemoteObject> & object)471 void PowerInterfaceImpl::PowerDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &object)
472 {
473     HDF_LOGI("PowerDeathRecipient OnRemoteDied");
474     powerInterfaceImpl_->UnRegister();
475     RunningLockImpl::Clean();
476 }
477 
LoadStringFd(int32_t fd,std::string & content)478 void LoadStringFd(int32_t fd, std::string &content)
479 {
480     if (fd <= 0) {
481         HDF_LOGW("invalid fd: %{public}d", fd);
482         return;
483     }
484 
485     const int32_t fileLength = lseek(fd, 0, SEEK_END);
486     if (fileLength > MAX_FILE_LENGTH || fileLength <= 0) {
487         HDF_LOGW("invalid file length(%{public}d)!", fileLength);
488         return;
489     }
490     int32_t loc = lseek(fd, 0, SEEK_SET);
491     if (loc == -1) {
492         HDF_LOGE("lseek file to begin failed!");
493         return;
494     }
495     content.resize(fileLength);
496     const int32_t len = static_cast<int32_t>(read(fd, content.data(), fileLength));
497     if (len <= 0) {
498         HDF_LOGW("the length read from file is failed, len: %{public}d, fileLen: %{public}d", len, fileLength);
499         content.clear();
500     }
501 }
502 
ReadWakeCount()503 std::string ReadWakeCount()
504 {
505     if (wakeupCountFd < 0) {
506         wakeupCountFd = UniqueFd(TEMP_FAILURE_RETRY(open(WAKEUP_COUNT_PATH, O_RDWR | O_CLOEXEC)));
507     }
508     std::string wakeupCount;
509     LoadStringFd(wakeupCountFd, wakeupCount);
510 
511     return wakeupCount;
512 }
513 
WriteWakeCount(const std::string & count)514 bool WriteWakeCount(const std::string &count)
515 {
516     if (wakeupCountFd < 0) {
517         wakeupCountFd = UniqueFd(TEMP_FAILURE_RETRY(open(WAKEUP_COUNT_PATH, O_RDWR | O_CLOEXEC)));
518     }
519     bool ret = SaveStringToFd(wakeupCountFd, count.c_str());
520     return ret;
521 }
522 
LoadSystemInfo(const std::string & path,std::string & info)523 static void LoadSystemInfo(const std::string &path, std::string &info)
524 {
525     UniqueFd fd(TEMP_FAILURE_RETRY(open(path.c_str(), O_RDWR | O_CLOEXEC)));
526     std::string str;
527     if (fd >= 0) {
528         bool ret = LoadStringFromFd(fd, str);
529         if (!ret) {
530             str = "# Failed to read";
531         }
532     } else {
533         str = "# Failed to open";
534     }
535     info.append(path);
536     info.append(": " + str + "\n");
537 }
538 
PowerDump(std::string & info)539 int32_t PowerInterfaceImpl::PowerDump(std::string &info)
540 {
541     std::string dumpInfo("");
542     LoadSystemInfo(SUSPEND_STATE_PATH, dumpInfo);
543     LoadSystemInfo(LOCK_PATH, dumpInfo);
544     LoadSystemInfo(UNLOCK_PATH, dumpInfo);
545     info = dumpInfo;
546 
547     return HDF_SUCCESS;
548 }
549 
HoldRunningLock(const RunningLockInfo & info)550 int32_t PowerInterfaceImpl::HoldRunningLock(const RunningLockInfo &info)
551 {
552     Power::PowerXCollie powerXcollie("Power_HoldRunningLock");
553     return RunningLockImpl::Hold(info, g_powerState);
554 }
555 
UnholdRunningLock(const RunningLockInfo & info)556 int32_t PowerInterfaceImpl::UnholdRunningLock(const RunningLockInfo &info)
557 {
558     Power::PowerXCollie powerXcollie("Power_UnholdRunningLock");
559     return RunningLockImpl::Unhold(info);
560 }
561 
HoldRunningLockExt(const RunningLockInfo & info,uint64_t lockid,const std::string & bundleName)562 int32_t PowerInterfaceImpl::HoldRunningLockExt(const RunningLockInfo &info,
563     uint64_t lockid, const std::string &bundleName)
564 {
565     // Background runningLock active
566     HDF_LOGI("BL active,T=%{public}d", info.type);
567     Power::PowerXCollie powerXcollie("Power_HoldRunningLockExt");
568     return RunningLockImpl::HoldLock(info, g_powerState, lockid, bundleName);
569 }
570 
UnholdRunningLockExt(const RunningLockInfo & info,uint64_t lockid,const std::string & bundleName)571 int32_t PowerInterfaceImpl::UnholdRunningLockExt(const RunningLockInfo &info,
572     uint64_t lockid, const std::string &bundleName)
573 {
574     // Background runningLock inactive
575     HDF_LOGI("BL inactive,T=%{public}d", info.type);
576     Power::PowerXCollie powerXcollie("Power_UnholdRunningLockExt");
577     return RunningLockImpl::UnholdLock(info, lockid, bundleName);
578 }
579 
GetWakeupReason(std::string & reason)580 int32_t PowerInterfaceImpl::GetWakeupReason(std::string &reason)
581 {
582 #ifdef DRIVER_PERIPHERAL_POWER_WAKEUP_CAUSE_PATH
583     return GetPowerConfig("wakeuo_cause", reason);
584 #else
585     HDF_LOGW("wakrup cause path not config");
586     return HDF_FAILURE;
587 #endif
588 }
589 
SetPowerConfig(const std::string & sceneName,const std::string & value)590 int32_t PowerInterfaceImpl::SetPowerConfig(const std::string &sceneName, const std::string &value)
591 {
592     auto& powerConfig = PowerConfig::GetInstance();
593     std::map<std::string, PowerConfig::PowerSceneConfig> sceneConfigMap = powerConfig.GetPowerSceneConfigMap();
594     if (sceneConfigMap.empty()) {
595         HDF_LOGE("SetPowerConfig sceneConfigMap is empty");
596         return HDF_ERR_NOT_SUPPORT;
597     }
598 
599     std::map<std::string, PowerConfig::PowerSceneConfig>::iterator it = sceneConfigMap.find(sceneName);
600     if (it == sceneConfigMap.end()) {
601         HDF_LOGE("SetPowerConfig sceneName: %{public}s does not exist", sceneName.c_str());
602         return HDF_FAILURE;
603     }
604     std::string setPath = (it->second).setPath;
605     HDF_LOGI("SetPowerConfig setPath = %{public}s", setPath.c_str());
606 
607     UniqueFd setValueFd = UniqueFd(TEMP_FAILURE_RETRY(open(setPath.c_str(), O_RDWR | O_CLOEXEC)));
608     if (setValueFd < 0) {
609         HDF_LOGE("SetPowerConfig open failed");
610         return HDF_FAILURE;
611     }
612     bool ret = SaveStringToFd(setValueFd, value);
613     if (!ret) {
614         HDF_LOGE("SetPowerConfig SaveStringToFd failed");
615         return HDF_FAILURE;
616     }
617     return HDF_SUCCESS;
618 }
619 
GetPowerConfig(const std::string & sceneName,std::string & value)620 int32_t PowerInterfaceImpl::GetPowerConfig(const std::string &sceneName, std::string &value)
621 {
622     auto& powerConfig = PowerConfig::GetInstance();
623     std::map<std::string, PowerConfig::PowerSceneConfig> sceneConfigMap = powerConfig.GetPowerSceneConfigMap();
624     if (sceneConfigMap.empty()) {
625         HDF_LOGE("GetPowerConfig sceneConfigMap is empty");
626         return HDF_ERR_NOT_SUPPORT;
627     }
628 
629     std::map<std::string, PowerConfig::PowerSceneConfig>::iterator it = sceneConfigMap.find(sceneName);
630     if (it == sceneConfigMap.end()) {
631         HDF_LOGE("GetPowerConfig sceneName: %{public}s does not exist", sceneName.c_str());
632         return HDF_FAILURE;
633     }
634     std::string getPath = (it->second).getPath;
635     HDF_LOGI("GetPowerConfig getPath = %{public}s", getPath.c_str());
636 
637     UniqueFd getValueFd = UniqueFd(TEMP_FAILURE_RETRY(open(getPath.c_str(), O_RDONLY | O_CLOEXEC)));
638     if (getValueFd < 0) {
639         HDF_LOGE("GetPowerConfig open failed");
640         return HDF_FAILURE;
641     }
642     LoadStringFd(getValueFd, value);
643     return HDF_SUCCESS;
644 }
645 } // namespace V1_3
646 } // namespace Power
647 } // namespace HDI
648 } // namespace OHOS
649