• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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