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, ¶m);
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