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