199552fe9Sopenharmony_ci/*
299552fe9Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
399552fe9Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
499552fe9Sopenharmony_ci * you may not use this file except in compliance with the License.
599552fe9Sopenharmony_ci * You may obtain a copy of the License at
699552fe9Sopenharmony_ci *
799552fe9Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
899552fe9Sopenharmony_ci *
999552fe9Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1099552fe9Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1199552fe9Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1299552fe9Sopenharmony_ci * See the License for the specific language governing permissions and
1399552fe9Sopenharmony_ci * limitations under the License.
1499552fe9Sopenharmony_ci */
1599552fe9Sopenharmony_ci
1699552fe9Sopenharmony_ci#include "standby_state_subscriber.h"
1799552fe9Sopenharmony_ci
1899552fe9Sopenharmony_ci#include "common_event_data.h"
1999552fe9Sopenharmony_ci#include "common_event_manager.h"
2099552fe9Sopenharmony_ci#include "common_event_support.h"
2199552fe9Sopenharmony_ci#include "want.h"
2299552fe9Sopenharmony_ci
2399552fe9Sopenharmony_ci#include "standby_messsage.h"
2499552fe9Sopenharmony_ci#include "standby_service_log.h"
2599552fe9Sopenharmony_ci#include "standby_state.h"
2699552fe9Sopenharmony_ci
2799552fe9Sopenharmony_cinamespace OHOS {
2899552fe9Sopenharmony_cinamespace DevStandbyMgr {
2999552fe9Sopenharmony_ciStandbyStateSubscriber::StandbyStateSubscriber()
3099552fe9Sopenharmony_ci{
3199552fe9Sopenharmony_ci    deathRecipient_ = new (std::nothrow) SubscriberDeathRecipient();
3299552fe9Sopenharmony_ci}
3399552fe9Sopenharmony_ci
3499552fe9Sopenharmony_ciStandbyStateSubscriber::~StandbyStateSubscriber() {}
3599552fe9Sopenharmony_ci
3699552fe9Sopenharmony_cistd::shared_ptr<StandbyStateSubscriber> StandbyStateSubscriber::GetInstance()
3799552fe9Sopenharmony_ci{
3899552fe9Sopenharmony_ci    return DelayedSingleton<StandbyStateSubscriber>::GetInstance();
3999552fe9Sopenharmony_ci}
4099552fe9Sopenharmony_ci
4199552fe9Sopenharmony_ciErrCode StandbyStateSubscriber::AddSubscriber(const sptr<IStandbyServiceSubscriber>& subscriber)
4299552fe9Sopenharmony_ci{
4399552fe9Sopenharmony_ci    STANDBYSERVICE_LOGD("StandbyStateSubscriber start subscriber");
4499552fe9Sopenharmony_ci    if (subscriber == NULL) {
4599552fe9Sopenharmony_ci        STANDBYSERVICE_LOGI("subscriber is null");
4699552fe9Sopenharmony_ci        return ERR_STANDBY_INVALID_PARAM;
4799552fe9Sopenharmony_ci    }
4899552fe9Sopenharmony_ci    auto remote = subscriber->AsObject();
4999552fe9Sopenharmony_ci    if (remote == nullptr) {
5099552fe9Sopenharmony_ci        STANDBYSERVICE_LOGE("remote in subscriber is null");
5199552fe9Sopenharmony_ci        return ERR_STANDBY_INVALID_PARAM;
5299552fe9Sopenharmony_ci    }
5399552fe9Sopenharmony_ci    std::lock_guard<std::mutex> subcriberLock(subscriberLock_);
5499552fe9Sopenharmony_ci    if (deathRecipient_ == nullptr) {
5599552fe9Sopenharmony_ci        STANDBYSERVICE_LOGW("create death recipient failed");
5699552fe9Sopenharmony_ci        return ERR_STANDBY_INVALID_PARAM;
5799552fe9Sopenharmony_ci    }
5899552fe9Sopenharmony_ci    auto subscriberIter = FindSubcriberObject(remote);
5999552fe9Sopenharmony_ci    if (subscriberIter != subscriberList_.end()) {
6099552fe9Sopenharmony_ci        STANDBYSERVICE_LOGE("subscriber has already exist");
6199552fe9Sopenharmony_ci        return ERR_STANDBY_OBJECT_EXISTS;
6299552fe9Sopenharmony_ci    }
6399552fe9Sopenharmony_ci
6499552fe9Sopenharmony_ci    subscriberList_.emplace_back(subscriber);
6599552fe9Sopenharmony_ci    remote->AddDeathRecipient(deathRecipient_);
6699552fe9Sopenharmony_ci    STANDBYSERVICE_LOGD(" suscriber standby service callback succeed, list.size() is %{public}d",
6799552fe9Sopenharmony_ci        static_cast<int32_t>(subscriberList_.size()));
6899552fe9Sopenharmony_ci    return ERR_OK;
6999552fe9Sopenharmony_ci}
7099552fe9Sopenharmony_ci
7199552fe9Sopenharmony_ciErrCode StandbyStateSubscriber::RemoveSubscriber(const sptr<IStandbyServiceSubscriber>& subscriber)
7299552fe9Sopenharmony_ci{
7399552fe9Sopenharmony_ci    if (subscriber == nullptr) {
7499552fe9Sopenharmony_ci        STANDBYSERVICE_LOGE("subscriber is null");
7599552fe9Sopenharmony_ci        return ERR_STANDBY_INVALID_PARAM;
7699552fe9Sopenharmony_ci    }
7799552fe9Sopenharmony_ci    auto remote = subscriber->AsObject();
7899552fe9Sopenharmony_ci    if (remote == nullptr) {
7999552fe9Sopenharmony_ci        STANDBYSERVICE_LOGE("remove subscriber failed, remote in subscriber is null");
8099552fe9Sopenharmony_ci        return ERR_STANDBY_INVALID_PARAM;
8199552fe9Sopenharmony_ci    }
8299552fe9Sopenharmony_ci    std::lock_guard<std::mutex> subcriberLock(subscriberLock_);
8399552fe9Sopenharmony_ci    if (deathRecipient_ == nullptr) {
8499552fe9Sopenharmony_ci        STANDBYSERVICE_LOGW("deathRecipient is null");
8599552fe9Sopenharmony_ci        return ERR_STANDBY_OBJECT_EXISTS;
8699552fe9Sopenharmony_ci    }
8799552fe9Sopenharmony_ci    auto subscriberIter = FindSubcriberObject(remote);
8899552fe9Sopenharmony_ci    if (subscriberIter == subscriberList_.end()) {
8999552fe9Sopenharmony_ci        STANDBYSERVICE_LOGE("request subscriber is not exists");
9099552fe9Sopenharmony_ci        return ERR_STANDBY_OBJECT_EXISTS;
9199552fe9Sopenharmony_ci    }
9299552fe9Sopenharmony_ci    subscriberList_.erase(subscriberIter);
9399552fe9Sopenharmony_ci    remote->RemoveDeathRecipient(deathRecipient_);
9499552fe9Sopenharmony_ci    STANDBYSERVICE_LOGD("remove subscriber from standby service subscriber succeed");
9599552fe9Sopenharmony_ci    return ERR_OK;
9699552fe9Sopenharmony_ci}
9799552fe9Sopenharmony_ci
9899552fe9Sopenharmony_civoid StandbyStateSubscriber::ReportStandbyState(uint32_t curState)
9999552fe9Sopenharmony_ci{
10099552fe9Sopenharmony_ci    bool napped = curState == StandbyState::NAP;
10199552fe9Sopenharmony_ci    bool sleeping = curState == StandbyState::SLEEP;
10299552fe9Sopenharmony_ci    STANDBYSERVICE_LOGD("start ReportStandbyState, napping is %{public}d, sleeping is %{public}d", napped, sleeping);
10399552fe9Sopenharmony_ci    NotifyIdleModeByCallback(napped, sleeping);
10499552fe9Sopenharmony_ci    NotifyIdleModeByCommonEvent(napped, sleeping);
10599552fe9Sopenharmony_ci}
10699552fe9Sopenharmony_ci
10799552fe9Sopenharmony_civoid StandbyStateSubscriber::NotifyIdleModeByCallback(bool napped, bool sleeping)
10899552fe9Sopenharmony_ci{
10999552fe9Sopenharmony_ci    std::lock_guard<std::mutex> subcriberLock(subscriberLock_);
11099552fe9Sopenharmony_ci    if (subscriberList_.empty()) {
11199552fe9Sopenharmony_ci        return;
11299552fe9Sopenharmony_ci    }
11399552fe9Sopenharmony_ci    for (auto iter = subscriberList_.begin(); iter != subscriberList_.end(); ++iter) {
11499552fe9Sopenharmony_ci        (*iter)->OnDeviceIdleMode(napped, sleeping);
11599552fe9Sopenharmony_ci    }
11699552fe9Sopenharmony_ci    STANDBYSERVICE_LOGD("stop callback subscriber list");
11799552fe9Sopenharmony_ci}
11899552fe9Sopenharmony_ci
11999552fe9Sopenharmony_civoid StandbyStateSubscriber::NotifyIdleModeByCommonEvent(bool napped, bool sleeping)
12099552fe9Sopenharmony_ci{
12199552fe9Sopenharmony_ci    AAFwk::Want want;
12299552fe9Sopenharmony_ci    want.SetAction(EventFwk::CommonEventSupport::COMMON_EVENT_DEVICE_IDLE_MODE_CHANGED);
12399552fe9Sopenharmony_ci    want.SetParam("napped", napped);
12499552fe9Sopenharmony_ci    want.SetParam("sleeping", sleeping);
12599552fe9Sopenharmony_ci    EventFwk::CommonEventData commonEventData;
12699552fe9Sopenharmony_ci    commonEventData.SetWant(want);
12799552fe9Sopenharmony_ci    if (!EventFwk::CommonEventManager::PublishCommonEvent(commonEventData)) {
12899552fe9Sopenharmony_ci        STANDBYSERVICE_LOGE("PublishCommonEvent for idle mode finished failed");
12999552fe9Sopenharmony_ci    } else {
13099552fe9Sopenharmony_ci        STANDBYSERVICE_LOGD("PublishCommonEvent for idle mode finished succeed");
13199552fe9Sopenharmony_ci    }
13299552fe9Sopenharmony_ci}
13399552fe9Sopenharmony_ci
13499552fe9Sopenharmony_civoid StandbyStateSubscriber::ReportAllowListChanged(int32_t uid, const std::string& name,
13599552fe9Sopenharmony_ci    uint32_t allowType, bool added)
13699552fe9Sopenharmony_ci{
13799552fe9Sopenharmony_ci    STANDBYSERVICE_LOGI("start ReportAllowListChanged, uid is %{public}d"\
13899552fe9Sopenharmony_ci        ", name is %{public}s, allowType is %{public}d", uid, name.c_str(), allowType);
13999552fe9Sopenharmony_ci    NotifyAllowChangedByCallback(uid, name, allowType, added);
14099552fe9Sopenharmony_ci    NotifyAllowChangedByCommonEvent(uid, name, allowType, added);
14199552fe9Sopenharmony_ci}
14299552fe9Sopenharmony_ci
14399552fe9Sopenharmony_civoid StandbyStateSubscriber::NotifyAllowChangedByCallback(int32_t uid, const std::string& name,
14499552fe9Sopenharmony_ci    uint32_t allowType, bool added)
14599552fe9Sopenharmony_ci{
14699552fe9Sopenharmony_ci    std::lock_guard<std::mutex> subcriberLock(subscriberLock_);
14799552fe9Sopenharmony_ci    if (subscriberList_.empty()) {
14899552fe9Sopenharmony_ci        STANDBYSERVICE_LOGW("Sleep State Subscriber List is empty");
14999552fe9Sopenharmony_ci        return;
15099552fe9Sopenharmony_ci    }
15199552fe9Sopenharmony_ci    for (auto iter = subscriberList_.begin(); iter != subscriberList_.end(); ++iter) {
15299552fe9Sopenharmony_ci        (*iter)->OnAllowListChanged(uid, name, allowType, added);
15399552fe9Sopenharmony_ci    }
15499552fe9Sopenharmony_ci}
15599552fe9Sopenharmony_ci
15699552fe9Sopenharmony_civoid StandbyStateSubscriber::NotifyPowerOverusedByCallback(const std::string& module, uint32_t level)
15799552fe9Sopenharmony_ci{
15899552fe9Sopenharmony_ci    STANDBYSERVICE_LOGI("[PowerOverused] NotifyPowerOverusedByCallback start, "
15999552fe9Sopenharmony_ci        "module: %{public}s, level: %{public}u.", module.c_str(), level);
16099552fe9Sopenharmony_ci
16199552fe9Sopenharmony_ci    std::lock_guard<std::mutex> lock(subscriberLock_);
16299552fe9Sopenharmony_ci    if (subscriberList_.empty()) {
16399552fe9Sopenharmony_ci        STANDBYSERVICE_LOGW("Sleep State Subscriber List is empty");
16499552fe9Sopenharmony_ci        return;
16599552fe9Sopenharmony_ci    }
16699552fe9Sopenharmony_ci
16799552fe9Sopenharmony_ci    for (auto iter : subscriberList_) {
16899552fe9Sopenharmony_ci        if (module == iter->GetModuleName()) {
16999552fe9Sopenharmony_ci            iter->OnPowerOverused(module, level);
17099552fe9Sopenharmony_ci        }
17199552fe9Sopenharmony_ci    }
17299552fe9Sopenharmony_ci}
17399552fe9Sopenharmony_ci
17499552fe9Sopenharmony_civoid StandbyStateSubscriber::NotifyAllowChangedByCommonEvent(int32_t uid, const std::string& name,
17599552fe9Sopenharmony_ci    uint32_t allowType, bool added)
17699552fe9Sopenharmony_ci{
17799552fe9Sopenharmony_ci    AAFwk::Want want;
17899552fe9Sopenharmony_ci    want.SetAction(EventFwk::CommonEventSupport::COMMON_EVENT_DEVICE_IDLE_EXEMPTION_LIST_UPDATED);
17999552fe9Sopenharmony_ci    want.SetParam("uid", uid);
18099552fe9Sopenharmony_ci    want.SetParam("name", name);
18199552fe9Sopenharmony_ci    want.SetParam("resourceType", static_cast<int32_t>(allowType));
18299552fe9Sopenharmony_ci    want.SetParam("added", added);
18399552fe9Sopenharmony_ci    EventFwk::CommonEventData commonEventData;
18499552fe9Sopenharmony_ci    commonEventData.SetWant(want);
18599552fe9Sopenharmony_ci    if (!EventFwk::CommonEventManager::PublishCommonEvent(commonEventData)) {
18699552fe9Sopenharmony_ci        STANDBYSERVICE_LOGE("PublishCommonEvent for exempt list update failed");
18799552fe9Sopenharmony_ci    } else {
18899552fe9Sopenharmony_ci        STANDBYSERVICE_LOGD("PublishCommonEvent for exempt list update succeed");
18999552fe9Sopenharmony_ci    }
19099552fe9Sopenharmony_ci}
19199552fe9Sopenharmony_ci
19299552fe9Sopenharmony_civoid StandbyStateSubscriber::HandleSubscriberDeath(const wptr<IRemoteObject>& remote)
19399552fe9Sopenharmony_ci{
19499552fe9Sopenharmony_ci    if (remote == nullptr) {
19599552fe9Sopenharmony_ci        STANDBYSERVICE_LOGE("suscriber death, remote in suscriber is null");
19699552fe9Sopenharmony_ci        return;
19799552fe9Sopenharmony_ci    }
19899552fe9Sopenharmony_ci    sptr<IRemoteObject> proxy = remote.promote();
19999552fe9Sopenharmony_ci    if (!proxy) {
20099552fe9Sopenharmony_ci        STANDBYSERVICE_LOGE("get remote proxy failed");
20199552fe9Sopenharmony_ci        return;
20299552fe9Sopenharmony_ci    }
20399552fe9Sopenharmony_ci    std::lock_guard<std::mutex> subcriberLock(subscriberLock_);
20499552fe9Sopenharmony_ci    auto subscriberIter = FindSubcriberObject(proxy);
20599552fe9Sopenharmony_ci    if (subscriberIter == subscriberList_.end()) {
20699552fe9Sopenharmony_ci        STANDBYSERVICE_LOGI("suscriber death, remote in suscriber not found");
20799552fe9Sopenharmony_ci        return;
20899552fe9Sopenharmony_ci    }
20999552fe9Sopenharmony_ci    subscriberList_.erase(subscriberIter);
21099552fe9Sopenharmony_ci    STANDBYSERVICE_LOGD("suscriber death, remove it from list");
21199552fe9Sopenharmony_ci}
21299552fe9Sopenharmony_ci
21399552fe9Sopenharmony_civoid StandbyStateSubscriber::ShellDump(const std::vector<std::string>& argsInStr, std::string& result)
21499552fe9Sopenharmony_ci{
21599552fe9Sopenharmony_ci    std::lock_guard<std::mutex> subcriberLock(subscriberLock_);
21699552fe9Sopenharmony_ci    if (subscriberList_.empty()) {
21799552fe9Sopenharmony_ci        result += "subscriber observer record is empty\n";
21899552fe9Sopenharmony_ci        return;
21999552fe9Sopenharmony_ci    }
22099552fe9Sopenharmony_ci    std::stringstream stream;
22199552fe9Sopenharmony_ci    for (auto iter = subscriberList_.begin(); iter != subscriberList_.end(); iter++) {
22299552fe9Sopenharmony_ci        stream << "\tobserverName: " << (*iter)->GetSubscriberName() << "\n";
22399552fe9Sopenharmony_ci        result += stream.str();
22499552fe9Sopenharmony_ci        stream.clear();
22599552fe9Sopenharmony_ci    }
22699552fe9Sopenharmony_ci}
22799552fe9Sopenharmony_ci
22899552fe9Sopenharmony_cistd::list<sptr<IStandbyServiceSubscriber>>::iterator StandbyStateSubscriber::FindSubcriberObject(
22999552fe9Sopenharmony_ci    sptr<IRemoteObject>& proxy)
23099552fe9Sopenharmony_ci{
23199552fe9Sopenharmony_ci    auto findSuscriber = [&proxy](const auto& subscriber) {
23299552fe9Sopenharmony_ci        return subscriber->AsObject() == proxy;
23399552fe9Sopenharmony_ci    };
23499552fe9Sopenharmony_ci    return std::find_if(subscriberList_.begin(), subscriberList_.end(), findSuscriber);
23599552fe9Sopenharmony_ci}
23699552fe9Sopenharmony_ci
23799552fe9Sopenharmony_ciSubscriberDeathRecipient::SubscriberDeathRecipient() {}
23899552fe9Sopenharmony_ci
23999552fe9Sopenharmony_ciSubscriberDeathRecipient::~SubscriberDeathRecipient() {}
24099552fe9Sopenharmony_ci
24199552fe9Sopenharmony_civoid SubscriberDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
24299552fe9Sopenharmony_ci{
24399552fe9Sopenharmony_ci    StandbyStateSubscriber::GetInstance()->HandleSubscriberDeath(remote);
24499552fe9Sopenharmony_ci}
24599552fe9Sopenharmony_ci}  // namespace DevStandbyMgr
24699552fe9Sopenharmony_ci}  // namespace OHOS