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