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_LOGD("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 return;
109 }
110 for (auto iter = subscriberList_.begin(); iter != subscriberList_.end(); ++iter) {
111 (*iter)->OnDeviceIdleMode(napped, sleeping);
112 }
113 STANDBYSERVICE_LOGD("stop callback subscriber list");
114 }
115
NotifyIdleModeByCommonEvent(bool napped,bool sleeping)116 void StandbyStateSubscriber::NotifyIdleModeByCommonEvent(bool napped, bool sleeping)
117 {
118 AAFwk::Want want;
119 want.SetAction(EventFwk::CommonEventSupport::COMMON_EVENT_DEVICE_IDLE_MODE_CHANGED);
120 want.SetParam("napped", napped);
121 want.SetParam("sleeping", sleeping);
122 EventFwk::CommonEventData commonEventData;
123 commonEventData.SetWant(want);
124 if (!EventFwk::CommonEventManager::PublishCommonEvent(commonEventData)) {
125 STANDBYSERVICE_LOGE("PublishCommonEvent for idle mode finished failed");
126 } else {
127 STANDBYSERVICE_LOGD("PublishCommonEvent for idle mode finished succeed");
128 }
129 }
130
ReportAllowListChanged(int32_t uid,const std::string & name,uint32_t allowType,bool added)131 void StandbyStateSubscriber::ReportAllowListChanged(int32_t uid, const std::string& name,
132 uint32_t allowType, bool added)
133 {
134 STANDBYSERVICE_LOGI("start ReportAllowListChanged, uid is %{public}d"\
135 ", name is %{public}s, allowType is %{public}d", uid, name.c_str(), allowType);
136 NotifyAllowChangedByCallback(uid, name, allowType, added);
137 NotifyAllowChangedByCommonEvent(uid, name, allowType, added);
138 }
139
NotifyAllowChangedByCallback(int32_t uid,const std::string & name,uint32_t allowType,bool added)140 void StandbyStateSubscriber::NotifyAllowChangedByCallback(int32_t uid, const std::string& name,
141 uint32_t allowType, bool added)
142 {
143 std::lock_guard<std::mutex> subcriberLock(subscriberLock_);
144 if (subscriberList_.empty()) {
145 STANDBYSERVICE_LOGW("Sleep State Subscriber List is empty");
146 return;
147 }
148 for (auto iter = subscriberList_.begin(); iter != subscriberList_.end(); ++iter) {
149 (*iter)->OnAllowListChanged(uid, name, allowType, added);
150 }
151 }
152
NotifyAllowChangedByCommonEvent(int32_t uid,const std::string & name,uint32_t allowType,bool added)153 void StandbyStateSubscriber::NotifyAllowChangedByCommonEvent(int32_t uid, const std::string& name,
154 uint32_t allowType, bool added)
155 {
156 AAFwk::Want want;
157 want.SetAction(EventFwk::CommonEventSupport::COMMON_EVENT_DEVICE_IDLE_EXEMPTION_LIST_UPDATED);
158 want.SetParam("uid", uid);
159 want.SetParam("name", name);
160 want.SetParam("resourceType", static_cast<int32_t>(allowType));
161 want.SetParam("added", added);
162 EventFwk::CommonEventData commonEventData;
163 commonEventData.SetWant(want);
164 if (!EventFwk::CommonEventManager::PublishCommonEvent(commonEventData)) {
165 STANDBYSERVICE_LOGE("PublishCommonEvent for exempt list update failed");
166 } else {
167 STANDBYSERVICE_LOGD("PublishCommonEvent for exempt list update succeed");
168 }
169 }
170
HandleSubscriberDeath(const wptr<IRemoteObject> & remote)171 void StandbyStateSubscriber::HandleSubscriberDeath(const wptr<IRemoteObject>& remote)
172 {
173 if (remote == nullptr) {
174 STANDBYSERVICE_LOGE("suscriber death, remote in suscriber is null");
175 return;
176 }
177 sptr<IRemoteObject> proxy = remote.promote();
178 if (!proxy) {
179 STANDBYSERVICE_LOGE("get remote proxy failed");
180 return;
181 }
182 std::lock_guard<std::mutex> subcriberLock(subscriberLock_);
183 auto subscriberIter = FindSubcriberObject(proxy);
184 if (subscriberIter == subscriberList_.end()) {
185 STANDBYSERVICE_LOGI("suscriber death, remote in suscriber not found");
186 return;
187 }
188 subscriberList_.erase(subscriberIter);
189 STANDBYSERVICE_LOGD("suscriber death, remove it from list");
190 }
191
ShellDump(const std::vector<std::string> & argsInStr,std::string & result)192 void StandbyStateSubscriber::ShellDump(const std::vector<std::string>& argsInStr, std::string& result)
193 {
194 if (subscriberList_.empty()) {
195 result += "subscriber observer record is empty\n";
196 return;
197 }
198 std::stringstream stream;
199 for (auto iter = subscriberList_.begin(); iter != subscriberList_.end(); iter++) {
200 stream << "\tobserverName: " << (*iter)->GetSubscriberName() << "\n";
201 result += stream.str();
202 stream.clear();
203 }
204 }
205
FindSubcriberObject(sptr<IRemoteObject> & proxy)206 std::list<sptr<IStandbyServiceSubscriber>>::iterator StandbyStateSubscriber::FindSubcriberObject(
207 sptr<IRemoteObject>& proxy)
208 {
209 auto findSuscriber = [&proxy](const auto& subscriber) {
210 return subscriber->AsObject() == proxy;
211 };
212 return std::find_if(subscriberList_.begin(), subscriberList_.end(), findSuscriber);
213 }
214
SubscriberDeathRecipient()215 SubscriberDeathRecipient::SubscriberDeathRecipient() {}
216
~SubscriberDeathRecipient()217 SubscriberDeathRecipient::~SubscriberDeathRecipient() {}
218
OnRemoteDied(const wptr<IRemoteObject> & remote)219 void SubscriberDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
220 {
221 StandbyStateSubscriber::GetInstance()->HandleSubscriberDeath(remote);
222 }
223 } // namespace DevStandbyMgr
224 } // namespace OHOS