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> ¬ification, const sptr<NotificationSortingMap> ¬ificationMap)
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> ¬ification, const sptr<NotificationSortingMap> ¬ificationMap, 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> ¬ificationMap)
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> ¬ification, const sptr<NotificationSortingMap> ¬ificationMap)
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> ¬ification, const sptr<NotificationSortingMap> ¬ificationMap, 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> ¬ificationMap)
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