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