1 /*
2  * Copyright (c) 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 "standby_state_subscriber.h"
17 
18 #include "common_event_data.h"
19 #include "common_event_manager.h"
20 #include "common_event_support.h"
21 #include "want.h"
22 
23 #include "standby_messsage.h"
24 #include "standby_service_log.h"
25 #include "standby_state.h"
26 
27 namespace OHOS {
28 namespace DevStandbyMgr {
StandbyStateSubscriber()29 StandbyStateSubscriber::StandbyStateSubscriber()
30 {
31     deathRecipient_ = new (std::nothrow) SubscriberDeathRecipient();
32 }
33 
~StandbyStateSubscriber()34 StandbyStateSubscriber::~StandbyStateSubscriber() {}
35 
GetInstance()36 std::shared_ptr<StandbyStateSubscriber> StandbyStateSubscriber::GetInstance()
37 {
38     return DelayedSingleton<StandbyStateSubscriber>::GetInstance();
39 }
40 
AddSubscriber(const sptr<IStandbyServiceSubscriber>& subscriber)41 ErrCode StandbyStateSubscriber::AddSubscriber(const sptr<IStandbyServiceSubscriber>& subscriber)
42 {
43     STANDBYSERVICE_LOGD("StandbyStateSubscriber start subscriber");
44     if (subscriber == NULL) {
45         STANDBYSERVICE_LOGI("subscriber is null");
46         return ERR_STANDBY_INVALID_PARAM;
47     }
48     auto remote = subscriber->AsObject();
49     if (remote == nullptr) {
50         STANDBYSERVICE_LOGE("remote in subscriber is null");
51         return ERR_STANDBY_INVALID_PARAM;
52     }
53     std::lock_guard<std::mutex> subcriberLock(subscriberLock_);
54     if (deathRecipient_ == nullptr) {
55         STANDBYSERVICE_LOGW("create death recipient failed");
56         return ERR_STANDBY_INVALID_PARAM;
57     }
58     auto subscriberIter = FindSubcriberObject(remote);
59     if (subscriberIter != subscriberList_.end()) {
60         STANDBYSERVICE_LOGE("subscriber has already exist");
61         return ERR_STANDBY_OBJECT_EXISTS;
62     }
63 
64     subscriberList_.emplace_back(subscriber);
65     remote->AddDeathRecipient(deathRecipient_);
66     STANDBYSERVICE_LOGD(" suscriber standby service callback succeed, list.size() is %{public}d",
67         static_cast<int32_t>(subscriberList_.size()));
68     return ERR_OK;
69 }
70 
RemoveSubscriber(const sptr<IStandbyServiceSubscriber>& subscriber)71 ErrCode StandbyStateSubscriber::RemoveSubscriber(const sptr<IStandbyServiceSubscriber>& subscriber)
72 {
73     if (subscriber == nullptr) {
74         STANDBYSERVICE_LOGE("subscriber is null");
75         return ERR_STANDBY_INVALID_PARAM;
76     }
77     auto remote = subscriber->AsObject();
78     if (remote == nullptr) {
79         STANDBYSERVICE_LOGE("remove subscriber failed, remote in subscriber is null");
80         return ERR_STANDBY_INVALID_PARAM;
81     }
82     std::lock_guard<std::mutex> subcriberLock(subscriberLock_);
83     if (deathRecipient_ == nullptr) {
84         STANDBYSERVICE_LOGW("deathRecipient is null");
85         return ERR_STANDBY_OBJECT_EXISTS;
86     }
87     auto subscriberIter = FindSubcriberObject(remote);
88     if (subscriberIter == subscriberList_.end()) {
89         STANDBYSERVICE_LOGE("request subscriber is not exists");
90         return ERR_STANDBY_OBJECT_EXISTS;
91     }
92     subscriberList_.erase(subscriberIter);
93     remote->RemoveDeathRecipient(deathRecipient_);
94     STANDBYSERVICE_LOGD("remove subscriber from standby service subscriber succeed");
95     return ERR_OK;
96 }
97 
ReportStandbyState(uint32_t curState)98 void StandbyStateSubscriber::ReportStandbyState(uint32_t curState)
99 {
100     bool napped = curState == StandbyState::NAP;
101     bool sleeping = curState == StandbyState::SLEEP;
102     STANDBYSERVICE_LOGD("start ReportStandbyState, napping is %{public}d, sleeping is %{public}d", napped, sleeping);
103     NotifyIdleModeByCallback(napped, sleeping);
104     NotifyIdleModeByCommonEvent(napped, sleeping);
105 }
106 
NotifyIdleModeByCallback(bool napped, bool sleeping)107 void StandbyStateSubscriber::NotifyIdleModeByCallback(bool napped, bool sleeping)
108 {
109     std::lock_guard<std::mutex> subcriberLock(subscriberLock_);
110     if (subscriberList_.empty()) {
111         return;
112     }
113     for (auto iter = subscriberList_.begin(); iter != subscriberList_.end(); ++iter) {
114         (*iter)->OnDeviceIdleMode(napped, sleeping);
115     }
116     STANDBYSERVICE_LOGD("stop callback subscriber list");
117 }
118 
NotifyIdleModeByCommonEvent(bool napped, bool sleeping)119 void StandbyStateSubscriber::NotifyIdleModeByCommonEvent(bool napped, bool sleeping)
120 {
121     AAFwk::Want want;
122     want.SetAction(EventFwk::CommonEventSupport::COMMON_EVENT_DEVICE_IDLE_MODE_CHANGED);
123     want.SetParam("napped", napped);
124     want.SetParam("sleeping", sleeping);
125     EventFwk::CommonEventData commonEventData;
126     commonEventData.SetWant(want);
127     if (!EventFwk::CommonEventManager::PublishCommonEvent(commonEventData)) {
128         STANDBYSERVICE_LOGE("PublishCommonEvent for idle mode finished failed");
129     } else {
130         STANDBYSERVICE_LOGD("PublishCommonEvent for idle mode finished succeed");
131     }
132 }
133 
ReportAllowListChanged(int32_t uid, const std::string& name, uint32_t allowType, bool added)134 void StandbyStateSubscriber::ReportAllowListChanged(int32_t uid, const std::string& name,
135     uint32_t allowType, bool added)
136 {
137     STANDBYSERVICE_LOGI("start ReportAllowListChanged, uid is %{public}d"\
138         ", name is %{public}s, allowType is %{public}d", uid, name.c_str(), allowType);
139     NotifyAllowChangedByCallback(uid, name, allowType, added);
140     NotifyAllowChangedByCommonEvent(uid, name, allowType, added);
141 }
142 
NotifyAllowChangedByCallback(int32_t uid, const std::string& name, uint32_t allowType, bool added)143 void StandbyStateSubscriber::NotifyAllowChangedByCallback(int32_t uid, const std::string& name,
144     uint32_t allowType, bool added)
145 {
146     std::lock_guard<std::mutex> subcriberLock(subscriberLock_);
147     if (subscriberList_.empty()) {
148         STANDBYSERVICE_LOGW("Sleep State Subscriber List is empty");
149         return;
150     }
151     for (auto iter = subscriberList_.begin(); iter != subscriberList_.end(); ++iter) {
152         (*iter)->OnAllowListChanged(uid, name, allowType, added);
153     }
154 }
155 
NotifyPowerOverusedByCallback(const std::string& module, uint32_t level)156 void StandbyStateSubscriber::NotifyPowerOverusedByCallback(const std::string& module, uint32_t level)
157 {
158     STANDBYSERVICE_LOGI("[PowerOverused] NotifyPowerOverusedByCallback start, "
159         "module: %{public}s, level: %{public}u.", module.c_str(), level);
160 
161     std::lock_guard<std::mutex> lock(subscriberLock_);
162     if (subscriberList_.empty()) {
163         STANDBYSERVICE_LOGW("Sleep State Subscriber List is empty");
164         return;
165     }
166 
167     for (auto iter : subscriberList_) {
168         if (module == iter->GetModuleName()) {
169             iter->OnPowerOverused(module, level);
170         }
171     }
172 }
173 
NotifyAllowChangedByCommonEvent(int32_t uid, const std::string& name, uint32_t allowType, bool added)174 void StandbyStateSubscriber::NotifyAllowChangedByCommonEvent(int32_t uid, const std::string& name,
175     uint32_t allowType, bool added)
176 {
177     AAFwk::Want want;
178     want.SetAction(EventFwk::CommonEventSupport::COMMON_EVENT_DEVICE_IDLE_EXEMPTION_LIST_UPDATED);
179     want.SetParam("uid", uid);
180     want.SetParam("name", name);
181     want.SetParam("resourceType", static_cast<int32_t>(allowType));
182     want.SetParam("added", added);
183     EventFwk::CommonEventData commonEventData;
184     commonEventData.SetWant(want);
185     if (!EventFwk::CommonEventManager::PublishCommonEvent(commonEventData)) {
186         STANDBYSERVICE_LOGE("PublishCommonEvent for exempt list update failed");
187     } else {
188         STANDBYSERVICE_LOGD("PublishCommonEvent for exempt list update succeed");
189     }
190 }
191 
HandleSubscriberDeath(const wptr<IRemoteObject>& remote)192 void StandbyStateSubscriber::HandleSubscriberDeath(const wptr<IRemoteObject>& remote)
193 {
194     if (remote == nullptr) {
195         STANDBYSERVICE_LOGE("suscriber death, remote in suscriber is null");
196         return;
197     }
198     sptr<IRemoteObject> proxy = remote.promote();
199     if (!proxy) {
200         STANDBYSERVICE_LOGE("get remote proxy failed");
201         return;
202     }
203     std::lock_guard<std::mutex> subcriberLock(subscriberLock_);
204     auto subscriberIter = FindSubcriberObject(proxy);
205     if (subscriberIter == subscriberList_.end()) {
206         STANDBYSERVICE_LOGI("suscriber death, remote in suscriber not found");
207         return;
208     }
209     subscriberList_.erase(subscriberIter);
210     STANDBYSERVICE_LOGD("suscriber death, remove it from list");
211 }
212 
ShellDump(const std::vector<std::string>& argsInStr, std::string& result)213 void StandbyStateSubscriber::ShellDump(const std::vector<std::string>& argsInStr, std::string& result)
214 {
215     std::lock_guard<std::mutex> subcriberLock(subscriberLock_);
216     if (subscriberList_.empty()) {
217         result += "subscriber observer record is empty\n";
218         return;
219     }
220     std::stringstream stream;
221     for (auto iter = subscriberList_.begin(); iter != subscriberList_.end(); iter++) {
222         stream << "\tobserverName: " << (*iter)->GetSubscriberName() << "\n";
223         result += stream.str();
224         stream.clear();
225     }
226 }
227 
FindSubcriberObject( sptr<IRemoteObject>& proxy)228 std::list<sptr<IStandbyServiceSubscriber>>::iterator StandbyStateSubscriber::FindSubcriberObject(
229     sptr<IRemoteObject>& proxy)
230 {
231     auto findSuscriber = [&proxy](const auto& subscriber) {
232         return subscriber->AsObject() == proxy;
233     };
234     return std::find_if(subscriberList_.begin(), subscriberList_.end(), findSuscriber);
235 }
236 
SubscriberDeathRecipient()237 SubscriberDeathRecipient::SubscriberDeathRecipient() {}
238 
~SubscriberDeathRecipient()239 SubscriberDeathRecipient::~SubscriberDeathRecipient() {}
240 
OnRemoteDied(const wptr<IRemoteObject>& remote)241 void SubscriberDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
242 {
243     StandbyStateSubscriber::GetInstance()->HandleSubscriberDeath(remote);
244 }
245 }  // namespace DevStandbyMgr
246 }  // namespace OHOS