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