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