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