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