1/*
2 * Copyright (c) 2021-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_mgr_client.h"
17
18#include <cinttypes>
19#include <mutex>
20#include <memory>
21#include <unistd.h>
22#include <vector>
23#include <datetime_ex.h>
24#include <thread>
25#include <chrono>
26#include <if_system_ability_manager.h>
27#include <iservice_registry.h>
28#include <system_ability_definition.h>
29#include "new"
30#include "refbase.h"
31#include "ipower_mgr.h"
32#include "ipower_mode_callback.h"
33#include "ipower_state_callback.h"
34#include "ipower_runninglock_callback.h"
35#include "iremote_broker.h"
36#include "iremote_object.h"
37#include "iscreen_off_pre_callback.h"
38#include "power_log.h"
39#include "power_common.h"
40#include "running_lock_info.h"
41
42namespace OHOS {
43namespace PowerMgr {
44std::vector<std::weak_ptr<RunningLock>> PowerMgrClient::runningLocks_;
45std::mutex PowerMgrClient::runningLocksMutex_;
46std::mutex g_instanceMutex;
47
48PowerMgrClient::PowerMgrClient()
49{
50    token_ = sptr<IPCObjectStub>::MakeSptr(u"ohos.powermgr.ClientAlivenessToken");
51}
52
53PowerMgrClient::~PowerMgrClient()
54{
55    if (proxy_ != nullptr) {
56        auto remoteObject = proxy_->AsObject();
57        if (remoteObject != nullptr) {
58            remoteObject->RemoveDeathRecipient(deathRecipient_);
59        }
60    }
61}
62
63PowerMgrClient& PowerMgrClient::GetInstance()
64{
65    static PowerMgrClient* instance = nullptr;
66    if (instance == nullptr) {
67        std::lock_guard<std::mutex> lock(g_instanceMutex);
68        if (instance == nullptr) {
69            instance = new PowerMgrClient();
70        }
71    }
72    return *instance;
73}
74
75ErrCode PowerMgrClient::Connect()
76{
77    std::lock_guard<std::mutex> lock(mutex_);
78    if (proxy_ != nullptr) {
79        return ERR_OK;
80    }
81
82    sptr<ISystemAbilityManager> sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
83    if (sam == nullptr) {
84        POWER_HILOGE(COMP_FWK, "Failed to obtain SystemAbilityMgr");
85        return E_GET_SYSTEM_ABILITY_MANAGER_FAILED;
86    }
87    sptr<IRemoteObject> remoteObject_ = sam->CheckSystemAbility(POWER_MANAGER_SERVICE_ID);
88    if (remoteObject_ == nullptr) {
89        POWER_HILOGE(COMP_FWK, "Check SystemAbility failed");
90        return E_GET_POWER_SERVICE_FAILED;
91    }
92
93    sptr<IRemoteObject::DeathRecipient> drt = new(std::nothrow) PowerMgrDeathRecipient(*this);
94    if (drt == nullptr) {
95        POWER_HILOGE(COMP_FWK, "Failed to create PowerMgrDeathRecipient");
96        return ERR_NO_MEMORY;
97    }
98    if ((remoteObject_->IsProxyObject()) && (!remoteObject_->AddDeathRecipient(drt))) {
99        POWER_HILOGE(COMP_FWK, "Add death recipient to PowerMgr service failed");
100        return E_ADD_DEATH_RECIPIENT_FAILED;
101    }
102
103    proxy_ = iface_cast<IPowerMgr>(remoteObject_);
104    deathRecipient_ = drt;
105    POWER_HILOGI(COMP_FWK, "Connecting PowerMgrService success, pid=%{public}d", getpid());
106    return ERR_OK;
107}
108
109void PowerMgrClient::PowerMgrDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
110{
111    POWER_HILOGW(COMP_FWK, "Recv death notice, PowerMgr Death");
112    client_.ResetProxy(remote);
113
114    // wait for powermgr service restart
115    ErrCode ret = E_GET_POWER_SERVICE_FAILED;
116    uint32_t retryCount = 0;
117    while (++retryCount <= CONNECT_RETRY_COUNT) {
118        usleep(CONNECT_RETRY_MS);
119        ret = client_.Connect();
120        if (ret == ERR_OK) {
121            POWER_HILOGI(COMP_FWK, "retry connect success, count %{public}d", retryCount);
122            break;
123        }
124        POWER_HILOGI(COMP_FWK, "retry connect failed, count %{public}d", retryCount);
125    }
126    if (ret != ERR_OK) {
127        return;
128    }
129
130    // recover running lock info
131    client_.RecoverRunningLocks();
132}
133
134void PowerMgrClient::RecoverRunningLocks()
135{
136    POWER_HILOGI(COMP_FWK, "start to recover running locks");
137    std::lock_guard<std::mutex> lock(runningLocksMutex_);
138    for (auto runningLock : runningLocks_) {
139        if (runningLock.expired()) {
140            continue;
141        }
142        std::shared_ptr<RunningLock> lock = runningLock.lock();
143        if (lock != nullptr) {
144            lock->Recover(proxy_);
145        }
146    }
147}
148
149void PowerMgrClient::ResetProxy(const wptr<IRemoteObject>& remote)
150{
151    if (remote == nullptr) {
152        POWER_HILOGE(COMP_FWK, "OnRemoteDied failed, remote is nullptr");
153        return;
154    }
155
156    std::lock_guard<std::mutex> lock(mutex_);
157    RETURN_IF(proxy_ == nullptr);
158
159    auto serviceRemote = proxy_->AsObject();
160    if ((serviceRemote != nullptr) && (serviceRemote == remote.promote())) {
161        serviceRemote->RemoveDeathRecipient(deathRecipient_);
162        proxy_ = nullptr;
163    }
164}
165
166PowerErrors PowerMgrClient::RebootDevice(const std::string& reason)
167{
168    RETURN_IF_WITH_RET(Connect() != ERR_OK, PowerErrors::ERR_CONNECTION_FAIL);
169    return proxy_->RebootDevice(reason);
170}
171
172PowerErrors PowerMgrClient::RebootDeviceForDeprecated(const std::string& reason)
173{
174    RETURN_IF_WITH_RET(Connect() != ERR_OK, PowerErrors::ERR_CONNECTION_FAIL);
175    return proxy_->RebootDeviceForDeprecated(reason);
176}
177
178PowerErrors PowerMgrClient::ShutDownDevice(const std::string& reason)
179{
180    RETURN_IF_WITH_RET(Connect() != ERR_OK, PowerErrors::ERR_CONNECTION_FAIL);
181    return proxy_->ShutDownDevice(reason);
182}
183
184PowerErrors PowerMgrClient::SetSuspendTag(const std::string &tag)
185{
186    RETURN_IF_WITH_RET(Connect() != ERR_OK, PowerErrors::ERR_CONNECTION_FAIL);
187    POWER_HILOGI(FEATURE_SUSPEND, "Set suspend tag: %{public}s", tag.c_str());
188    return proxy_->SetSuspendTag(tag);
189}
190
191PowerErrors PowerMgrClient::SuspendDevice(SuspendDeviceType reason, bool suspendImmed)
192{
193    RETURN_IF_WITH_RET(Connect() != ERR_OK, PowerErrors::ERR_CONNECTION_FAIL);
194    POWER_HILOGD(FEATURE_SUSPEND, " Calling SuspendDevice success");
195    return proxy_->SuspendDevice(GetTickCount(), reason, suspendImmed);
196}
197
198PowerErrors PowerMgrClient::WakeupDevice(WakeupDeviceType reason, const std::string& detail)
199{
200    RETURN_IF_WITH_RET(Connect() != ERR_OK, PowerErrors::ERR_CONNECTION_FAIL);
201    POWER_HILOGD(FEATURE_WAKEUP, " Calling WakeupDevice success");
202    return proxy_->WakeupDevice(GetTickCount(), reason, detail);
203}
204
205void PowerMgrClient::WakeupDeviceAsync(WakeupDeviceType reason, const std::string& detail)
206{
207    RETURN_IF(Connect() != ERR_OK);
208    POWER_HILOGD(FEATURE_WAKEUP, " Calling WakeupDeviceAsync success");
209    return proxy_->WakeupDeviceAsync(GetTickCount(), reason, detail);
210}
211
212bool PowerMgrClient::RefreshActivity(UserActivityType type)
213{
214    RETURN_IF_WITH_RET(Connect() != ERR_OK, false);
215    bool ret = proxy_->RefreshActivity(GetTickCount(), type, true);
216    POWER_HILOGD(FEATURE_ACTIVITY, "Calling RefreshActivity Success");
217    return ret;
218}
219
220PowerErrors PowerMgrClient::OverrideScreenOffTime(int64_t timeout)
221{
222    if (timeout <= 0) {
223        POWER_HILOGW(COMP_FWK, "Invalid timeout, timeout=%{public}" PRId64 "", timeout);
224        return PowerErrors::ERR_PARAM_INVALID;
225    }
226    RETURN_IF_WITH_RET(Connect() != ERR_OK, PowerErrors::ERR_CONNECTION_FAIL);
227    PowerErrors ret = proxy_->OverrideScreenOffTime(timeout);
228    POWER_HILOGD(COMP_FWK, "Calling OverrideScreenOffTime Success");
229    return ret;
230}
231
232PowerErrors PowerMgrClient::RestoreScreenOffTime()
233{
234    RETURN_IF_WITH_RET(Connect() != ERR_OK, PowerErrors::ERR_CONNECTION_FAIL);
235    PowerErrors ret = proxy_->RestoreScreenOffTime();
236    POWER_HILOGD(COMP_FWK, "Calling RestoreScreenOffTime Success");
237    return ret;
238}
239
240bool PowerMgrClient::IsRunningLockTypeSupported(RunningLockType type)
241{
242    POWER_HILOGD(FEATURE_RUNNING_LOCK, "RunningLockType=%{public}u", type);
243    RETURN_IF_WITH_RET(Connect() != ERR_OK, false);
244    return proxy_->IsRunningLockTypeSupported(type);
245}
246
247PowerErrors PowerMgrClient::ForceSuspendDevice()
248{
249    RETURN_IF_WITH_RET(Connect() != ERR_OK, PowerErrors::ERR_CONNECTION_FAIL);
250    PowerErrors ret = proxy_->ForceSuspendDevice(GetTickCount());
251    POWER_HILOGD(FEATURE_SUSPEND, "Calling ForceSuspendDevice Success");
252    return ret;
253}
254
255bool PowerMgrClient::IsScreenOn(bool needPrintLog)
256{
257    RETURN_IF_WITH_RET(Connect() != ERR_OK, false);
258    bool ret = false;
259    ret = proxy_->IsScreenOn(needPrintLog);
260    if (needPrintLog) {
261        POWER_HILOGI(COMP_FWK, "IsScreenOn=%{public}d, caller pid=%{public}d", ret, getpid());
262    } else {
263        POWER_HILOGD(COMP_FWK, "IsScreenOn=%{public}d, caller pid=%{public}d", ret, getpid());
264    }
265    return ret;
266}
267
268bool PowerMgrClient::IsFoldScreenOn()
269{
270    RETURN_IF_WITH_RET(Connect() != ERR_OK, false);
271    bool ret = false;
272    ret = proxy_->IsFoldScreenOn();
273    POWER_HILOGI(COMP_FWK, "IsFoldScreenOn=%{public}d, caller pid=%{public}d", ret, getpid());
274    return ret;
275}
276
277bool PowerMgrClient::IsCollaborationScreenOn()
278{
279    RETURN_IF_WITH_RET(Connect() != ERR_OK, false);
280    bool ret = false;
281    ret = proxy_->IsCollaborationScreenOn();
282    POWER_HILOGI(COMP_FWK, "IsCollaborationScreenOn=%{public}d, caller pid=%{public}d", ret, getpid());
283    return ret;
284}
285
286PowerState PowerMgrClient::GetState()
287{
288    RETURN_IF_WITH_RET(Connect() != ERR_OK, PowerState::UNKNOWN);
289    return proxy_->GetState();
290}
291
292std::shared_ptr<RunningLock> PowerMgrClient::CreateRunningLock(const std::string& name, RunningLockType type)
293{
294    RETURN_IF_WITH_RET(Connect() != ERR_OK, nullptr);
295
296    uint32_t nameLen = (name.size() > RunningLock::MAX_NAME_LEN) ? RunningLock::MAX_NAME_LEN : name.size();
297    std::string nameExt = name.substr(0, nameLen) + "_" + std::to_string(GetTickCount());
298    std::shared_ptr<RunningLock> runningLock = std::make_shared<RunningLock>(proxy_, nameExt, type);
299    if (runningLock == nullptr) {
300        POWER_HILOGE(FEATURE_RUNNING_LOCK, "Failed to create RunningLock record");
301        return nullptr;
302    }
303    POWER_HILOGI(
304        FEATURE_RUNNING_LOCK, "Client CreateRunningLock name: %{public}s, type = %{public}d", name.c_str(), type);
305    auto error = runningLock->Init();
306    if (error != PowerErrors::ERR_OK) {
307        POWER_HILOGE(FEATURE_RUNNING_LOCK, "RunningLock init failed");
308        error_ = error;
309        return nullptr;
310    }
311
312    std::lock_guard<std::mutex> lock(runningLocksMutex_);
313    runningLocks_.push_back(std::weak_ptr<RunningLock>(runningLock));
314    return runningLock;
315}
316
317bool PowerMgrClient::ProxyRunningLock(bool isProxied, pid_t pid, pid_t uid)
318{
319    RETURN_IF_WITH_RET(Connect() != ERR_OK, false);
320    return proxy_->ProxyRunningLock(isProxied, pid, uid);
321}
322
323bool PowerMgrClient::ProxyRunningLocks(bool isProxied, const std::vector<std::pair<pid_t, pid_t>>& processInfos)
324{
325    RETURN_IF_WITH_RET(Connect() != ERR_OK, false);
326    return proxy_->ProxyRunningLocks(isProxied, processInfos);
327}
328
329bool PowerMgrClient::ResetRunningLocks()
330{
331    RETURN_IF_WITH_RET(Connect() != ERR_OK, false);
332    return proxy_->ResetRunningLocks();
333}
334
335bool PowerMgrClient::RegisterPowerStateCallback(const sptr<IPowerStateCallback>& callback, bool isSync)
336{
337    RETURN_IF_WITH_RET((callback == nullptr) || (Connect() != ERR_OK), false);
338    bool ret = proxy_->RegisterPowerStateCallback(callback, isSync);
339    return ret;
340}
341
342bool PowerMgrClient::UnRegisterPowerStateCallback(const sptr<IPowerStateCallback>& callback)
343{
344    RETURN_IF_WITH_RET((callback == nullptr) || (Connect() != ERR_OK), false);
345    bool ret = proxy_->UnRegisterPowerStateCallback(callback);
346    return ret;
347}
348
349bool PowerMgrClient::RegisterSyncSleepCallback(const sptr<ISyncSleepCallback>& callback, SleepPriority priority)
350{
351    RETURN_IF_WITH_RET((callback == nullptr) || (Connect() != ERR_OK), false);
352    bool ret = proxy_->RegisterSyncSleepCallback(callback, priority);
353    return ret;
354}
355
356bool PowerMgrClient::UnRegisterSyncSleepCallback(const sptr<ISyncSleepCallback>& callback)
357{
358    RETURN_IF_WITH_RET((callback == nullptr) || (Connect() != ERR_OK), false);
359    bool ret = proxy_->UnRegisterSyncSleepCallback(callback);
360    return ret;
361}
362
363bool PowerMgrClient::RegisterSyncHibernateCallback(const sptr<ISyncHibernateCallback>& callback)
364{
365    RETURN_IF_WITH_RET((callback == nullptr) || (Connect() != ERR_OK), false);
366    bool ret = proxy_->RegisterSyncHibernateCallback(callback);
367    return ret;
368}
369
370bool PowerMgrClient::UnRegisterSyncHibernateCallback(const sptr<ISyncHibernateCallback>& callback)
371{
372    RETURN_IF_WITH_RET((callback == nullptr) || (Connect() != ERR_OK), false);
373    bool ret = proxy_->UnRegisterSyncHibernateCallback(callback);
374    return ret;
375}
376
377bool PowerMgrClient::RegisterPowerModeCallback(const sptr<IPowerModeCallback>& callback)
378{
379    RETURN_IF_WITH_RET((callback == nullptr) || (Connect() != ERR_OK), false);
380    bool ret = proxy_->RegisterPowerModeCallback(callback);
381    return ret;
382}
383
384bool PowerMgrClient::UnRegisterPowerModeCallback(const sptr<IPowerModeCallback>& callback)
385{
386    RETURN_IF_WITH_RET((callback == nullptr) || (Connect() != ERR_OK), false);
387    bool ret = proxy_->UnRegisterPowerModeCallback(callback);
388    return ret;
389}
390
391bool PowerMgrClient::RegisterScreenStateCallback(int32_t remainTime, const sptr<IScreenOffPreCallback>& callback)
392{
393    RETURN_IF_WITH_RET((remainTime <= 0) || (callback == nullptr) || (Connect() != ERR_OK), false);
394    POWER_HILOGI(FEATURE_SCREEN_OFF_PRE, "Register screen off pre Callback by client");
395    bool ret = proxy_->RegisterScreenStateCallback(remainTime, callback);
396    return ret;
397}
398
399bool PowerMgrClient::UnRegisterScreenStateCallback(const sptr<IScreenOffPreCallback>& callback)
400{
401    RETURN_IF_WITH_RET((callback == nullptr) || (Connect() != ERR_OK), false);
402    POWER_HILOGI(FEATURE_SCREEN_OFF_PRE, "Unregister screen off pre Callback by client");
403    bool ret = proxy_->UnRegisterScreenStateCallback(callback);
404    return ret;
405}
406
407bool PowerMgrClient::RegisterRunningLockCallback(const sptr<IPowerRunninglockCallback>& callback)
408{
409    RETURN_IF_WITH_RET((callback == nullptr) || (Connect() != ERR_OK), false);
410    POWER_HILOGI(FEATURE_RUNNING_LOCK, "Register running lock Callback by client");
411    bool ret = proxy_->RegisterRunningLockCallback(callback);
412    return ret;
413}
414
415bool PowerMgrClient::UnRegisterRunningLockCallback(const sptr<IPowerRunninglockCallback>& callback)
416{
417    RETURN_IF_WITH_RET((callback == nullptr) || (Connect() != ERR_OK), false);
418    POWER_HILOGI(FEATURE_RUNNING_LOCK, "Unregister running lock Callback by client");
419    bool ret = proxy_->UnRegisterRunningLockCallback(callback);
420    return ret;
421}
422
423bool PowerMgrClient::SetDisplaySuspend(bool enable)
424{
425    RETURN_IF_WITH_RET(Connect() != ERR_OK, false);
426    bool ret = proxy_->SetDisplaySuspend(enable);
427    return ret;
428}
429
430PowerErrors PowerMgrClient::Hibernate(bool clearMemory)
431{
432    RETURN_IF_WITH_RET(Connect() != ERR_OK, PowerErrors::ERR_CONNECTION_FAIL);
433    return proxy_->Hibernate(clearMemory);
434}
435
436PowerErrors PowerMgrClient::SetDeviceMode(const PowerMode mode)
437{
438    RETURN_IF_WITH_RET(Connect() != ERR_OK, PowerErrors::ERR_CONNECTION_FAIL);
439    return proxy_->SetDeviceMode(mode);
440}
441
442PowerMode PowerMgrClient::GetDeviceMode()
443{
444    RETURN_IF_WITH_RET(Connect() != ERR_OK, static_cast<PowerMode>(0));
445    return static_cast<PowerMode>(proxy_->GetDeviceMode());
446}
447
448std::string PowerMgrClient::Dump(const std::vector<std::string>& args)
449{
450    std::string error = "can't connect service";
451    RETURN_IF_WITH_RET(Connect() != ERR_OK, error);
452    return proxy_->ShellDump(args, args.size());
453}
454
455PowerErrors PowerMgrClient::GetError()
456{
457    auto temp = error_;
458    error_ = PowerErrors::ERR_OK;
459    return temp;
460}
461
462PowerErrors PowerMgrClient::IsStandby(bool& isStandby)
463{
464    RETURN_IF_WITH_RET(Connect() != ERR_OK, PowerErrors::ERR_CONNECTION_FAIL);
465    PowerErrors ret = proxy_->IsStandby(isStandby);
466    return ret;
467}
468
469bool PowerMgrClient::QueryRunningLockLists(std::map<std::string, RunningLockInfo>& runningLockLists)
470{
471    RETURN_IF_WITH_RET(Connect() != ERR_OK, false);
472    POWER_HILOGD(FEATURE_RUNNING_LOCK, "Query running lock lists by client");
473    return proxy_->QueryRunningLockLists(runningLockLists);
474}
475
476PowerErrors PowerMgrClient::SetForceTimingOut(bool enabled)
477{
478    RETURN_IF_WITH_RET(Connect() != ERR_OK, PowerErrors::ERR_CONNECTION_FAIL);
479    PowerErrors ret = proxy_->SetForceTimingOut(enabled, token_);
480    return ret;
481}
482
483PowerErrors PowerMgrClient::LockScreenAfterTimingOut(bool enabledLockScreen, bool checkLock, bool sendScreenOffEvent)
484{
485    RETURN_IF_WITH_RET(Connect() != ERR_OK, PowerErrors::ERR_CONNECTION_FAIL);
486    PowerErrors ret = proxy_->LockScreenAfterTimingOut(enabledLockScreen, checkLock, sendScreenOffEvent, token_);
487    return ret;
488}
489
490} // namespace PowerMgr
491} // namespace OHOS
492