/* * Copyright (c) 2021-2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "power_mgr_client.h" #include <cinttypes> #include <mutex> #include <memory> #include <unistd.h> #include <vector> #include <datetime_ex.h> #include <thread> #include <chrono> #include <if_system_ability_manager.h> #include <iservice_registry.h> #include <system_ability_definition.h> #include "new" #include "refbase.h" #include "ipower_mgr.h" #include "ipower_mode_callback.h" #include "ipower_state_callback.h" #include "ipower_runninglock_callback.h" #include "iremote_broker.h" #include "iremote_object.h" #include "iscreen_off_pre_callback.h" #include "power_log.h" #include "power_common.h" #include "running_lock_info.h" namespace OHOS { namespace PowerMgr { std::vector<std::weak_ptr<RunningLock>> PowerMgrClient::runningLocks_; std::mutex PowerMgrClient::runningLocksMutex_; std::mutex g_instanceMutex; PowerMgrClient::PowerMgrClient() { token_ = sptr<IPCObjectStub>::MakeSptr(u"ohos.powermgr.ClientAlivenessToken"); } PowerMgrClient::~PowerMgrClient() { if (proxy_ != nullptr) { auto remoteObject = proxy_->AsObject(); if (remoteObject != nullptr) { remoteObject->RemoveDeathRecipient(deathRecipient_); } } } PowerMgrClient& PowerMgrClient::GetInstance() { static PowerMgrClient* instance = nullptr; if (instance == nullptr) { std::lock_guard<std::mutex> lock(g_instanceMutex); if (instance == nullptr) { instance = new PowerMgrClient(); } } return *instance; } ErrCode PowerMgrClient::Connect() { std::lock_guard<std::mutex> lock(mutex_); if (proxy_ != nullptr) { return ERR_OK; } sptr<ISystemAbilityManager> sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); if (sam == nullptr) { POWER_HILOGE(COMP_FWK, "Failed to obtain SystemAbilityMgr"); return E_GET_SYSTEM_ABILITY_MANAGER_FAILED; } sptr<IRemoteObject> remoteObject_ = sam->CheckSystemAbility(POWER_MANAGER_SERVICE_ID); if (remoteObject_ == nullptr) { POWER_HILOGE(COMP_FWK, "Check SystemAbility failed"); return E_GET_POWER_SERVICE_FAILED; } sptr<IRemoteObject::DeathRecipient> drt = new(std::nothrow) PowerMgrDeathRecipient(*this); if (drt == nullptr) { POWER_HILOGE(COMP_FWK, "Failed to create PowerMgrDeathRecipient"); return ERR_NO_MEMORY; } if ((remoteObject_->IsProxyObject()) && (!remoteObject_->AddDeathRecipient(drt))) { POWER_HILOGE(COMP_FWK, "Add death recipient to PowerMgr service failed"); return E_ADD_DEATH_RECIPIENT_FAILED; } proxy_ = iface_cast<IPowerMgr>(remoteObject_); deathRecipient_ = drt; POWER_HILOGI(COMP_FWK, "Connecting PowerMgrService success, pid=%{public}d", getpid()); return ERR_OK; } void PowerMgrClient::PowerMgrDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote) { POWER_HILOGW(COMP_FWK, "Recv death notice, PowerMgr Death"); client_.ResetProxy(remote); // wait for powermgr service restart ErrCode ret = E_GET_POWER_SERVICE_FAILED; uint32_t retryCount = 0; while (++retryCount <= CONNECT_RETRY_COUNT) { usleep(CONNECT_RETRY_MS); ret = client_.Connect(); if (ret == ERR_OK) { POWER_HILOGI(COMP_FWK, "retry connect success, count %{public}d", retryCount); break; } POWER_HILOGI(COMP_FWK, "retry connect failed, count %{public}d", retryCount); } if (ret != ERR_OK) { return; } // recover running lock info client_.RecoverRunningLocks(); } void PowerMgrClient::RecoverRunningLocks() { POWER_HILOGI(COMP_FWK, "start to recover running locks"); std::lock_guard<std::mutex> lock(runningLocksMutex_); for (auto runningLock : runningLocks_) { if (runningLock.expired()) { continue; } std::shared_ptr<RunningLock> lock = runningLock.lock(); if (lock != nullptr) { lock->Recover(proxy_); } } } void PowerMgrClient::ResetProxy(const wptr<IRemoteObject>& remote) { if (remote == nullptr) { POWER_HILOGE(COMP_FWK, "OnRemoteDied failed, remote is nullptr"); return; } std::lock_guard<std::mutex> lock(mutex_); RETURN_IF(proxy_ == nullptr); auto serviceRemote = proxy_->AsObject(); if ((serviceRemote != nullptr) && (serviceRemote == remote.promote())) { serviceRemote->RemoveDeathRecipient(deathRecipient_); proxy_ = nullptr; } } PowerErrors PowerMgrClient::RebootDevice(const std::string& reason) { RETURN_IF_WITH_RET(Connect() != ERR_OK, PowerErrors::ERR_CONNECTION_FAIL); return proxy_->RebootDevice(reason); } PowerErrors PowerMgrClient::RebootDeviceForDeprecated(const std::string& reason) { RETURN_IF_WITH_RET(Connect() != ERR_OK, PowerErrors::ERR_CONNECTION_FAIL); return proxy_->RebootDeviceForDeprecated(reason); } PowerErrors PowerMgrClient::ShutDownDevice(const std::string& reason) { RETURN_IF_WITH_RET(Connect() != ERR_OK, PowerErrors::ERR_CONNECTION_FAIL); return proxy_->ShutDownDevice(reason); } PowerErrors PowerMgrClient::SetSuspendTag(const std::string &tag) { RETURN_IF_WITH_RET(Connect() != ERR_OK, PowerErrors::ERR_CONNECTION_FAIL); POWER_HILOGI(FEATURE_SUSPEND, "Set suspend tag: %{public}s", tag.c_str()); return proxy_->SetSuspendTag(tag); } PowerErrors PowerMgrClient::SuspendDevice(SuspendDeviceType reason, bool suspendImmed) { RETURN_IF_WITH_RET(Connect() != ERR_OK, PowerErrors::ERR_CONNECTION_FAIL); POWER_HILOGD(FEATURE_SUSPEND, " Calling SuspendDevice success"); return proxy_->SuspendDevice(GetTickCount(), reason, suspendImmed); } PowerErrors PowerMgrClient::WakeupDevice(WakeupDeviceType reason, const std::string& detail) { RETURN_IF_WITH_RET(Connect() != ERR_OK, PowerErrors::ERR_CONNECTION_FAIL); POWER_HILOGD(FEATURE_WAKEUP, " Calling WakeupDevice success"); return proxy_->WakeupDevice(GetTickCount(), reason, detail); } void PowerMgrClient::WakeupDeviceAsync(WakeupDeviceType reason, const std::string& detail) { RETURN_IF(Connect() != ERR_OK); POWER_HILOGD(FEATURE_WAKEUP, " Calling WakeupDeviceAsync success"); return proxy_->WakeupDeviceAsync(GetTickCount(), reason, detail); } bool PowerMgrClient::RefreshActivity(UserActivityType type) { RETURN_IF_WITH_RET(Connect() != ERR_OK, false); bool ret = proxy_->RefreshActivity(GetTickCount(), type, true); POWER_HILOGD(FEATURE_ACTIVITY, "Calling RefreshActivity Success"); return ret; } PowerErrors PowerMgrClient::OverrideScreenOffTime(int64_t timeout) { if (timeout <= 0) { POWER_HILOGW(COMP_FWK, "Invalid timeout, timeout=%{public}" PRId64 "", timeout); return PowerErrors::ERR_PARAM_INVALID; } RETURN_IF_WITH_RET(Connect() != ERR_OK, PowerErrors::ERR_CONNECTION_FAIL); PowerErrors ret = proxy_->OverrideScreenOffTime(timeout); POWER_HILOGD(COMP_FWK, "Calling OverrideScreenOffTime Success"); return ret; } PowerErrors PowerMgrClient::RestoreScreenOffTime() { RETURN_IF_WITH_RET(Connect() != ERR_OK, PowerErrors::ERR_CONNECTION_FAIL); PowerErrors ret = proxy_->RestoreScreenOffTime(); POWER_HILOGD(COMP_FWK, "Calling RestoreScreenOffTime Success"); return ret; } bool PowerMgrClient::IsRunningLockTypeSupported(RunningLockType type) { POWER_HILOGD(FEATURE_RUNNING_LOCK, "RunningLockType=%{public}u", type); RETURN_IF_WITH_RET(Connect() != ERR_OK, false); return proxy_->IsRunningLockTypeSupported(type); } PowerErrors PowerMgrClient::ForceSuspendDevice() { RETURN_IF_WITH_RET(Connect() != ERR_OK, PowerErrors::ERR_CONNECTION_FAIL); PowerErrors ret = proxy_->ForceSuspendDevice(GetTickCount()); POWER_HILOGD(FEATURE_SUSPEND, "Calling ForceSuspendDevice Success"); return ret; } bool PowerMgrClient::IsScreenOn(bool needPrintLog) { RETURN_IF_WITH_RET(Connect() != ERR_OK, false); bool ret = false; ret = proxy_->IsScreenOn(needPrintLog); if (needPrintLog) { POWER_HILOGI(COMP_FWK, "IsScreenOn=%{public}d, caller pid=%{public}d", ret, getpid()); } else { POWER_HILOGD(COMP_FWK, "IsScreenOn=%{public}d, caller pid=%{public}d", ret, getpid()); } return ret; } bool PowerMgrClient::IsFoldScreenOn() { RETURN_IF_WITH_RET(Connect() != ERR_OK, false); bool ret = false; ret = proxy_->IsFoldScreenOn(); POWER_HILOGI(COMP_FWK, "IsFoldScreenOn=%{public}d, caller pid=%{public}d", ret, getpid()); return ret; } bool PowerMgrClient::IsCollaborationScreenOn() { RETURN_IF_WITH_RET(Connect() != ERR_OK, false); bool ret = false; ret = proxy_->IsCollaborationScreenOn(); POWER_HILOGI(COMP_FWK, "IsCollaborationScreenOn=%{public}d, caller pid=%{public}d", ret, getpid()); return ret; } PowerState PowerMgrClient::GetState() { RETURN_IF_WITH_RET(Connect() != ERR_OK, PowerState::UNKNOWN); return proxy_->GetState(); } std::shared_ptr<RunningLock> PowerMgrClient::CreateRunningLock(const std::string& name, RunningLockType type) { RETURN_IF_WITH_RET(Connect() != ERR_OK, nullptr); uint32_t nameLen = (name.size() > RunningLock::MAX_NAME_LEN) ? RunningLock::MAX_NAME_LEN : name.size(); std::string nameExt = name.substr(0, nameLen) + "_" + std::to_string(GetTickCount()); std::shared_ptr<RunningLock> runningLock = std::make_shared<RunningLock>(proxy_, nameExt, type); if (runningLock == nullptr) { POWER_HILOGE(FEATURE_RUNNING_LOCK, "Failed to create RunningLock record"); return nullptr; } POWER_HILOGI( FEATURE_RUNNING_LOCK, "Client CreateRunningLock name: %{public}s, type = %{public}d", name.c_str(), type); auto error = runningLock->Init(); if (error != PowerErrors::ERR_OK) { POWER_HILOGE(FEATURE_RUNNING_LOCK, "RunningLock init failed"); error_ = error; return nullptr; } std::lock_guard<std::mutex> lock(runningLocksMutex_); runningLocks_.push_back(std::weak_ptr<RunningLock>(runningLock)); return runningLock; } bool PowerMgrClient::ProxyRunningLock(bool isProxied, pid_t pid, pid_t uid) { RETURN_IF_WITH_RET(Connect() != ERR_OK, false); return proxy_->ProxyRunningLock(isProxied, pid, uid); } bool PowerMgrClient::ProxyRunningLocks(bool isProxied, const std::vector<std::pair<pid_t, pid_t>>& processInfos) { RETURN_IF_WITH_RET(Connect() != ERR_OK, false); return proxy_->ProxyRunningLocks(isProxied, processInfos); } bool PowerMgrClient::ResetRunningLocks() { RETURN_IF_WITH_RET(Connect() != ERR_OK, false); return proxy_->ResetRunningLocks(); } bool PowerMgrClient::RegisterPowerStateCallback(const sptr<IPowerStateCallback>& callback, bool isSync) { RETURN_IF_WITH_RET((callback == nullptr) || (Connect() != ERR_OK), false); bool ret = proxy_->RegisterPowerStateCallback(callback, isSync); return ret; } bool PowerMgrClient::UnRegisterPowerStateCallback(const sptr<IPowerStateCallback>& callback) { RETURN_IF_WITH_RET((callback == nullptr) || (Connect() != ERR_OK), false); bool ret = proxy_->UnRegisterPowerStateCallback(callback); return ret; } bool PowerMgrClient::RegisterSyncSleepCallback(const sptr<ISyncSleepCallback>& callback, SleepPriority priority) { RETURN_IF_WITH_RET((callback == nullptr) || (Connect() != ERR_OK), false); bool ret = proxy_->RegisterSyncSleepCallback(callback, priority); return ret; } bool PowerMgrClient::UnRegisterSyncSleepCallback(const sptr<ISyncSleepCallback>& callback) { RETURN_IF_WITH_RET((callback == nullptr) || (Connect() != ERR_OK), false); bool ret = proxy_->UnRegisterSyncSleepCallback(callback); return ret; } bool PowerMgrClient::RegisterSyncHibernateCallback(const sptr<ISyncHibernateCallback>& callback) { RETURN_IF_WITH_RET((callback == nullptr) || (Connect() != ERR_OK), false); bool ret = proxy_->RegisterSyncHibernateCallback(callback); return ret; } bool PowerMgrClient::UnRegisterSyncHibernateCallback(const sptr<ISyncHibernateCallback>& callback) { RETURN_IF_WITH_RET((callback == nullptr) || (Connect() != ERR_OK), false); bool ret = proxy_->UnRegisterSyncHibernateCallback(callback); return ret; } bool PowerMgrClient::RegisterPowerModeCallback(const sptr<IPowerModeCallback>& callback) { RETURN_IF_WITH_RET((callback == nullptr) || (Connect() != ERR_OK), false); bool ret = proxy_->RegisterPowerModeCallback(callback); return ret; } bool PowerMgrClient::UnRegisterPowerModeCallback(const sptr<IPowerModeCallback>& callback) { RETURN_IF_WITH_RET((callback == nullptr) || (Connect() != ERR_OK), false); bool ret = proxy_->UnRegisterPowerModeCallback(callback); return ret; } bool PowerMgrClient::RegisterScreenStateCallback(int32_t remainTime, const sptr<IScreenOffPreCallback>& callback) { RETURN_IF_WITH_RET((remainTime <= 0) || (callback == nullptr) || (Connect() != ERR_OK), false); POWER_HILOGI(FEATURE_SCREEN_OFF_PRE, "Register screen off pre Callback by client"); bool ret = proxy_->RegisterScreenStateCallback(remainTime, callback); return ret; } bool PowerMgrClient::UnRegisterScreenStateCallback(const sptr<IScreenOffPreCallback>& callback) { RETURN_IF_WITH_RET((callback == nullptr) || (Connect() != ERR_OK), false); POWER_HILOGI(FEATURE_SCREEN_OFF_PRE, "Unregister screen off pre Callback by client"); bool ret = proxy_->UnRegisterScreenStateCallback(callback); return ret; } bool PowerMgrClient::RegisterRunningLockCallback(const sptr<IPowerRunninglockCallback>& callback) { RETURN_IF_WITH_RET((callback == nullptr) || (Connect() != ERR_OK), false); POWER_HILOGI(FEATURE_RUNNING_LOCK, "Register running lock Callback by client"); bool ret = proxy_->RegisterRunningLockCallback(callback); return ret; } bool PowerMgrClient::UnRegisterRunningLockCallback(const sptr<IPowerRunninglockCallback>& callback) { RETURN_IF_WITH_RET((callback == nullptr) || (Connect() != ERR_OK), false); POWER_HILOGI(FEATURE_RUNNING_LOCK, "Unregister running lock Callback by client"); bool ret = proxy_->UnRegisterRunningLockCallback(callback); return ret; } bool PowerMgrClient::SetDisplaySuspend(bool enable) { RETURN_IF_WITH_RET(Connect() != ERR_OK, false); bool ret = proxy_->SetDisplaySuspend(enable); return ret; } PowerErrors PowerMgrClient::Hibernate(bool clearMemory) { RETURN_IF_WITH_RET(Connect() != ERR_OK, PowerErrors::ERR_CONNECTION_FAIL); return proxy_->Hibernate(clearMemory); } PowerErrors PowerMgrClient::SetDeviceMode(const PowerMode mode) { RETURN_IF_WITH_RET(Connect() != ERR_OK, PowerErrors::ERR_CONNECTION_FAIL); return proxy_->SetDeviceMode(mode); } PowerMode PowerMgrClient::GetDeviceMode() { RETURN_IF_WITH_RET(Connect() != ERR_OK, static_cast<PowerMode>(0)); return static_cast<PowerMode>(proxy_->GetDeviceMode()); } std::string PowerMgrClient::Dump(const std::vector<std::string>& args) { std::string error = "can't connect service"; RETURN_IF_WITH_RET(Connect() != ERR_OK, error); return proxy_->ShellDump(args, args.size()); } PowerErrors PowerMgrClient::GetError() { auto temp = error_; error_ = PowerErrors::ERR_OK; return temp; } PowerErrors PowerMgrClient::IsStandby(bool& isStandby) { RETURN_IF_WITH_RET(Connect() != ERR_OK, PowerErrors::ERR_CONNECTION_FAIL); PowerErrors ret = proxy_->IsStandby(isStandby); return ret; } bool PowerMgrClient::QueryRunningLockLists(std::map<std::string, RunningLockInfo>& runningLockLists) { RETURN_IF_WITH_RET(Connect() != ERR_OK, false); POWER_HILOGD(FEATURE_RUNNING_LOCK, "Query running lock lists by client"); return proxy_->QueryRunningLockLists(runningLockLists); } PowerErrors PowerMgrClient::SetForceTimingOut(bool enabled) { RETURN_IF_WITH_RET(Connect() != ERR_OK, PowerErrors::ERR_CONNECTION_FAIL); PowerErrors ret = proxy_->SetForceTimingOut(enabled, token_); return ret; } PowerErrors PowerMgrClient::LockScreenAfterTimingOut(bool enabledLockScreen, bool checkLock, bool sendScreenOffEvent) { RETURN_IF_WITH_RET(Connect() != ERR_OK, PowerErrors::ERR_CONNECTION_FAIL); PowerErrors ret = proxy_->LockScreenAfterTimingOut(enabledLockScreen, checkLock, sendScreenOffEvent, token_); return ret; } } // namespace PowerMgr } // namespace OHOS