• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 "notification_subscriber_manager.h"
17 
18 #include <algorithm>
19 #include <memory>
20 #include <set>
21 
22 #include "ans_const_define.h"
23 #include "ans_inner_errors.h"
24 #include "ans_log_wrapper.h"
25 #include "ans_watchdog.h"
26 #include "hitrace_meter.h"
27 #include "ipc_skeleton.h"
28 #include "os_account_manager.h"
29 #include "remote_death_recipient.h"
30 
31 namespace OHOS {
32 namespace Notification {
33 struct NotificationSubscriberManager::SubscriberRecord {
34     sptr<AnsSubscriberInterface> subscriber {nullptr};
35     std::set<std::string> bundleList_ {};
36     bool subscribedAll {false};
37     int32_t userId {SUBSCRIBE_USER_INIT};
38 };
39 
NotificationSubscriberManager()40 NotificationSubscriberManager::NotificationSubscriberManager()
41 {
42     runner_ = OHOS::AppExecFwk::EventRunner::Create("NotificationSubscriberMgr");
43     handler_ = std::make_shared<OHOS::AppExecFwk::EventHandler>(runner_);
44     AnsWatchdog::AddHandlerThread(handler_, runner_);
45     recipient_ =
46         new RemoteDeathRecipient(std::bind(&NotificationSubscriberManager::OnRemoteDied, this, std::placeholders::_1));
47 }
48 
~NotificationSubscriberManager()49 NotificationSubscriberManager::~NotificationSubscriberManager()
50 {
51     subscriberRecordList_.clear();
52 }
53 
AddSubscriber(const sptr<AnsSubscriberInterface> & subscriber,const sptr<NotificationSubscribeInfo> & subscribeInfo)54 ErrCode NotificationSubscriberManager::AddSubscriber(
55     const sptr<AnsSubscriberInterface> &subscriber, const sptr<NotificationSubscribeInfo> &subscribeInfo)
56 {
57     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
58     if (subscriber == nullptr) {
59         ANS_LOGE("subscriber is null.");
60         return ERR_ANS_INVALID_PARAM;
61     }
62 
63     sptr<NotificationSubscribeInfo> subInfo = subscribeInfo;
64     if (subInfo == nullptr) {
65         subInfo = new (std::nothrow) NotificationSubscribeInfo();
66         if (subInfo == nullptr) {
67             ANS_LOGE("Failed to create NotificationSubscribeInfo ptr.");
68             return ERR_ANS_NO_MEMORY;
69         }
70     }
71 
72     if (subInfo->GetAppUserId() == SUBSCRIBE_USER_INIT) {
73         int32_t userId = SUBSCRIBE_USER_INIT;
74         int32_t callingUid = IPCSkeleton::GetCallingUid();
75         ErrCode ret = OHOS::AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(callingUid, userId);
76         if (ret != ERR_OK) {
77             ANS_LOGD("Get userId failed, callingUid = <%{public}d>", callingUid);
78             return ERR_ANS_INVALID_PARAM;
79         }
80 
81         ANS_LOGD("Get userId succeeded, callingUid = <%{public}d> userId = <%{public}d>", callingUid, userId);
82         subInfo->AddAppUserId(userId);
83     }
84 
85     ErrCode result = ERR_ANS_TASK_ERR;
86     handler_->PostSyncTask(std::bind([this, &subscriber, &subInfo, &result]() {
87         result = this->AddSubscriberInner(subscriber, subInfo);
88     }),
89         AppExecFwk::EventQueue::Priority::HIGH);
90     return result;
91 }
92 
RemoveSubscriber(const sptr<AnsSubscriberInterface> & subscriber,const sptr<NotificationSubscribeInfo> & subscribeInfo)93 ErrCode NotificationSubscriberManager::RemoveSubscriber(
94     const sptr<AnsSubscriberInterface> &subscriber, const sptr<NotificationSubscribeInfo> &subscribeInfo)
95 {
96     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
97     if (subscriber == nullptr) {
98         ANS_LOGE("subscriber is null.");
99         return ERR_ANS_INVALID_PARAM;
100     }
101 
102     ErrCode result = ERR_ANS_TASK_ERR;
103     handler_->PostSyncTask(std::bind([this, &subscriber, &subscribeInfo, &result]() {
104         result = this->RemoveSubscriberInner(subscriber, subscribeInfo);
105     }),
106         AppExecFwk::EventQueue::Priority::HIGH);
107     return result;
108 }
109 
NotifyConsumed(const sptr<Notification> & notification,const sptr<NotificationSortingMap> & notificationMap)110 void NotificationSubscriberManager::NotifyConsumed(
111     const sptr<Notification> &notification, const sptr<NotificationSortingMap> &notificationMap)
112 {
113     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
114     if (handler_ == nullptr) {
115         ANS_LOGE("handler is nullptr");
116         return;
117     }
118     AppExecFwk::EventHandler::Callback NotifyConsumedFunc =
119         std::bind(&NotificationSubscriberManager::NotifyConsumedInner, this, notification, notificationMap);
120 
121     handler_->PostTask(NotifyConsumedFunc);
122 }
123 
NotifyCanceled(const sptr<Notification> & notification,const sptr<NotificationSortingMap> & notificationMap,int32_t deleteReason)124 void NotificationSubscriberManager::NotifyCanceled(
125     const sptr<Notification> &notification, const sptr<NotificationSortingMap> &notificationMap, int32_t deleteReason)
126 {
127     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
128     if (handler_ == nullptr) {
129         ANS_LOGE("handler is nullptr");
130         return;
131     }
132 
133     AppExecFwk::EventHandler::Callback NotifyCanceledFunc = std::bind(
134         &NotificationSubscriberManager::NotifyCanceledInner, this, notification, notificationMap, deleteReason);
135 
136     handler_->PostTask(NotifyCanceledFunc);
137 }
138 
NotifyUpdated(const sptr<NotificationSortingMap> & notificationMap)139 void NotificationSubscriberManager::NotifyUpdated(const sptr<NotificationSortingMap> &notificationMap)
140 {
141     if (handler_ == nullptr) {
142         ANS_LOGE("handler is nullptr");
143         return;
144     }
145 
146     AppExecFwk::EventHandler::Callback NotifyUpdatedFunc =
147         std::bind(&NotificationSubscriberManager::NotifyUpdatedInner, this, notificationMap);
148 
149     handler_->PostTask(NotifyUpdatedFunc);
150 }
151 
NotifyDoNotDisturbDateChanged(const sptr<NotificationDoNotDisturbDate> & date)152 void NotificationSubscriberManager::NotifyDoNotDisturbDateChanged(const sptr<NotificationDoNotDisturbDate> &date)
153 {
154     if (handler_ == nullptr) {
155         ANS_LOGE("handler is nullptr");
156         return;
157     }
158 
159     AppExecFwk::EventHandler::Callback func =
160         std::bind(&NotificationSubscriberManager::NotifyDoNotDisturbDateChangedInner, this, date);
161 
162     handler_->PostTask(func);
163 }
164 
NotifyEnabledNotificationChanged(const sptr<EnabledNotificationCallbackData> & callbackData)165 void NotificationSubscriberManager::NotifyEnabledNotificationChanged(
166     const sptr<EnabledNotificationCallbackData> &callbackData)
167 {
168     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
169     if (handler_ == nullptr) {
170         ANS_LOGE("handler is nullptr");
171         return;
172     }
173 
174     AppExecFwk::EventHandler::Callback func =
175         std::bind(&NotificationSubscriberManager::NotifyEnabledNotificationChangedInner, this, callbackData);
176 
177     handler_->PostTask(func);
178 }
179 
OnRemoteDied(const wptr<IRemoteObject> & object)180 void NotificationSubscriberManager::OnRemoteDied(const wptr<IRemoteObject> &object)
181 {
182     ANS_LOGI("OnRemoteDied");
183     handler_->PostSyncTask(std::bind([this, object]() {
184         std::shared_ptr<SubscriberRecord> record = FindSubscriberRecord(object);
185         if (record != nullptr) {
186             ANS_LOGW("subscriber removed.");
187             subscriberRecordList_.remove(record);
188         }
189     }),
190         AppExecFwk::EventQueue::Priority::HIGH);
191 }
192 
FindSubscriberRecord(const wptr<IRemoteObject> & object)193 std::shared_ptr<NotificationSubscriberManager::SubscriberRecord> NotificationSubscriberManager::FindSubscriberRecord(
194     const wptr<IRemoteObject> &object)
195 {
196     auto iter = subscriberRecordList_.begin();
197 
198     for (; iter != subscriberRecordList_.end(); iter++) {
199         if ((*iter)->subscriber->AsObject() == object) {
200             return (*iter);
201         }
202     }
203     return nullptr;
204 }
205 
FindSubscriberRecord(const sptr<AnsSubscriberInterface> & subscriber)206 std::shared_ptr<NotificationSubscriberManager::SubscriberRecord> NotificationSubscriberManager::FindSubscriberRecord(
207     const sptr<AnsSubscriberInterface> &subscriber)
208 {
209     auto iter = subscriberRecordList_.begin();
210 
211     for (; iter != subscriberRecordList_.end(); iter++) {
212         if ((*iter)->subscriber->AsObject() == subscriber->AsObject()) {
213             return (*iter);
214         }
215     }
216     return nullptr;
217 }
218 
CreateSubscriberRecord(const sptr<AnsSubscriberInterface> & subscriber)219 std::shared_ptr<NotificationSubscriberManager::SubscriberRecord> NotificationSubscriberManager::CreateSubscriberRecord(
220     const sptr<AnsSubscriberInterface> &subscriber)
221 {
222     std::shared_ptr<SubscriberRecord> record = std::make_shared<SubscriberRecord>();
223     if (record != nullptr) {
224         record->subscriber = subscriber;
225     }
226     return record;
227 }
228 
AddRecordInfo(std::shared_ptr<SubscriberRecord> & record,const sptr<NotificationSubscribeInfo> & subscribeInfo)229 void NotificationSubscriberManager::AddRecordInfo(
230     std::shared_ptr<SubscriberRecord> &record, const sptr<NotificationSubscribeInfo> &subscribeInfo)
231 {
232     if (subscribeInfo != nullptr) {
233         record->bundleList_.clear();
234         record->subscribedAll = true;
235         for (auto bundle : subscribeInfo->GetAppNames()) {
236             record->bundleList_.insert(bundle);
237             record->subscribedAll = false;
238         }
239         record->userId = subscribeInfo->GetAppUserId();
240     } else {
241         record->bundleList_.clear();
242         record->subscribedAll = true;
243     }
244 }
245 
RemoveRecordInfo(std::shared_ptr<SubscriberRecord> & record,const sptr<NotificationSubscribeInfo> & subscribeInfo)246 void NotificationSubscriberManager::RemoveRecordInfo(
247     std::shared_ptr<SubscriberRecord> &record, const sptr<NotificationSubscribeInfo> &subscribeInfo)
248 {
249     if (subscribeInfo != nullptr) {
250         for (auto bundle : subscribeInfo->GetAppNames()) {
251             if (record->subscribedAll) {
252                 record->bundleList_.insert(bundle);
253             } else {
254                 record->bundleList_.erase(bundle);
255             }
256         }
257     } else {
258         record->bundleList_.clear();
259         record->subscribedAll = false;
260     }
261 }
262 
AddSubscriberInner(const sptr<AnsSubscriberInterface> & subscriber,const sptr<NotificationSubscribeInfo> & subscribeInfo)263 ErrCode NotificationSubscriberManager::AddSubscriberInner(
264     const sptr<AnsSubscriberInterface> &subscriber, const sptr<NotificationSubscribeInfo> &subscribeInfo)
265 {
266     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
267     std::shared_ptr<SubscriberRecord> record = FindSubscriberRecord(subscriber);
268     if (record == nullptr) {
269         record = CreateSubscriberRecord(subscriber);
270         if (record == nullptr) {
271             ANS_LOGE("CreateSubscriberRecord failed.");
272             return ERR_ANS_NO_MEMORY;
273         }
274         subscriberRecordList_.push_back(record);
275 
276         record->subscriber->AsObject()->AddDeathRecipient(recipient_);
277 
278         record->subscriber->OnConnected();
279         ANS_LOGI("subscriber is connected.");
280     }
281 
282     AddRecordInfo(record, subscribeInfo);
283 
284     return ERR_OK;
285 }
286 
RemoveSubscriberInner(const sptr<AnsSubscriberInterface> & subscriber,const sptr<NotificationSubscribeInfo> & subscribeInfo)287 ErrCode NotificationSubscriberManager::RemoveSubscriberInner(
288     const sptr<AnsSubscriberInterface> &subscriber, const sptr<NotificationSubscribeInfo> &subscribeInfo)
289 {
290     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
291     std::shared_ptr<SubscriberRecord> record = FindSubscriberRecord(subscriber);
292 
293     if (record == nullptr) {
294         ANS_LOGE("subscriber not found.");
295         return ERR_ANS_INVALID_PARAM;
296     }
297 
298     RemoveRecordInfo(record, subscribeInfo);
299 
300     if (!record->subscribedAll && record->bundleList_.empty()) {
301         record->subscriber->AsObject()->RemoveDeathRecipient(recipient_);
302 
303         subscriberRecordList_.remove(record);
304 
305         record->subscriber->OnDisconnected();
306         ANS_LOGI("subscriber is disconnected.");
307     }
308 
309     return ERR_OK;
310 }
311 
NotifyConsumedInner(const sptr<Notification> & notification,const sptr<NotificationSortingMap> & notificationMap)312 void NotificationSubscriberManager::NotifyConsumedInner(
313     const sptr<Notification> &notification, const sptr<NotificationSortingMap> &notificationMap)
314 {
315     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
316     ANS_LOGD("%{public}s notification->GetUserId <%{public}d>", __FUNCTION__, notification->GetUserId());
317     int32_t recvUserId = notification->GetNotificationRequest().GetReceiverUserId();
318     int32_t sendUserId = notification->GetUserId();
319     for (auto record : subscriberRecordList_) {
320         auto BundleNames = notification->GetBundleName();
321         ANS_LOGD("%{public}s record->userId = <%{public}d> BundleName  = <%{public}s",
322             __FUNCTION__, record->userId, BundleNames.c_str());
323         auto iter = std::find(record->bundleList_.begin(), record->bundleList_.end(), BundleNames);
324         if (!record->subscribedAll == (iter != record->bundleList_.end()) &&
325             ((record->userId == sendUserId) ||
326             (record->userId == SUBSCRIBE_USER_ALL) ||
327             (record->userId == recvUserId) ||
328             IsSystemUser(record->userId) ||  // Delete this, When the systemui subscribe carry the user ID.
329             IsSystemUser(sendUserId))) {
330             record->subscriber->OnConsumed(notification, notificationMap);
331             record->subscriber->OnConsumed(notification);
332         }
333     }
334 }
335 
NotifyCanceledInner(const sptr<Notification> & notification,const sptr<NotificationSortingMap> & notificationMap,int32_t deleteReason)336 void NotificationSubscriberManager::NotifyCanceledInner(
337     const sptr<Notification> &notification, const sptr<NotificationSortingMap> &notificationMap, int32_t deleteReason)
338 {
339     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
340     ANS_LOGD("%{public}s notification->GetUserId <%{public}d>", __FUNCTION__, notification->GetUserId());
341     int32_t recvUserId = notification->GetNotificationRequest().GetReceiverUserId();
342     int32_t sendUserId = notification->GetUserId();
343     for (auto record : subscriberRecordList_) {
344         ANS_LOGD("%{public}s record->userId = <%{public}d>", __FUNCTION__, record->userId);
345         auto BundleNames = notification->GetBundleName();
346         auto iter = std::find(record->bundleList_.begin(), record->bundleList_.end(), BundleNames);
347         if (!record->subscribedAll == (iter != record->bundleList_.end()) &&
348             ((record->userId == sendUserId) ||
349             (record->userId == SUBSCRIBE_USER_ALL) ||
350             (record->userId == recvUserId) ||
351             IsSystemUser(record->userId) ||   // Delete this, When the systemui subscribe carry the user ID.
352             IsSystemUser(sendUserId))) {
353             record->subscriber->OnCanceled(notification, notificationMap, deleteReason);
354         }
355     }
356 }
357 
NotifyUpdatedInner(const sptr<NotificationSortingMap> & notificationMap)358 void NotificationSubscriberManager::NotifyUpdatedInner(const sptr<NotificationSortingMap> &notificationMap)
359 {
360     for (auto record : subscriberRecordList_) {
361         record->subscriber->OnUpdated(notificationMap);
362     }
363 }
364 
NotifyDoNotDisturbDateChangedInner(const sptr<NotificationDoNotDisturbDate> & date)365 void NotificationSubscriberManager::NotifyDoNotDisturbDateChangedInner(const sptr<NotificationDoNotDisturbDate> &date)
366 {
367     for (auto record : subscriberRecordList_) {
368         record->subscriber->OnDoNotDisturbDateChange(date);
369     }
370 }
371 
IsSystemUser(int32_t userId)372 bool NotificationSubscriberManager::IsSystemUser(int32_t userId)
373 {
374     return ((userId >= SUBSCRIBE_USER_SYSTEM_BEGIN) && (userId <= SUBSCRIBE_USER_SYSTEM_END));
375 }
376 
NotifyEnabledNotificationChangedInner(const sptr<EnabledNotificationCallbackData> & callbackData)377 void NotificationSubscriberManager::NotifyEnabledNotificationChangedInner(
378     const sptr<EnabledNotificationCallbackData> &callbackData)
379 {
380     for (auto record : subscriberRecordList_) {
381         record->subscriber->OnEnabledNotificationChanged(callbackData);
382     }
383 }
384 }  // namespace Notification
385 }  // namespace OHOS
386