• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025-2025 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 "advanced_notification_service.h"
17 
18 #include "ans_trace_wrapper.h"
19 #include "access_token_helper.h"
20 #include "ans_permission_def.h"
21 #include "bundle_manager_helper.h"
22 #include "ipc_skeleton.h"
23 #include "notification_analytics_util.h"
24 #include "notification_bundle_option.h"
25 #include "notification_constant.h"
26 #include "notification_local_live_view_content.h"
27 #include "notification_subscriber_manager.h"
28 #include "os_account_manager.h"
29 
30 #include "../advanced_notification_inline.cpp"
31 
32 namespace OHOS {
33 namespace Notification {
Cancel(int32_t notificationId,const std::string & label,const std::string & instanceKey)34 ErrCode AdvancedNotificationService::Cancel(int32_t notificationId,
35     const std::string &label, const std::string &instanceKey)
36 {
37     ANS_LOGD("called");
38 
39     sptr<NotificationBundleOption> bundleOption = GenerateBundleOption();
40     if (bundleOption == nullptr) {
41         std::string message = "get bundleOption is null.";
42         OHOS::Notification::HaMetaMessage haMetaMessage = HaMetaMessage(1, 1)
43             .ErrorCode(ERR_ANS_INVALID_BUNDLE).NotificationId(notificationId);
44         ReportDeleteFailedEventPush(haMetaMessage, NotificationConstant::APP_CANCEL_REASON_DELETE,
45             message);
46         ANS_LOGE("%{public}s", message.c_str());
47         return ERR_ANS_INVALID_BUNDLE;
48     }
49     bundleOption->SetAppInstanceKey(instanceKey);
50     return CancelPreparedNotification(notificationId, label, bundleOption,
51         NotificationConstant::APP_CANCEL_REASON_DELETE);
52 }
53 
CancelAll(const std::string & instanceKey)54 ErrCode AdvancedNotificationService::CancelAll(const std::string &instanceKey)
55 {
56     ANS_LOGD("called");
57     const int reason = NotificationConstant::APP_CANCEL_ALL_REASON_DELETE;
58     sptr<NotificationBundleOption> bundleOption = GenerateBundleOption();
59     if (bundleOption == nullptr) {
60         return ERR_ANS_INVALID_BUNDLE;
61     }
62     bundleOption->SetAppInstanceKey(instanceKey);
63 
64     if (notificationSvrQueue_ == nullptr) {
65         ANS_LOGE("null notificationSvrQueue");
66         return ERR_ANS_INVALID_PARAM;
67     }
68     ErrCode result = ExcuteCancelAll(bundleOption, reason);
69     return result;
70 }
71 
ExcuteCancelAll(const sptr<NotificationBundleOption> & bundleOption,const int32_t reason)72 ErrCode AdvancedNotificationService::ExcuteCancelAll(
73     const sptr<NotificationBundleOption>& bundleOption, const int32_t reason)
74 {
75     ErrCode result = ERR_OK;
76     ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
77         ANS_LOGD("ffrt enter!");
78         sptr<Notification> notification = nullptr;
79 
80         std::vector<std::string> keys = GetNotificationKeysByBundle(bundleOption);
81         std::vector<sptr<Notification>> notifications;
82         std::vector<uint64_t> timerIds;
83         for (auto key : keys) {
84 #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED
85             std::string deviceId;
86             std::string bundleName;
87             GetDistributedInfo(key, deviceId, bundleName);
88 #endif
89             result = RemoveFromNotificationList(key, notification, true, reason);
90             if (result != ERR_OK) {
91                 continue;
92             }
93 
94             if (notification != nullptr) {
95                 UpdateRecentNotification(notification, true, reason);
96                 notifications.emplace_back(notification);
97                 timerIds.emplace_back(notification->GetAutoDeletedTimer());
98 #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED
99                 DoDistributedDelete(deviceId, bundleName, notification);
100 #endif
101             }
102             if (notifications.size() >= MAX_CANCELED_PARCELABLE_VECTOR_NUM) {
103                 std::vector<sptr<Notification>> currNotificationList = notifications;
104                 NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled(
105                     currNotificationList, nullptr, reason);
106                 notifications.clear();
107             }
108         }
109 
110         if (!notifications.empty()) {
111             NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled(
112                 notifications, nullptr, reason);
113         }
114         BatchCancelTimer(timerIds);
115         result = ERR_OK;
116     }));
117     notificationSvrQueue_->wait(handler);
118     return result;
119 }
120 
CancelAsBundle(const sptr<NotificationBundleOption> & bundleOption,int32_t notificationId,int32_t userId)121 ErrCode AdvancedNotificationService::CancelAsBundle(
122     const sptr<NotificationBundleOption> &bundleOption, int32_t notificationId, int32_t userId)
123 {
124     ANS_LOGD("called");
125     int32_t reason = NotificationConstant::APP_CANCEL_AS_BUNELE_REASON_DELETE;
126     if (bundleOption == nullptr) {
127         ANS_LOGE("null bundleOption");
128         return ERR_ANS_INVALID_PARAM;
129     }
130     int32_t errCode = ValidRightsForCancelAsBundle(notificationId, reason);
131     if (errCode != ERR_OK) {
132         return errCode;
133     }
134     errCode = CheckUserIdParams(userId);
135     if (errCode != ERR_OK) {
136         std::string message = "userId:" + std::to_string(userId);
137         HaMetaMessage haMateMessage = HaMetaMessage(EventSceneId::SCENE_13, EventBranchId::BRANCH_14)
138             .ErrorCode(errCode).NotificationId(notificationId);
139         ReportDeleteFailedEventPush(haMateMessage, reason, message);
140         return errCode;
141     }
142 
143     int32_t uid = -1;
144     if (bundleOption->GetUid() == DEFAULT_UID) {
145         std::shared_ptr<BundleManagerHelper> bundleManager = BundleManagerHelper::GetInstance();
146         if (bundleManager != nullptr) {
147             uid = BundleManagerHelper::GetInstance()->GetDefaultUidByBundleName(bundleOption->GetBundleName(), userId);
148         }
149     } else {
150         uid = bundleOption->GetUid();
151     }
152     if (uid < 0) {
153         std::string message = "uid error";
154         OHOS::Notification::HaMetaMessage haMetaMessage = HaMetaMessage(2, 3)
155             .ErrorCode(ERR_ANS_INVALID_UID).NotificationId(notificationId);
156         ReportDeleteFailedEventPush(haMetaMessage, reason, message);
157         ANS_LOGE("%{public}s", message.c_str());
158         return ERR_ANS_INVALID_UID;
159     }
160     sptr<NotificationBundleOption> bundle = new (std::nothrow) NotificationBundleOption(
161         bundleOption->GetBundleName(), uid);
162     return CancelPreparedNotification(notificationId, "", bundle, reason);
163 }
164 
ValidRightsForCancelAsBundle(int32_t notificationId,int32_t & reason)165 ErrCode AdvancedNotificationService::ValidRightsForCancelAsBundle(int32_t notificationId, int32_t &reason)
166 {
167     bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
168     if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
169         std::string message = "not systemApp";
170         OHOS::Notification::HaMetaMessage haMetaMessage = HaMetaMessage(2, 1)
171             .ErrorCode(ERR_ANS_NON_SYSTEM_APP).NotificationId(notificationId);
172         ReportDeleteFailedEventPush(haMetaMessage, reason, message);
173         ANS_LOGE("%{public}s", message.c_str());
174         return ERR_ANS_NON_SYSTEM_APP;
175     }
176 
177     if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER) ||
178         !AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_AGENT_CONTROLLER)) {
179         std::string message = "no acl permission";
180         OHOS::Notification::HaMetaMessage haMetaMessage = HaMetaMessage(2, 2)
181             .ErrorCode(ERR_ANS_PERMISSION_DENIED).NotificationId(notificationId);
182         ReportDeleteFailedEventPush(haMetaMessage, reason, message);
183         ANS_LOGE("%{public}s", message.c_str());
184         return ERR_ANS_PERMISSION_DENIED;
185     }
186     return ERR_OK;
187 }
188 
CancelAsBundle(const sptr<NotificationBundleOption> & bundleOption,int32_t notificationId)189 ErrCode AdvancedNotificationService::CancelAsBundle(
190     const sptr<NotificationBundleOption> &bundleOption, int32_t notificationId)
191 {
192     ANS_LOGD("uid = %{public}d", bundleOption->GetUid());
193     int32_t userId = -1;
194     if (bundleOption->GetUid() != 0) {
195         OHOS::AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(bundleOption->GetUid(), userId);
196     } else {
197         OHOS::AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(IPCSkeleton::GetCallingUid(), userId);
198     }
199     return CancelAsBundle(bundleOption, notificationId, userId);
200 }
201 
CancelAsBundle(int32_t notificationId,const std::string & representativeBundle,int32_t userId)202 ErrCode AdvancedNotificationService::CancelAsBundle(
203     int32_t notificationId, const std::string &representativeBundle, int32_t userId)
204 {
205     ANS_LOGD("called");
206     sptr<NotificationBundleOption> bundleOption = new (std::nothrow) NotificationBundleOption(
207          representativeBundle, DEFAULT_UID);
208     if (bundleOption == nullptr) {
209         ANS_LOGE("null bundleOption");
210         return ERR_ANS_TASK_ERR;
211     }
212     return CancelAsBundle(bundleOption, notificationId, userId);
213 }
214 
CancelAsBundleWithAgent(const sptr<NotificationBundleOption> & bundleOption,const int32_t id)215 ErrCode AdvancedNotificationService::CancelAsBundleWithAgent(
216     const sptr<NotificationBundleOption> &bundleOption, const int32_t id)
217 {
218     ANS_LOGD("Called.");
219     int32_t reason = NotificationConstant::APP_CANCEL_AS_BUNELE_WITH_AGENT_REASON_DELETE;
220     bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
221     if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
222         std::string message = "not systemApp";
223         OHOS::Notification::HaMetaMessage haMetaMessage = HaMetaMessage(2, 4)
224             .ErrorCode(ERR_ANS_NON_SYSTEM_APP).NotificationId(id);
225         ReportDeleteFailedEventPush(haMetaMessage, reason, message);
226         ANS_LOGE("%{public}s", message.c_str());
227         return ERR_ANS_NON_SYSTEM_APP;
228     }
229 
230     if (IsAgentRelationship(GetClientBundleName(), bundleOption->GetBundleName())) {
231         int32_t userId = -1;
232         if (bundleOption->GetUid() != 0) {
233             OHOS::AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(bundleOption->GetUid(), userId);
234         } else {
235             OHOS::AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(IPCSkeleton::GetCallingUid(), userId);
236         }
237         int32_t uid = -1;
238         if (bundleOption->GetUid() == DEFAULT_UID) {
239             std::shared_ptr<BundleManagerHelper> bundleManager = BundleManagerHelper::GetInstance();
240             if (bundleManager != nullptr) {
241                 uid = BundleManagerHelper::GetInstance()->GetDefaultUidByBundleName(
242                     bundleOption->GetBundleName(), userId);
243             }
244         } else {
245             uid = bundleOption->GetUid();
246         }
247         if (uid < 0) {
248             std::string message = "uid error";
249             OHOS::Notification::HaMetaMessage haMetaMessage = HaMetaMessage(2, 5)
250                 .ErrorCode(ERR_ANS_INVALID_UID).NotificationId(id);
251             ReportDeleteFailedEventPush(haMetaMessage, reason, message);
252             ANS_LOGE("%{public}s", message.c_str());
253             return ERR_ANS_INVALID_UID;
254         }
255         sptr<NotificationBundleOption> bundle = new (std::nothrow) NotificationBundleOption(
256             bundleOption->GetBundleName(), uid);
257         return CancelPreparedNotification(id, "", bundle, reason);
258     }
259     std::string message = "no agent setting";
260     OHOS::Notification::HaMetaMessage haMetaMessage = HaMetaMessage(2, 6)
261         .ErrorCode(ERR_ANS_NO_AGENT_SETTING).NotificationId(id);
262     ReportDeleteFailedEventPush(haMetaMessage, reason, message);
263     ANS_LOGE("%{public}s", message.c_str());
264     return ERR_ANS_NO_AGENT_SETTING;
265 }
266 
CancelContinuousTaskNotification(const std::string & label,int32_t notificationId)267 ErrCode AdvancedNotificationService::CancelContinuousTaskNotification(const std::string &label, int32_t notificationId)
268 {
269     ANS_LOGD("called");
270 
271     bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
272     if (!isSubsystem) {
273         return ERR_ANS_NOT_SYSTEM_SERVICE;
274     }
275 
276     if (notificationSvrQueue_ == nullptr) {
277         ANS_LOGE("null notificationSvrQueue");
278         return ERR_ANS_INVALID_PARAM;
279     }
280     int32_t uid = IPCSkeleton::GetCallingUid();
281     ErrCode result = ERR_OK;
282     ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
283         ANS_LOGD("called");
284         sptr<Notification> notification = nullptr;
285         for (auto record : notificationList_) {
286             if ((record->bundleOption->GetBundleName().empty()) && (record->bundleOption->GetUid() == uid) &&
287                 (record->notification->GetId() == notificationId) && (record->notification->GetLabel() == label)) {
288                 notification = record->notification;
289                 notificationList_.remove(record);
290                 result = ERR_OK;
291                 break;
292             }
293         }
294         if (notification != nullptr) {
295             int32_t reason = NotificationConstant::APP_CANCEL_REASON_DELETE;
296             UpdateRecentNotification(notification, true, reason);
297             CancelTimer(notification->GetAutoDeletedTimer());
298             NotificationSubscriberManager::GetInstance()->NotifyCanceled(notification, nullptr, reason);
299         }
300     }));
301     notificationSvrQueue_->wait(handler);
302     return result;
303 }
304 
RemoveNotification(const sptr<NotificationBundleOption> & bundleOption,int32_t notificationId,const std::string & label,int32_t removeReason)305 ErrCode AdvancedNotificationService::RemoveNotification(const sptr<NotificationBundleOption> &bundleOption,
306     int32_t notificationId, const std::string &label, int32_t removeReason)
307 {
308     NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION);
309     ANS_LOGD("called");
310 
311     bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
312     if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
313         std::string message = "not systemApp.";
314         OHOS::Notification::HaMetaMessage haMetaMessage = HaMetaMessage(4, 4)
315             .ErrorCode(ERR_ANS_NON_SYSTEM_APP).NotificationId(notificationId);
316         ReportDeleteFailedEventPush(haMetaMessage, removeReason, message);
317         ANS_LOGE("%{public}s", message.c_str());
318         return ERR_ANS_NON_SYSTEM_APP;
319     }
320 
321     if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) {
322         std::string message = "no acl controller permission.";
323         OHOS::Notification::HaMetaMessage haMetaMessage = HaMetaMessage(4, 5)
324             .ErrorCode(ERR_ANS_PERMISSION_DENIED).NotificationId(notificationId);
325         ReportDeleteFailedEventPush(haMetaMessage, removeReason, message);
326         ANS_LOGE("%{public}s", message.c_str());
327         return ERR_ANS_PERMISSION_DENIED;
328     }
329 
330     sptr<NotificationBundleOption> bundle = GenerateValidBundleOption(bundleOption);
331     if (bundle == nullptr) {
332         return ERR_ANS_INVALID_BUNDLE;
333     }
334 
335     if (notificationSvrQueue_ == nullptr) {
336         std::string message = "NotificationSvrQueue_ is null.";
337         ANS_LOGE("%{public}s", message.c_str());
338         return ERR_ANS_INVALID_PARAM;
339     }
340     ErrCode result = ERR_ANS_NOTIFICATION_NOT_EXISTS;
341     ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
342         result = ExcuteRemoveNotification(bundle, notificationId, label, removeReason);
343     }));
344     notificationSvrQueue_->wait(handler);
345     if (result != ERR_OK) {
346         std::string message = "remove notificaiton error";
347         ANS_LOGE("%{public}s %{public}d", message.c_str(), result);
348     }
349     SendRemoveHiSysEvent(notificationId, label, bundleOption, result);
350     return result;
351 }
352 
ExcuteRemoveNotification(const sptr<NotificationBundleOption> & bundle,int32_t notificationId,const std::string & label,int32_t & removeReason)353 ErrCode AdvancedNotificationService::ExcuteRemoveNotification(const sptr<NotificationBundleOption> &bundle,
354     int32_t notificationId, const std::string &label, int32_t &removeReason)
355 {
356     ErrCode result = ERR_ANS_NOTIFICATION_NOT_EXISTS;
357     ANS_LOGD("called");
358     bool isThirdParty = true;
359     sptr<Notification> notification = nullptr;
360     sptr<NotificationRequest> notificationRequest = nullptr;
361 
362 #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED
363     std::string deviceId;
364     std::string bundleName;
365 #endif
366     for (auto record : notificationList_) {
367         if ((record->bundleOption->GetBundleName() == bundle->GetBundleName()) &&
368             (record->bundleOption->GetUid() == bundle->GetUid()) &&
369 #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED
370             (record->deviceId.empty()) &&
371 #endif
372             (record->notification->GetId() == notificationId) && (record->notification->GetLabel() == label)) {
373             if (!record->notification->IsRemoveAllowed()) {
374                 result = ERR_ANS_NOTIFICATION_IS_UNALLOWED_REMOVEALLOWED;
375                 break;
376             }
377 #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED
378             deviceId = record->deviceId;
379             bundleName = record->bundleName;
380 #endif
381             notification = record->notification;
382             notificationRequest = record->request;
383             isThirdParty = record->isThirdparty;
384 
385             if (!IsReasonClickDelete(removeReason)) {
386                 ProcForDeleteLiveView(record);
387             }
388 
389             notificationList_.remove(record);
390             result = ERR_OK;
391             break;
392         }
393     }
394 
395     if (notification != nullptr) {
396         UpdateRecentNotification(notification, true, removeReason);
397         CancelTimer(notification->GetAutoDeletedTimer());
398         NotificationSubscriberManager::GetInstance()->NotifyCanceled(notification, nullptr, removeReason);
399 #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED
400         DoDistributedDelete(deviceId, bundleName, notification);
401 #endif
402     }
403     if (!IsReasonClickDelete(removeReason)) {
404         TriggerRemoveWantAgent(notificationRequest, removeReason, isThirdParty);
405     }
406     return result;
407 }
408 
IsReasonClickDelete(const int32_t removeReason)409 bool AdvancedNotificationService::IsReasonClickDelete(const int32_t removeReason)
410 {
411     return removeReason == NotificationConstant::CLICK_REASON_DELETE ||
412         removeReason == NotificationConstant::DISTRIBUTED_COLLABORATIVE_CLICK_DELETE;
413 }
414 
RemoveAllNotificationsForDisable(const sptr<NotificationBundleOption> & bundleOption)415 ErrCode AdvancedNotificationService::RemoveAllNotificationsForDisable(
416     const sptr<NotificationBundleOption> &bundleOption)
417 {
418     return RemoveAllNotificationsInner(bundleOption, NotificationConstant::DISABLE_NOTIFICATION_REASON_DELETE);
419 }
420 
RemoveAllNotifications(const sptr<NotificationBundleOption> & bundleOption)421 ErrCode AdvancedNotificationService::RemoveAllNotifications(const sptr<NotificationBundleOption> &bundleOption)
422 {
423     return RemoveAllNotificationsInner(bundleOption, NotificationConstant::APP_REMOVE_ALL_REASON_DELETE);
424 }
425 
RemoveAllNotificationsInner(const sptr<NotificationBundleOption> & bundleOption,int32_t reason)426 ErrCode AdvancedNotificationService::RemoveAllNotificationsInner(const sptr<NotificationBundleOption> &bundleOption,
427     int32_t reason)
428 {
429     NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION);
430     ANS_LOGD("called");
431 
432     bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
433     if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
434         std::string message = "not system app.";
435         OHOS::Notification::HaMetaMessage haMetaMessage = HaMetaMessage(6, 1)
436             .ErrorCode(ERR_ANS_NON_SYSTEM_APP);
437         ReportDeleteFailedEventPush(haMetaMessage, reason, message);
438         ANS_LOGE("%{public}s", message.c_str());
439         return ERR_ANS_NON_SYSTEM_APP;
440     }
441 
442     int32_t callingUid = IPCSkeleton::GetCallingUid();
443     if (callingUid != NotificationConstant::ANS_UID &&
444         !AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) {
445         std::string message = "no acl permission.";
446         OHOS::Notification::HaMetaMessage haMetaMessage = HaMetaMessage(6, 2)
447             .ErrorCode(ERR_ANS_PERMISSION_DENIED);
448         ReportDeleteFailedEventPush(haMetaMessage, reason, message);
449         ANS_LOGE("%{public}s", message.c_str());
450         return ERR_ANS_PERMISSION_DENIED;
451     }
452 
453     sptr<NotificationBundleOption> bundle = GenerateValidBundleOption(bundleOption);
454     if (bundle == nullptr) {
455         std::string message = "budle is nullptr.";
456         OHOS::Notification::HaMetaMessage haMetaMessage = HaMetaMessage(6, 3)
457             .ErrorCode(ERR_ANS_INVALID_BUNDLE);
458         ReportDeleteFailedEventPush(haMetaMessage, reason, message);
459         ANS_LOGE("%{public}s", message.c_str());
460         return ERR_ANS_INVALID_BUNDLE;
461     }
462 
463     if (notificationSvrQueue_ == nullptr) {
464         std::string message = "Serial queue is nullptr.";
465         ANS_LOGE("%{public}s", message.c_str());
466         return ERR_ANS_INVALID_PARAM;
467     }
468     ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
469         ExcuteRemoveAllNotificationsInner(bundleOption, bundle, reason);
470     }));
471     notificationSvrQueue_->wait(handler);
472 
473     return ERR_OK;
474 }
475 
ExcuteRemoveAllNotificationsInner(const sptr<NotificationBundleOption> & bundleOption,const sptr<NotificationBundleOption> & bundle,int32_t & reason)476 void AdvancedNotificationService::ExcuteRemoveAllNotificationsInner(const sptr<NotificationBundleOption> &bundleOption,
477     const sptr<NotificationBundleOption> &bundle, int32_t &reason)
478 {
479     std::vector<std::shared_ptr<NotificationRecord>> removeList;
480     ANS_LOGD("called");
481     GetRemoveListForRemoveAll(bundleOption, bundle, removeList);
482     std::vector<sptr<Notification>> notifications;
483     std::vector<uint64_t> timerIds;
484     for (auto record : removeList) {
485         notificationList_.remove(record);
486         if (record->notification != nullptr) {
487             ANS_LOGD("record->notification is not nullptr.");
488             UpdateRecentNotification(record->notification, true, reason);
489             notifications.emplace_back(record->notification);
490             timerIds.emplace_back(record->notification->GetAutoDeletedTimer());
491 #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED
492             DoDistributedDelete(record->deviceId, record->bundleName, record->notification);
493 #endif
494         }
495         if (notifications.size() >= MAX_CANCELED_PARCELABLE_VECTOR_NUM) {
496             SendNotificationsOnCanceled(notifications, nullptr, reason);
497         }
498 
499         TriggerRemoveWantAgent(record->request, reason, record->isThirdparty);
500     }
501 
502     if (!notifications.empty()) {
503         NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled(notifications, nullptr, reason);
504     }
505     BatchCancelTimer(timerIds);
506 }
507 
GetRemoveListForRemoveAll(const sptr<NotificationBundleOption> & bundleOption,const sptr<NotificationBundleOption> & bundle,std::vector<std::shared_ptr<NotificationRecord>> & removeList)508 void AdvancedNotificationService::GetRemoveListForRemoveAll(const sptr<NotificationBundleOption> &bundleOption,
509     const sptr<NotificationBundleOption> &bundle, std::vector<std::shared_ptr<NotificationRecord>> &removeList)
510 {
511     for (auto record : notificationList_) {
512         bool isAllowedNotification = true;
513         if (IsAllowedNotifyForBundle(bundleOption, isAllowedNotification) != ERR_OK) {
514             ANSR_LOGW("The application does not request enable notification.");
515         }
516         if (!record->notification->IsRemoveAllowed() && isAllowedNotification) {
517             ANS_LOGI("BatchRemove-FILTER-RemoveNotAllowed-%{public}s", record->notification->GetKey().c_str());
518             continue;
519         }
520         if (record->slot != nullptr && record->slot->GetForceControl() && record->slot->GetEnable()) {
521             ANS_LOGI("BatchRemove-FILTER-ForceControl-%{public}s", record->notification->GetKey().c_str());
522             continue;
523         }
524         if (record->bundleOption->GetBundleName() != bundle->GetBundleName() ||
525             record->bundleOption->GetUid() != bundle->GetUid()
526 #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED
527             || !record->deviceId.empty()
528 #endif
529             ) {
530             continue;
531         }
532         auto notificationRequest = record->request;
533         if (!BundleManagerHelper::GetInstance()->IsSystemApp(bundle->GetUid()) &&
534             notificationRequest->IsSystemLiveView()) {
535             auto localLiveviewContent = std::static_pointer_cast<NotificationLocalLiveViewContent>(
536                 notificationRequest->GetContent()->GetNotificationContent());
537             if (localLiveviewContent->GetType() == 0) {
538                 continue;
539             }
540         }
541         ProcForDeleteLiveView(record);
542         removeList.push_back(record);
543     }
544 }
545 
RemoveNotifications(const std::vector<std::string> & keys,int32_t removeReason)546 ErrCode AdvancedNotificationService::RemoveNotifications(
547     const std::vector<std::string> &keys, int32_t removeReason)
548 {
549     NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION);
550     ANS_LOGD("called");
551 
552     bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
553     if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
554         return ERR_ANS_NON_SYSTEM_APP;
555     }
556     if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) {
557         return ERR_ANS_PERMISSION_DENIED;
558     }
559     if (notificationSvrQueue_ == nullptr) {
560         ANS_LOGE("null notificationSvrQueue");
561         return ERR_ANS_INVALID_PARAM;
562     }
563     ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
564         ExcuteRemoveNotifications(keys, removeReason);
565     }));
566     notificationSvrQueue_->wait(handler);
567 
568     return ERR_OK;
569 }
570 
ExcuteRemoveNotifications(const std::vector<std::string> & keys,int32_t removeReason)571 void AdvancedNotificationService::ExcuteRemoveNotifications(const std::vector<std::string> &keys, int32_t removeReason)
572 {
573     std::vector<sptr<Notification>> notifications;
574     std::vector<uint64_t> timerIds;
575     for (auto key : keys) {
576         sptr<Notification> notification = nullptr;
577 #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED
578         std::string deviceId;
579         std::string bundleName;
580         GetDistributedInfo(key, deviceId, bundleName);
581 #endif
582         ErrCode result = RemoveFromNotificationList(key, notification, false, removeReason);
583         if (result != ERR_OK) {
584             continue;
585         }
586         if (notification != nullptr) {
587             UpdateRecentNotification(notification, true, removeReason);
588             notifications.emplace_back(notification);
589             timerIds.emplace_back(notification->GetAutoDeletedTimer());
590 #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED
591             DoDistributedDelete(deviceId, bundleName, notification);
592 #endif
593         }
594         if (notifications.size() >= MAX_CANCELED_PARCELABLE_VECTOR_NUM) {
595             std::vector<sptr<Notification>> currNotificationList = notifications;
596             NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled(
597                 currNotificationList, nullptr, removeReason);
598             notifications.clear();
599         }
600     }
601 
602     if (!notifications.empty()) {
603         NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled(notifications, nullptr, removeReason);
604     }
605     BatchCancelTimer(timerIds);
606 }
607 
RemoveNotificationBySlot(const sptr<NotificationBundleOption> & bundleOption,const sptr<NotificationSlot> & slot,const int reason)608 ErrCode AdvancedNotificationService::RemoveNotificationBySlot(const sptr<NotificationBundleOption> &bundleOption,
609     const sptr<NotificationSlot> &slot, const int reason)
610 {
611     NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION);
612     ANS_LOGD("called");
613 
614     bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
615     if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
616         return ERR_ANS_NON_SYSTEM_APP;
617     }
618 
619     sptr<NotificationBundleOption> bundle = GenerateValidBundleOption(bundleOption);
620     if (bundle == nullptr) {
621         return ERR_ANS_INVALID_BUNDLE;
622     }
623     ErrCode result = ERR_ANS_NOTIFICATION_NOT_EXISTS;
624     std::vector<std::shared_ptr<NotificationRecord>> removeList;
625     GetRemoveListForRemoveNtfBySlot(bundle, slot, removeList);
626 
627     std::vector<sptr<Notification>> notifications;
628     std::vector<uint64_t> timerIds;
629     for (auto record : removeList) {
630         if (record == nullptr) {
631             ANS_LOGE("null record");
632             continue;
633         }
634         notificationList_.remove(record);
635         if (record->notification != nullptr) {
636             ANS_LOGD("record->notification is not nullptr.");
637             UpdateRecentNotification(record->notification, true, reason);
638             notifications.emplace_back(record->notification);
639             timerIds.emplace_back(record->notification->GetAutoDeletedTimer());
640         }
641         if (notifications.size() >= MAX_CANCELED_PARCELABLE_VECTOR_NUM) {
642             SendNotificationsOnCanceled(notifications, nullptr, reason);
643         }
644 
645         TriggerRemoveWantAgent(record->request, reason, record->isThirdparty);
646         result = ERR_OK;
647     }
648 
649     if (!notifications.empty()) {
650         NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled(notifications, nullptr, reason);
651     }
652     BatchCancelTimer(timerIds);
653     return result;
654 }
655 
GetRemoveListForRemoveNtfBySlot(const sptr<NotificationBundleOption> & bundle,const sptr<NotificationSlot> & slot,std::vector<std::shared_ptr<NotificationRecord>> & removeList)656 void AdvancedNotificationService::GetRemoveListForRemoveNtfBySlot(const sptr<NotificationBundleOption> &bundle,
657     const sptr<NotificationSlot> &slot, std::vector<std::shared_ptr<NotificationRecord>> &removeList)
658 {
659     for (auto record : notificationList_) {
660         if (record == nullptr) {
661             ANS_LOGE("null record");
662             continue;
663         }
664         if ((record->bundleOption->GetBundleName() == bundle->GetBundleName()) &&
665             (record->bundleOption->GetUid() == bundle->GetUid()) &&
666             (record->request->GetSlotType() == slot->GetType())) {
667             if ((record->request->GetAgentBundle() != nullptr && record->request->IsSystemLiveView())) {
668                 ANS_LOGW("Agent systemliveview no need remove.");
669                 continue;
670             }
671             ProcForDeleteLiveView(record);
672             removeList.push_back(record);
673         }
674     }
675 }
676 
RemoveNotificationFromRecordList(const std::vector<std::shared_ptr<NotificationRecord>> & recordList)677 ErrCode AdvancedNotificationService::RemoveNotificationFromRecordList(
678     const std::vector<std::shared_ptr<NotificationRecord>>& recordList)
679 {
680     ErrCode result = ERR_OK;
681         std::vector<sptr<Notification>> notifications;
682         std::vector<uint64_t> timerIds;
683         for (auto& record : recordList) {
684             std::string key = record->notification->GetKey();
685             sptr<Notification> notification = nullptr;
686 #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED
687             std::string deviceId;
688             std::string bundleName;
689             GetDistributedInfo(key, deviceId, bundleName);
690 #endif
691             result = RemoveFromNotificationList(key, notification, true,
692                 NotificationConstant::USER_STOPPED_REASON_DELETE);
693             if (result != ERR_OK) {
694                 continue;
695             }
696             if (notification != nullptr) {
697                 int32_t reason = NotificationConstant::USER_STOPPED_REASON_DELETE;
698                 UpdateRecentNotification(notification, true, reason);
699                 notifications.emplace_back(notification);
700                 timerIds.emplace_back(notification->GetAutoDeletedTimer());
701 #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED
702             DoDistributedDelete(deviceId, bundleName, notification);
703 #endif
704             }
705             if (notifications.size() >= MAX_CANCELED_PARCELABLE_VECTOR_NUM) {
706                 std::vector<sptr<Notification>> currNotificationList = notifications;
707                 NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled(
708                     currNotificationList, nullptr, NotificationConstant::USER_STOPPED_REASON_DELETE);
709                 notifications.clear();
710             }
711         }
712         if (!notifications.empty()) {
713             NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled(
714                 notifications, nullptr, NotificationConstant::USER_STOPPED_REASON_DELETE);
715         }
716         BatchCancelTimer(timerIds);
717         return result;
718 }
719 
Delete(const std::string & key,int32_t removeReason)720 ErrCode AdvancedNotificationService::Delete(const std::string &key, int32_t removeReason)
721 {
722     ANS_LOGD("called");
723     bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
724     if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
725         std::string message = "not systemApp. key:" + key + ".";
726         OHOS::Notification::HaMetaMessage haMetaMessage = HaMetaMessage(4, 1)
727             .ErrorCode(ERR_ANS_NON_SYSTEM_APP);
728         ReportDeleteFailedEventPush(haMetaMessage, removeReason, message);
729         ANS_LOGE("%{public}s", message.c_str());
730         return ERR_ANS_NON_SYSTEM_APP;
731     }
732 
733     if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) {
734         std::string message = "no acl permission. key:" + key + ".";
735         OHOS::Notification::HaMetaMessage haMetaMessage = HaMetaMessage(4, 2)
736             .ErrorCode(ERR_ANS_PERMISSION_DENIED);
737         ReportDeleteFailedEventPush(haMetaMessage, removeReason, message);
738         ANS_LOGE("%{public}s", message.c_str());
739         return ERR_ANS_PERMISSION_DENIED;
740     }
741 
742     if (notificationSvrQueue_ == nullptr) {
743         std::string message = "Serial queue is invalidated. key:" + key + ".";
744         ANS_LOGE("%{public}s", message.c_str());
745         return ERR_ANS_INVALID_PARAM;
746     }
747 
748     return ExcuteDelete(key, removeReason);
749 }
750 
ExcuteDelete(const std::string & key,const int32_t removeReason)751 ErrCode AdvancedNotificationService::ExcuteDelete(const std::string &key, const int32_t removeReason)
752 {
753     ErrCode result = ERR_OK;
754     ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
755         ANS_LOGD("called");
756         sptr<Notification> notification = nullptr;
757 #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED
758         std::string deviceId;
759         std::string bundleName;
760         GetDistributedInfo(key, deviceId, bundleName);
761 #endif
762         result = RemoveFromNotificationList(key, notification, false, removeReason);
763         if (result != ERR_OK) {
764             return;
765         }
766 
767         if (notification != nullptr) {
768             UpdateRecentNotification(notification, true, removeReason);
769             CancelTimer(notification->GetAutoDeletedTimer());
770             NotificationSubscriberManager::GetInstance()->NotifyCanceled(notification, nullptr, removeReason);
771 #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED
772             DoDistributedDelete(deviceId, bundleName, notification);
773 #endif
774         }
775     }));
776     notificationSvrQueue_->wait(handler);
777 
778     return result;
779 }
780 
DeleteByBundle(const sptr<NotificationBundleOption> & bundleOption)781 ErrCode AdvancedNotificationService::DeleteByBundle(const sptr<NotificationBundleOption> &bundleOption)
782 {
783     ANS_LOGD("called");
784 
785     bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
786     if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
787         ANS_LOGD("VerifyNativeToken is false.");
788         return ERR_ANS_NON_SYSTEM_APP;
789     }
790 
791     if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) {
792         return ERR_ANS_PERMISSION_DENIED;
793     }
794 
795     sptr<NotificationBundleOption> bundle = GenerateValidBundleOption(bundleOption);
796     if (bundle == nullptr) {
797         ANS_LOGD("null bundle");
798         return ERR_ANS_INVALID_BUNDLE;
799     }
800 
801     if (notificationSvrQueue_ == nullptr) {
802         ANS_LOGE("null notificationSvrQueue");
803         return ERR_ANS_INVALID_PARAM;
804     }
805     ErrCode result = ERR_OK;
806     ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
807         ANS_LOGD("ffrt enter!");
808         std::vector<std::string> keys = GetNotificationKeys(bundle);
809         for (auto key : keys) {
810 #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED
811             std::string deviceId;
812             std::string bundleName;
813             GetDistributedInfo(key, deviceId, bundleName);
814 #endif
815             sptr<Notification> notification = nullptr;
816 
817             result = RemoveFromNotificationList(key, notification, false, NotificationConstant::CANCEL_REASON_DELETE);
818             if (result != ERR_OK) {
819                 continue;
820             }
821 
822             if (notification != nullptr) {
823                 int32_t reason = NotificationConstant::CANCEL_REASON_DELETE;
824                 UpdateRecentNotification(notification, true, reason);
825                 CancelTimer(notification->GetAutoDeletedTimer());
826                 NotificationSubscriberManager::GetInstance()->NotifyCanceled(notification, nullptr, reason);
827 #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED
828                 DoDistributedDelete(deviceId, bundleName, notification);
829 #endif
830             }
831         }
832 
833         result = ERR_OK;
834     }));
835     notificationSvrQueue_->wait(handler);
836 
837     return result;
838 }
839 
DeleteAll()840 ErrCode AdvancedNotificationService::DeleteAll()
841 {
842     ANS_LOGD("called");
843 
844     const int32_t reason = NotificationConstant::CANCEL_ALL_REASON_DELETE;
845     bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
846     if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
847         std::string message = "not system app.";
848         OHOS::Notification::HaMetaMessage haMetaMessage = HaMetaMessage(6, 8)
849             .ErrorCode(ERR_ANS_NON_SYSTEM_APP);
850         ReportDeleteFailedEventPush(haMetaMessage, reason, message);
851         ANS_LOGE("%{public}s", message.c_str());
852         return ERR_ANS_NON_SYSTEM_APP;
853     }
854 
855     if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) {
856         std::string message = "no acl permission.";
857         OHOS::Notification::HaMetaMessage haMetaMessage = HaMetaMessage(6, 9)
858             .ErrorCode(ERR_ANS_PERMISSION_DENIED);
859         ReportDeleteFailedEventPush(haMetaMessage, reason, message);
860         ANS_LOGE("%{public}s", message.c_str());
861         return ERR_ANS_PERMISSION_DENIED;
862     }
863 
864     if (notificationSvrQueue_ == nullptr) {
865         std::string message = "Serial queue is invalidity.";
866         ANS_LOGE("%{public}s", message.c_str());
867         return ERR_ANS_INVALID_PARAM;
868     }
869     ErrCode result = ERR_OK;
870     ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
871         ExcuteDeleteAll(result, reason);
872     }));
873     notificationSvrQueue_->wait(handler);
874 
875     return result;
876 }
877 
ExcuteDeleteAll(ErrCode & result,const int32_t reason)878 void AdvancedNotificationService::ExcuteDeleteAll(ErrCode &result, const int32_t reason)
879 {
880     ANS_LOGD("called");
881     int32_t activeUserId = SUBSCRIBE_USER_INIT;
882     if (OsAccountManagerHelper::GetInstance().GetCurrentActiveUserId(activeUserId) != ERR_OK) {
883         return;
884     }
885     std::vector<std::string> keys = GetNotificationKeys(nullptr);
886     std::vector<sptr<Notification>> notifications;
887     std::vector<uint64_t> timerIds;
888     for (auto key : keys) {
889 #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED
890         std::string deviceId;
891         std::string bundleName;
892         GetDistributedInfo(key, deviceId, bundleName);
893 #endif
894         sptr<Notification> notification = nullptr;
895 
896         result = RemoveFromNotificationListForDeleteAll(key, activeUserId, notification);
897         if ((result != ERR_OK) || (notification == nullptr)) {
898             continue;
899         }
900 
901         if (notification->GetUserId() == activeUserId) {
902             UpdateRecentNotification(notification, true, reason);
903             notifications.emplace_back(notification);
904             timerIds.emplace_back(notification->GetAutoDeletedTimer());
905 #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED
906             DoDistributedDelete(deviceId, bundleName, notification);
907 #endif
908         }
909         if (notifications.size() >= MAX_CANCELED_PARCELABLE_VECTOR_NUM) {
910             ANS_LOGD("Notifications size greater than or equal to MAX_CANCELED_PARCELABLE_VECTOR_NUM.");
911             SendNotificationsOnCanceled(notifications, nullptr, reason);
912         }
913     }
914     if (!notifications.empty()) {
915         NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled(
916             notifications, nullptr, reason);
917     }
918     BatchCancelTimer(timerIds);
919     result = ERR_OK;
920 }
921 
RemoveDistributedNotifications(const std::vector<std::string> & hashcodes,const int32_t slotTypeInt,const int32_t deleteTypeInt,const int32_t removeReason,const std::string & deviceId)922 ErrCode AdvancedNotificationService::RemoveDistributedNotifications(
923     const std::vector<std::string>& hashcodes, const int32_t slotTypeInt,
924     const int32_t deleteTypeInt, const int32_t removeReason, const std::string& deviceId)
925 {
926     bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
927     if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
928         ANS_LOGE("IsSystemApp is false.");
929         return ERR_ANS_NON_SYSTEM_APP;
930     }
931 
932     if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) {
933         ANS_LOGE("app no controller");
934         return ERR_ANS_PERMISSION_DENIED;
935     }
936 
937     if (notificationSvrQueue_ == nullptr) {
938         ANS_LOGE("notificationSvrQueue is null");
939         return ERR_ANS_INVALID_PARAM;
940     }
941 
942     NotificationConstant::SlotType slotType = static_cast<NotificationConstant::SlotType>(slotTypeInt);
943     NotificationConstant::DistributedDeleteType deleteType =
944         static_cast<NotificationConstant::DistributedDeleteType>(deleteTypeInt);
945 
946     switch (deleteType) {
947         case NotificationConstant::DistributedDeleteType::ALL:
948             return RemoveAllDistributedNotifications(removeReason);
949         case NotificationConstant::DistributedDeleteType::SLOT:
950         case NotificationConstant::DistributedDeleteType::EXCLUDE_ONE_SLOT:
951             return RemoveDistributedNotifications(slotType, removeReason, deleteType);
952         case NotificationConstant::DistributedDeleteType::HASHCODES:
953             return RemoveDistributedNotifications(hashcodes, removeReason);
954         case NotificationConstant::DistributedDeleteType::DEVICE_ID:
955             return RemoveDistributedNotificationsByDeviceId(deviceId, removeReason);
956         default:
957             ANS_LOGW("no deleteType");
958             break;
959     }
960     return ERR_OK;
961 }
962 
RemoveDistributedNotificationsByDeviceId(const std::string & deviceId,const int32_t removeReason)963 ErrCode AdvancedNotificationService::RemoveDistributedNotificationsByDeviceId(
964     const std::string& deviceId, const int32_t removeReason)
965 {
966     ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([=]() {
967         std::vector<sptr<Notification>> notifications;
968         std::list<std::shared_ptr<NotificationRecord>> deleteRecords;
969         for (auto record : notificationList_) {
970             auto notification = record->notification;
971             if (notification == nullptr) {
972                 continue;
973             }
974             auto request = notification->GetNotificationRequestPoint();
975             if (request == nullptr) {
976                 continue;
977             }
978             auto extendInfo = request->GetExtendInfo();
979             if (extendInfo == nullptr) {
980                 continue;
981             }
982             auto key = ANS_EXTENDINFO_INFO_PRE + ANS_EXTENDINFO_DEVICE_ID;
983             auto id = extendInfo->GetStringParam(key);
984             if (id.empty()) {
985                 continue;
986             }
987             if (id != deviceId) {
988                 continue;
989             }
990 
991             if (ExecuteDeleteDistributedNotification(record, notifications, removeReason)) {
992                 deleteRecords.push_back(record);
993             }
994             if (notifications.size() >= MAX_CANCELED_PARCELABLE_VECTOR_NUM) {
995                 std::vector<sptr<Notification>> currNotificationList = notifications;
996                 NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled(
997                     currNotificationList, nullptr, removeReason);
998                 notifications.clear();
999             }
1000         }
1001 
1002         if (!notifications.empty()) {
1003             NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled(
1004                 notifications, nullptr, removeReason);
1005         }
1006         for (auto deleteRecord : deleteRecords) {
1007             notificationList_.remove(deleteRecord);
1008         }
1009     }));
1010     return ERR_OK;
1011 }
1012 
RemoveDistributedNotifications(const std::vector<std::string> & hashcodes,const int32_t removeReason)1013 ErrCode AdvancedNotificationService::RemoveDistributedNotifications(
1014     const std::vector<std::string>& hashcodes, const int32_t removeReason)
1015 {
1016     ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([=]() {
1017         std::vector<sptr<Notification>> notifications;
1018         std::list<std::shared_ptr<NotificationRecord>> deleteRecords;
1019         for (auto record : notificationList_) {
1020             auto notification = record->notification;
1021             if (notification == nullptr) {
1022                 continue;
1023             }
1024 
1025             auto key = notification->GetKey();
1026             if (std::find(hashcodes.begin(), hashcodes.end(), key) == hashcodes.end()) {
1027                 continue;
1028             }
1029             if (ExecuteDeleteDistributedNotification(record, notifications, removeReason)) {
1030                 deleteRecords.push_back(record);
1031             }
1032             if (notifications.size() >= MAX_CANCELED_PARCELABLE_VECTOR_NUM) {
1033                 std::vector<sptr<Notification>> currNotificationList = notifications;
1034                 NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled(
1035                     currNotificationList, nullptr, removeReason);
1036                 notifications.clear();
1037             }
1038         }
1039 
1040         if (!notifications.empty()) {
1041             NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled(
1042                 notifications, nullptr, removeReason);
1043         }
1044         for (auto deleteRecord : deleteRecords) {
1045             notificationList_.remove(deleteRecord);
1046         }
1047     }));
1048     return ERR_OK;
1049 }
1050 
RemoveDistributedNotifications(const NotificationConstant::SlotType & slotType,const int32_t removeReason,const NotificationConstant::DistributedDeleteType & deleteType)1051 ErrCode AdvancedNotificationService::RemoveDistributedNotifications(
1052     const NotificationConstant::SlotType& slotType, const int32_t removeReason,
1053     const NotificationConstant::DistributedDeleteType& deleteType)
1054 {
1055     ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([=]() {
1056         std::vector<sptr<Notification>> notifications;
1057         std::list<std::shared_ptr<NotificationRecord>> deleteRecords;
1058         for (auto record : notificationList_) {
1059             auto notification = record->notification;
1060             if (notification == nullptr) {
1061                 continue;
1062             }
1063             auto request = notification->GetNotificationRequestPoint();
1064             if (request == nullptr) {
1065                 continue;
1066             }
1067             if (deleteType == NotificationConstant::DistributedDeleteType::EXCLUDE_ONE_SLOT &&
1068                 request->GetSlotType() == slotType) {
1069                 ANS_LOGD("key:%{public}s,ty:%{public}d", request->GetKey().c_str(), request->GetSlotType());
1070                 continue;
1071             }
1072             if (deleteType == NotificationConstant::DistributedDeleteType::SLOT &&
1073                 request->GetSlotType() != slotType) {
1074                 ANS_LOGD("key:%{public}s,ty:%{public}d", request->GetKey().c_str(), request->GetSlotType());
1075                 continue;
1076             }
1077 
1078             if (ExecuteDeleteDistributedNotification(record, notifications, removeReason)) {
1079                 deleteRecords.push_back(record);
1080             }
1081             if (notifications.size() >= MAX_CANCELED_PARCELABLE_VECTOR_NUM) {
1082                 std::vector<sptr<Notification>> currNotificationList = notifications;
1083                 NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled(
1084                     currNotificationList, nullptr, removeReason);
1085                 notifications.clear();
1086             }
1087         }
1088 
1089         if (!notifications.empty()) {
1090             NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled(
1091                 notifications, nullptr, removeReason);
1092         }
1093         for (auto deleteRecord : deleteRecords) {
1094             notificationList_.remove(deleteRecord);
1095         }
1096     }));
1097     return ERR_OK;
1098 }
1099 
RemoveAllDistributedNotifications(const int32_t removeReason)1100 ErrCode AdvancedNotificationService::RemoveAllDistributedNotifications(
1101     const int32_t removeReason)
1102 {
1103     ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([=]() {
1104         std::vector<sptr<Notification>> notifications;
1105         std::list<std::shared_ptr<NotificationRecord>> deleteRecords;
1106         for (auto record : notificationList_) {
1107             if (ExecuteDeleteDistributedNotification(record, notifications, removeReason)) {
1108                 deleteRecords.push_back(record);
1109             }
1110             if (notifications.size() >= MAX_CANCELED_PARCELABLE_VECTOR_NUM) {
1111                 std::vector<sptr<Notification>> currNotificationList = notifications;
1112                 NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled(
1113                     currNotificationList, nullptr, removeReason);
1114                 notifications.clear();
1115             }
1116         }
1117 
1118         if (!notifications.empty()) {
1119             NotificationSubscriberManager::GetInstance()->BatchNotifyCanceled(
1120                 notifications, nullptr, removeReason);
1121         }
1122 
1123         for (auto deleteRecord : deleteRecords) {
1124             notificationList_.remove(deleteRecord);
1125         }
1126     }));
1127     return ERR_OK;
1128 }
1129 
ExecuteDeleteDistributedNotification(std::shared_ptr<NotificationRecord> & record,std::vector<sptr<Notification>> & notifications,const int32_t removeReason)1130 bool AdvancedNotificationService::ExecuteDeleteDistributedNotification(
1131     std::shared_ptr<NotificationRecord>& record,
1132     std::vector<sptr<Notification>>& notifications,
1133     const int32_t removeReason)
1134 {
1135     if (record == nullptr) {
1136         ANS_LOGE("delete record is null");
1137         return false;
1138     }
1139 
1140     auto notification = record->notification;
1141     if (notification == nullptr) {
1142         ANS_LOGE("delete notification is null");
1143         return false;
1144     }
1145 
1146     auto request = notification->GetNotificationRequestPoint();
1147     if (request == nullptr) {
1148         ANS_LOGE("delete request is null");
1149         return false;
1150     }
1151     if (IsDistributedNotification(request)) {
1152         notifications.emplace_back(notification);
1153         CancelTimer(notification->GetAutoDeletedTimer());
1154         ProcForDeleteLiveView(record);
1155         TriggerRemoveWantAgent(request, removeReason, record->isThirdparty);
1156         CancelWantAgent(notification);
1157         return true;
1158     }
1159     ANS_LOGD("delete not distributed, key:%{public}s", request->GetKey().c_str());
1160     return false;
1161 }
1162 
IsDistributedNotification(sptr<NotificationRequest> request)1163 bool AdvancedNotificationService::IsDistributedNotification(sptr<NotificationRequest> request)
1164 {
1165     if (request == nullptr) {
1166         return false;
1167     }
1168 
1169     if (request->GetDistributedCollaborate()) {
1170         return true;
1171     }
1172     return false;
1173 }
1174 }  // namespace Notification
1175 }  // namespace OHOS