1 /*
2  * Copyright (c) 2021-2024 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 <functional>
19 #include <iomanip>
20 #include <sstream>
21 
22 #include "access_token_helper.h"
23 #include "ans_inner_errors.h"
24 #include "ans_log_wrapper.h"
25 #include "ans_permission_def.h"
26 #include "errors.h"
27 #include "common_event_manager.h"
28 #include "common_event_support.h"
29 #include "hitrace_meter_adapter.h"
30 #include "os_account_manager_helper.h"
31 #include "ipc_skeleton.h"
32 #ifdef NOTIFICATION_SMART_REMINDER_SUPPORTED
33 #include "smart_reminder_center.h"
34 #endif
35 
36 #include "advanced_notification_inline.cpp"
37 #include "notification_extension_wrapper.h"
38 #include "notification_analytics_util.h"
39 #include "notification_trust_list.h"
40 
41 namespace OHOS {
42 namespace Notification {
43 namespace {
44     constexpr char KEY_NAME[] = "AGGREGATE_CONFIG";
45     constexpr char CTRL_LIST_KEY_NAME[] = "NOTIFICATION_CTL_LIST_PKG";
46     constexpr char CALL_UI_BUNDLE[] = "com.ohos.callui";
47 }
48 
AddSlots(const std::vector<sptr<NotificationSlot>> &slots)49 ErrCode AdvancedNotificationService::AddSlots(const std::vector<sptr<NotificationSlot>> &slots)
50 {
51     ANS_LOGD("%{public}s", __FUNCTION__);
52 
53     bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
54     if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
55         return ERR_ANS_NON_SYSTEM_APP;
56     }
57 
58     if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) {
59         return ERR_ANS_PERMISSION_DENIED;
60     }
61 
62     sptr<NotificationBundleOption> bundleOption = GenerateBundleOption();
63     if (bundleOption == nullptr) {
64         return ERR_ANS_INVALID_BUNDLE;
65     }
66 
67     if (slots.size() == 0) {
68         return ERR_ANS_INVALID_PARAM;
69     }
70 
71     if (notificationSvrQueue_ == nullptr) {
72         ANS_LOGE("Serial queue is invalid.");
73         return ERR_ANS_INVALID_PARAM;
74     }
75     ErrCode result = ERR_OK;
76     ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
77         ANS_LOGD("ffrt enter!");
78         std::vector<sptr<NotificationSlot>> addSlots;
79         for (auto slot : slots) {
80             sptr<NotificationSlot> originalSlot;
81             result =NotificationPreferences::GetInstance()->GetNotificationSlot(bundleOption,
82                 slot->GetType(), originalSlot);
83             if ((result == ERR_OK) && (originalSlot != nullptr)) {
84                 continue;
85             }
86 
87             GenerateSlotReminderMode(slot, bundleOption, true);
88             addSlots.push_back(slot);
89         }
90 
91         if (addSlots.size() == 0) {
92             result = ERR_OK;
93         } else {
94             result = NotificationPreferences::GetInstance()->AddNotificationSlots(bundleOption, addSlots);
95         }
96     }));
97     notificationSvrQueue_->wait(handler);
98     return result;
99 }
100 
GetSlots(std::vector<sptr<NotificationSlot>> &slots)101 ErrCode AdvancedNotificationService::GetSlots(std::vector<sptr<NotificationSlot>> &slots)
102 {
103     ANS_LOGD("%{public}s", __FUNCTION__);
104 
105     sptr<NotificationBundleOption> bundleOption = GenerateBundleOption();
106     if (bundleOption == nullptr) {
107         return ERR_ANS_INVALID_BUNDLE;
108     }
109 
110     if (notificationSvrQueue_ == nullptr) {
111         ANS_LOGE("NotificationSvrQueue_ is nullptr.");
112         return ERR_ANS_INVALID_PARAM;
113     }
114     ErrCode result = ERR_OK;
115     ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
116         ANS_LOGD("ffrt enter!");
117         result = NotificationPreferences::GetInstance()->GetNotificationAllSlots(bundleOption, slots);
118         if (result == ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST) {
119             result = ERR_OK;
120             slots.clear();
121         }
122     }));
123     notificationSvrQueue_->wait(handler);
124     return result;
125 }
126 
GetSlotsByBundle( const sptr<NotificationBundleOption> &bundleOption, std::vector<sptr<NotificationSlot>> &slots)127 ErrCode AdvancedNotificationService::GetSlotsByBundle(
128     const sptr<NotificationBundleOption> &bundleOption, std::vector<sptr<NotificationSlot>> &slots)
129 {
130     ANS_LOGD("%{public}s", __FUNCTION__);
131 
132     bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
133     if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
134         ANS_LOGD("IsSystemApp is false.");
135         return ERR_ANS_NON_SYSTEM_APP;
136     }
137 
138     if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) {
139         return ERR_ANS_PERMISSION_DENIED;
140     }
141 
142     sptr<NotificationBundleOption> bundle = GenerateValidBundleOption(bundleOption);
143     if (bundle == nullptr) {
144         ANS_LOGD("GenerateValidBundleOption failed.");
145         return ERR_ANS_INVALID_BUNDLE;
146     }
147 
148     if (notificationSvrQueue_ == nullptr) {
149         ANS_LOGE("Serial queue is invalid.");
150         return ERR_ANS_INVALID_PARAM;
151     }
152     ErrCode result = ERR_OK;
153     ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
154         ANS_LOGD("ffrt enter!");
155         result = NotificationPreferences::GetInstance()->GetNotificationAllSlots(bundle, slots);
156         if (result == ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST) {
157             result = ERR_OK;
158             slots.clear();
159         }
160     }));
161 
162     notificationSvrQueue_->wait(handler);
163     return result;
164 }
165 
GetSlotByBundle( const sptr<NotificationBundleOption> &bundleOption, const NotificationConstant::SlotType &slotType, sptr<NotificationSlot> &slot)166 ErrCode AdvancedNotificationService::GetSlotByBundle(
167     const sptr<NotificationBundleOption> &bundleOption, const NotificationConstant::SlotType &slotType,
168     sptr<NotificationSlot> &slot)
169 {
170     ANS_LOGD("%{public}s", __FUNCTION__);
171 
172     bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
173     if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
174         ANS_LOGD("IsSystemApp is false.");
175         return ERR_ANS_NON_SYSTEM_APP;
176     }
177 
178     if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) {
179         return ERR_ANS_PERMISSION_DENIED;
180     }
181 
182     sptr<NotificationBundleOption> bundle = GenerateValidBundleOption(bundleOption);
183     if (bundleOption == nullptr) {
184         ANS_LOGD("Failed to generateBundleOption.");
185         return ERR_ANS_INVALID_BUNDLE;
186     }
187 
188     if (notificationSvrQueue_ == nullptr) {
189         ANS_LOGE("Serial queue is invalid.");
190         return ERR_ANS_INVALID_PARAM;
191     }
192     ErrCode result = ERR_OK;
193     ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
194         ANS_LOGD("ffrt enter!");
195         result = NotificationPreferences::GetInstance()->GetNotificationSlot(bundle, slotType, slot);
196     }));
197     notificationSvrQueue_->wait(handler);
198     if (slot != nullptr) {
199         ANS_LOGD("GetSlotByBundle, authStatus: %{public}d), authHintCnt: %{public}d",
200             slot->GetAuthorizedStatus(), slot->GetAuthHintCnt());
201     }
202     return result;
203 }
204 
UpdateSlots( const sptr<NotificationBundleOption> &bundleOption, const std::vector<sptr<NotificationSlot>> &slots)205 ErrCode AdvancedNotificationService::UpdateSlots(
206     const sptr<NotificationBundleOption> &bundleOption, const std::vector<sptr<NotificationSlot>> &slots)
207 {
208     ANS_LOGD("%{public}s", __FUNCTION__);
209 
210     bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
211     if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
212         return ERR_ANS_NON_SYSTEM_APP;
213     }
214 
215     if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) {
216         ANS_LOGD("AccessTokenHelper::CheckPermission is false.");
217         return ERR_ANS_PERMISSION_DENIED;
218     }
219 
220     sptr<NotificationBundleOption> bundle = GenerateValidBundleOption(bundleOption);
221     if (bundle == nullptr) {
222         return ERR_ANS_INVALID_BUNDLE;
223     }
224 
225     if (notificationSvrQueue_ == nullptr) {
226         ANS_LOGE("notificationSvrQueue_ is nullptr.");
227         return ERR_ANS_INVALID_PARAM;
228     }
229     ErrCode result = ERR_OK;
230     ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
231         ANS_LOGD("ffrt enter!");
232         result = NotificationPreferences::GetInstance()->UpdateNotificationSlots(bundle, slots);
233         if (result == ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST) {
234             result = ERR_ANS_PREFERENCES_NOTIFICATION_SLOT_TYPE_NOT_EXIST;
235         }
236     }));
237     notificationSvrQueue_->wait(handler);
238 
239     if (result == ERR_OK) {
240         PublishSlotChangeCommonEvent(bundle);
241     }
242 
243     return result;
244 }
245 
RemoveAllSlots()246 ErrCode AdvancedNotificationService::RemoveAllSlots()
247 {
248     ANS_LOGD("%{public}s", __FUNCTION__);
249 
250     sptr<NotificationBundleOption> bundleOption = GenerateBundleOption();
251     if (bundleOption == nullptr) {
252         ANS_LOGD("GenerateBundleOption defeat.");
253         return ERR_ANS_INVALID_BUNDLE;
254     }
255 
256     if (notificationSvrQueue_ == nullptr) {
257         ANS_LOGE("Serial queue is invalid.");
258         return ERR_ANS_INVALID_PARAM;
259     }
260     ErrCode result = ERR_OK;
261     ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
262         ANS_LOGD("ffrt enter!");
263         sptr<NotificationSlot> liveViewSlot;
264 
265         bool isLiveViewSlotExist = true;
266         // retain liveview slot before removeNotificationAllSlots
267         if (NotificationPreferences::GetInstance()->GetNotificationSlot(
268             bundleOption, NotificationConstant::SlotType::LIVE_VIEW, liveViewSlot) != ERR_OK) {
269             isLiveViewSlotExist = false;
270         }
271 
272         result = NotificationPreferences::GetInstance()->RemoveNotificationAllSlots(bundleOption);
273         if (result == ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST) {
274             result = ERR_OK;
275         }
276 
277         if (!isLiveViewSlotExist) {
278             return;
279         }
280         // retain liveview slot when caller is not sa or systemapp
281         if ((result == ERR_OK) &&
282             (IsAllowedRemoveSlot(bundleOption, NotificationConstant::SlotType::LIVE_VIEW) != ERR_OK)) {
283             std::vector<sptr<NotificationSlot>> slots;
284 
285             slots.push_back(liveViewSlot);
286             (void)NotificationPreferences::GetInstance()->AddNotificationSlots(bundleOption, slots);
287         }
288     }));
289     notificationSvrQueue_->wait(handler);
290     return result;
291 }
292 
AddSlotByType(NotificationConstant::SlotType slotType)293 ErrCode AdvancedNotificationService::AddSlotByType(NotificationConstant::SlotType slotType)
294 {
295     ANS_LOGD("%{public}s", __FUNCTION__);
296 
297     if (!AccessTokenHelper::IsSystemApp() && slotType == NotificationConstant::SlotType::EMERGENCY_INFORMATION) {
298         ANS_LOGE("Non system app used illegal slot type.");
299         return ERR_ANS_INVALID_PARAM;
300     }
301 
302     sptr<NotificationBundleOption> bundleOption = GenerateBundleOption();
303     if (bundleOption == nullptr) {
304         return ERR_ANS_INVALID_BUNDLE;
305     }
306 
307     if (notificationSvrQueue_ == nullptr) {
308         ANS_LOGE("Serial queue is invalidity.");
309         return ERR_ANS_INVALID_PARAM;
310     }
311     ErrCode result = ERR_OK;
312     ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
313         ANS_LOGD("ffrt enter!");
314         sptr<NotificationSlot> slot;
315         result = NotificationPreferences::GetInstance()->GetNotificationSlot(bundleOption, slotType, slot);
316         if ((result == ERR_OK) && (slot != nullptr)) {
317             return;
318         }
319 
320         slot = new (std::nothrow) NotificationSlot(slotType);
321         if (slot == nullptr) {
322             ANS_LOGE("Failed to create NotificationSlot instance");
323             return;
324         }
325 
326         GenerateSlotReminderMode(slot, bundleOption);
327         std::vector<sptr<NotificationSlot>> slots;
328         slots.push_back(slot);
329         result = NotificationPreferences::GetInstance()->AddNotificationSlots(bundleOption, slots);
330     }));
331     notificationSvrQueue_->wait(handler);
332     return result;
333 }
334 
GetEnabledForBundleSlotSelf( const NotificationConstant::SlotType &slotType, bool &enabled)335 ErrCode AdvancedNotificationService::GetEnabledForBundleSlotSelf(
336     const NotificationConstant::SlotType &slotType, bool &enabled)
337 {
338     ANS_LOGD("slotType: %{public}d", slotType);
339 
340     sptr<NotificationBundleOption> bundleOption = GenerateBundleOption();
341     if (bundleOption == nullptr) {
342         return ERR_ANS_INVALID_BUNDLE;
343     }
344 
345     if (notificationSvrQueue_ == nullptr) {
346         ANS_LOGE("Serial queue is invalid.");
347         return ERR_ANS_INVALID_PARAM;
348     }
349     ErrCode result = ERR_OK;
350     ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
351         ANS_LOGD("ffrt enter!");
352         sptr<NotificationSlot> slot;
353         result = NotificationPreferences::GetInstance()->GetNotificationSlot(bundleOption, slotType, slot);
354         if (result != ERR_OK) {
355             ANS_LOGE("Get enable slot self: GetNotificationSlot failed");
356             return;
357         }
358         if (slot == nullptr) {
359             ANS_LOGW("Get enable slot: object is null, enabled default true");
360             enabled = true;
361             result = ERR_OK;
362             return;
363         }
364         enabled = slot->GetEnable();
365     }));
366     notificationSvrQueue_->wait(handler);
367 
368     return result;
369 }
370 
GetSlotFlagsAsBundle(const sptr<NotificationBundleOption> &bundleOption, uint32_t &slotFlags)371 ErrCode AdvancedNotificationService::GetSlotFlagsAsBundle(const sptr<NotificationBundleOption> &bundleOption,
372     uint32_t &slotFlags)
373 {
374     ANS_LOGD("%{public}s", __FUNCTION__);
375     bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
376     if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
377         return ERR_ANS_NON_SYSTEM_APP;
378     }
379 
380     if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) {
381         return ERR_ANS_PERMISSION_DENIED;
382     }
383 
384     sptr<NotificationBundleOption> bundle = GenerateValidBundleOption(bundleOption);
385     if (bundle == nullptr) {
386         ANS_LOGD("Bundle is null.");
387         return ERR_ANS_INVALID_BUNDLE;
388     }
389 
390     if (notificationSvrQueue_ == nullptr) {
391         ANS_LOGE("Serial queue is invalid.");
392         return ERR_ANS_INVALID_PARAM;
393     }
394     ErrCode result = ERR_OK;
395     ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
396         ANS_LOGD("ffrt enter!");
397         result = NotificationPreferences::GetInstance()->GetNotificationSlotFlagsForBundle(bundle, slotFlags);
398         if (result == ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST) {
399             result = ERR_OK;
400             slotFlags = DEFAULT_SLOT_FLAGS;
401         }
402     }));
403     notificationSvrQueue_->wait(handler);
404 
405     return result;
406 }
407 
SetSlotFlagsAsBundle(const sptr<NotificationBundleOption> &bundleOption, uint32_t slotFlags)408 ErrCode AdvancedNotificationService::SetSlotFlagsAsBundle(const sptr<NotificationBundleOption> &bundleOption,
409     uint32_t slotFlags)
410 {
411     ANS_LOGD("%{public}s", __FUNCTION__);
412     if (bundleOption == nullptr) {
413         ANS_LOGD("BundleOption is null.");
414         return ERR_ANS_INVALID_BUNDLE;
415     }
416 
417     bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
418     if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
419         ANS_LOGD("IsSystemApp is false.");
420         return ERR_ANS_NON_SYSTEM_APP;
421     }
422 
423     if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) {
424         return ERR_ANS_PERMISSION_DENIED;
425     }
426 
427     sptr<NotificationBundleOption> bundle = GenerateValidBundleOption(bundleOption);
428     if (bundle == nullptr) {
429         ANS_LOGD("Bundle is null.");
430         return ERR_ANS_INVALID_BUNDLE;
431     }
432 
433     if (notificationSvrQueue_ == nullptr) {
434         ANS_LOGE("Serial queue is invalidity.");
435         return ERR_ANS_INVALID_PARAM;
436     }
437     ErrCode result = ERR_OK;
438     ffrt::task_handle handler = notificationSvrQueue_->submit_h(
439         std::bind([&]() {
440             result = NotificationPreferences::GetInstance()->SetNotificationSlotFlagsForBundle(bundle, slotFlags);
441             if (result != ERR_OK) {
442                 return;
443             }
444             ANS_LOGI("Set slotflags %{public}d to %{public}s.", slotFlags, bundle->GetBundleName().c_str());
445             result = UpdateSlotReminderModeBySlotFlags(bundle, slotFlags);
446         }));
447     notificationSvrQueue_->wait(handler);
448     HaMetaMessage message = HaMetaMessage(EventSceneId::SCENE_4, EventBranchId::BRANCH_2)
449         .Message("Set slotflags " + bundleOption->GetBundleName() + " flag " +
450         std::to_string(slotFlags) + " ret " + std::to_string(result));
451     NotificationAnalyticsUtil::ReportModifyEvent(message);
452     return result;
453 }
454 
AssignValidNotificationSlot(const std::shared_ptr<NotificationRecord> &record, const sptr<NotificationBundleOption> &bundleOption)455 ErrCode AdvancedNotificationService::AssignValidNotificationSlot(const std::shared_ptr<NotificationRecord> &record,
456     const sptr<NotificationBundleOption> &bundleOption)
457 {
458     sptr<NotificationSlot> slot;
459     NotificationConstant::SlotType slotType = record->request->GetSlotType();
460     HaMetaMessage message = HaMetaMessage(EventSceneId::SCENE_7, EventBranchId::BRANCH_3).SlotType(slotType);
461     ErrCode result = NotificationPreferences::GetInstance()->GetNotificationSlot(bundleOption, slotType, slot);
462     if ((result == ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST) ||
463         (result == ERR_ANS_PREFERENCES_NOTIFICATION_SLOT_TYPE_NOT_EXIST)) {
464         slot = new (std::nothrow) NotificationSlot(slotType);
465         if (slot == nullptr) {
466             ANS_LOGE("Failed to create NotificationSlot instance");
467             return ERR_NO_MEMORY;
468         }
469 
470         GenerateSlotReminderMode(slot, bundleOption);
471         std::vector<sptr<NotificationSlot>> slots;
472         slots.push_back(slot);
473         result = NotificationPreferences::GetInstance()->AddNotificationSlots(bundleOption, slots);
474     }
475     if (result == ERR_OK) {
476         if (slot != nullptr &&
477             (bundleOption->GetBundleName() == CALL_UI_BUNDLE || slot->GetEnable() ||
478             (record->request->GetAgentBundle() != nullptr && record->request->IsSystemLiveView()) ||
479             (slot->GetType() == NotificationConstant::SlotType::LIVE_VIEW &&
480             DelayedSingleton<NotificationTrustList>::GetInstance()->IsLiveViewTrtust(bundleOption->GetBundleName())))) {
481             record->slot = slot;
482         } else {
483             message.ErrorCode(ERR_ANS_PREFERENCES_NOTIFICATION_SLOT_ENABLED);
484             NotificationAnalyticsUtil::ReportPublishFailedEvent(record->request, message);
485             result = ERR_ANS_PREFERENCES_NOTIFICATION_SLOT_ENABLED;
486             ANS_LOGE("Type[%{public}d] slot enable closed", slotType);
487         }
488     }
489     if (result != ERR_OK) {
490         message.ErrorCode(result).Message("assign slot failed");
491         NotificationAnalyticsUtil::ReportPublishFailedEvent(record->request, message);
492     }
493     return result;
494 }
495 
UpdateSlotReminderModeBySlotFlags( const sptr<NotificationBundleOption> &bundle, uint32_t slotFlags)496 ErrCode AdvancedNotificationService::UpdateSlotReminderModeBySlotFlags(
497     const sptr<NotificationBundleOption> &bundle, uint32_t slotFlags)
498 {
499     std::vector<sptr<NotificationSlot>> slots;
500     HaMetaMessage message = HaMetaMessage(EventSceneId::SCENE_3, EventBranchId::BRANCH_1);
501     ErrCode ret = NotificationPreferences::GetInstance()->GetNotificationAllSlots(bundle, slots);
502     if (ret != ERR_OK) {
503         message.Message("Failed to get slots by bundle, ret:" + std::to_string(ret), true);
504         NotificationAnalyticsUtil::ReportModifyEvent(message);
505         return ret;
506     }
507 
508     message.BundleName((bundle == nullptr) ? "" : bundle->GetBundleName());
509     if (slots.empty()) {
510         message.Message("The bundle has no slots.", true);
511         NotificationAnalyticsUtil::ReportModifyEvent(message);
512         return ERR_OK;
513     }
514 
515     for (auto slot : slots) {
516         auto configSlotReminderMode =
517             DelayedSingleton<NotificationConfigParse>::GetInstance()->GetConfigSlotReminderModeByType(slot->GetType());
518         slot->SetReminderMode(slotFlags & configSlotReminderMode);
519         std::string bundleName = (bundle == nullptr) ? "" : bundle->GetBundleName();
520         ANS_LOGD("Update reminderMode of %{public}d in %{public}s, value is %{public}d.",
521             slot->GetType(), bundleName.c_str(), slot->GetReminderMode());
522     }
523 
524     ret = NotificationPreferences::GetInstance()->UpdateNotificationSlots(bundle, slots);
525     if (ret == ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST) {
526         ret = ERR_ANS_PREFERENCES_NOTIFICATION_SLOT_TYPE_NOT_EXIST;
527     }
528     return ret;
529 }
530 
GenerateSlotReminderMode(const sptr<NotificationSlot> &slot, const sptr<NotificationBundleOption> &bundle, bool isSpecifiedSlot, uint32_t defaultSlotFlags)531 void AdvancedNotificationService::GenerateSlotReminderMode(const sptr<NotificationSlot> &slot,
532     const sptr<NotificationBundleOption> &bundle, bool isSpecifiedSlot, uint32_t defaultSlotFlags)
533 {
534     uint32_t slotFlags = defaultSlotFlags;
535     auto ret = NotificationPreferences::GetInstance()->GetNotificationSlotFlagsForBundle(bundle, slotFlags);
536     if (ret != ERR_OK) {
537         ANS_LOGI("Failed to get slotflags for bundle, use default slotflags.");
538     }
539 
540     auto configSlotReminderMode =
541         DelayedSingleton<NotificationConfigParse>::GetInstance()->GetConfigSlotReminderModeByType(slot->GetType());
542     if (isSpecifiedSlot) {
543         slot->SetReminderMode(configSlotReminderMode & slotFlags & slot->GetReminderMode());
544     } else {
545         slot->SetReminderMode(configSlotReminderMode & slotFlags);
546     }
547 
548     std::string bundleName = (bundle == nullptr) ? "" : bundle->GetBundleName();
549     ANS_LOGI("The reminder mode of %{public}d is %{public}d in %{public}s",
550         slot->GetType(), slot->GetReminderMode(), bundleName.c_str());
551 }
552 
GetDefaultSlotFlags(const sptr<NotificationRequest> &request)553 uint32_t AdvancedNotificationService::GetDefaultSlotFlags(const sptr<NotificationRequest> &request)
554 {
555     auto flags = DEFAULT_SLOT_FLAGS;
556     uint32_t notificationControlFlags = request->GetNotificationControlFlags();
557     // SA publish own's notification with banner
558     if (((notificationControlFlags & NotificationConstant::ReminderFlag::SA_SELF_BANNER_FLAG) != 0) &&
559         (request->GetCreatorUid() == IPCSkeleton::GetCallingUid() && request->GetCreatorBundleName().empty() &&
560         request->GetOwnerBundleName().empty() && request->GetOwnerUid() == DEFAULT_UID)) {
561         return (flags |= NotificationConstant::ReminderFlag::BANNER_FLAG);
562     }
563 
564     return flags;
565 }
566 
SetRequestBySlotType(const sptr<NotificationRequest> &request, const sptr<NotificationBundleOption> &bundleOption)567 void AdvancedNotificationService::SetRequestBySlotType(const sptr<NotificationRequest> &request,
568     const sptr<NotificationBundleOption> &bundleOption)
569 {
570     ANS_LOGD("Called.");
571     NotificationConstant::SlotType type = request->GetSlotType();
572     auto flags = std::make_shared<NotificationFlags>();
573 
574     sptr<NotificationSlot> slot;
575     NotificationConstant::SlotType slotType = request->GetSlotType();
576     ErrCode result = NotificationPreferences::GetInstance()->GetNotificationSlot(bundleOption, slotType, slot);
577     if (slot == nullptr) {
578         slot = new (std::nothrow) NotificationSlot(slotType);
579         if (slot == nullptr) {
580             ANS_LOGE("Failed to create NotificationSlot instance");
581             return;
582         }
583         uint32_t slotFlags = GetDefaultSlotFlags(request);
584         GenerateSlotReminderMode(slot, bundleOption, false, slotFlags);
585     }
586 
587     auto slotReminderMode = slot->GetReminderMode();
588     if ((slotReminderMode & NotificationConstant::ReminderFlag::SOUND_FLAG) != 0) {
589         flags->SetSoundEnabled(NotificationConstant::FlagStatus::OPEN);
590     }
591 
592     if ((slotReminderMode & NotificationConstant::ReminderFlag::LOCKSCREEN_FLAG) != 0) {
593         flags->SetLockScreenVisblenessEnabled(true);
594     }
595 
596     if ((slotReminderMode & NotificationConstant::ReminderFlag::BANNER_FLAG) != 0) {
597         flags->SetBannerEnabled(true);
598     }
599 
600     if ((slotReminderMode & NotificationConstant::ReminderFlag::LIGHTSCREEN_FLAG) != 0) {
601         flags->SetLightScreenEnabled(true);
602     }
603 
604     if ((slotReminderMode & NotificationConstant::ReminderFlag::VIBRATION_FLAG) != 0) {
605         flags->SetVibrationEnabled(NotificationConstant::FlagStatus::OPEN);
606     }
607 
608     if ((slotReminderMode & NotificationConstant::ReminderFlag::STATUSBAR_ICON_FLAG) != 0) {
609         flags->SetStatusIconEnabled(true);
610     }
611 
612     request->SetFlags(flags);
613     ANS_LOGI("SetFlags-GetRemindMode, notificationKey = %{public}s flags = %{public}d",
614         request->GetKey().c_str(), flags->GetReminderFlags());
615 #ifdef NOTIFICATION_SMART_REMINDER_SUPPORTED
616     DelayedSingleton<SmartReminderCenter>::GetInstance()->ReminderDecisionProcess(request);
617 #endif
618 }
619 
GetSlotByType( const NotificationConstant::SlotType &slotType, sptr<NotificationSlot> &slot)620 ErrCode AdvancedNotificationService::GetSlotByType(
621     const NotificationConstant::SlotType &slotType, sptr<NotificationSlot> &slot)
622 {
623     ANS_LOGD("%{public}s", __FUNCTION__);
624 
625     sptr<NotificationBundleOption> bundleOption = GenerateBundleOption();
626     if (bundleOption == nullptr) {
627         ANS_LOGD("Failed to generateBundleOption.");
628         return ERR_ANS_INVALID_BUNDLE;
629     }
630 
631     if (notificationSvrQueue_ == nullptr) {
632         ANS_LOGE("Serial queue is invalid.");
633         return ERR_ANS_INVALID_PARAM;
634     }
635     ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
636         ANS_LOGD("ffrt enter!");
637         NotificationPreferences::GetInstance()->GetNotificationSlot(bundleOption, slotType, slot);
638     }));
639     notificationSvrQueue_->wait(handler);
640     // if get slot failed, it still return ok.
641     return ERR_OK;
642 }
643 
RemoveSlotByType(const NotificationConstant::SlotType &slotType)644 ErrCode AdvancedNotificationService::RemoveSlotByType(const NotificationConstant::SlotType &slotType)
645 {
646     ANS_LOGD("%{public}s", __FUNCTION__);
647 
648     sptr<NotificationBundleOption> bundleOption = GenerateBundleOption();
649     if (bundleOption == nullptr) {
650         return ERR_ANS_INVALID_BUNDLE;
651     }
652 
653     if (notificationSvrQueue_ == nullptr) {
654         ANS_LOGE("notificationSvrQueue_ is nullptr.");
655         return ERR_ANS_INVALID_PARAM;
656     }
657 
658     ErrCode result = ERR_OK;
659     ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
660         ANS_LOGD("ffrt enter!");
661         result = IsAllowedRemoveSlot(bundleOption, slotType);
662         if (result != ERR_OK) {
663             ANS_LOGE("Liveview slot cann't remove.");
664             return;
665         }
666 
667         NotificationPreferences::GetInstance()->RemoveNotificationSlot(bundleOption, slotType);
668     }));
669     notificationSvrQueue_->wait(handler);
670     // if remove slot failed, it still return ok.
671     return result;
672 }
673 
GetSlotNumAsBundle( const sptr<NotificationBundleOption> &bundleOption, uint64_t &num)674 ErrCode AdvancedNotificationService::GetSlotNumAsBundle(
675     const sptr<NotificationBundleOption> &bundleOption, uint64_t &num)
676 {
677     ANS_LOGD("%{public}s", __FUNCTION__);
678 
679     bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
680     if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
681         return ERR_ANS_NON_SYSTEM_APP;
682     }
683 
684     if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) {
685         return ERR_ANS_PERMISSION_DENIED;
686     }
687 
688     sptr<NotificationBundleOption> bundle = GenerateValidBundleOption(bundleOption);
689     if (bundle == nullptr) {
690         ANS_LOGD("Bundle is null.");
691         return ERR_ANS_INVALID_BUNDLE;
692     }
693 
694     if (notificationSvrQueue_ == nullptr) {
695         ANS_LOGE("Serial queue is invalid.");
696         return ERR_ANS_INVALID_PARAM;
697     }
698     ErrCode result = ERR_OK;
699     ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
700         ANS_LOGD("ffrt enter!");
701         result = NotificationPreferences::GetInstance()->GetNotificationSlotsNumForBundle(bundle, num);
702         if (result == ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST) {
703             result = ERR_OK;
704             num = 0;
705         }
706     }));
707     notificationSvrQueue_->wait(handler);
708 
709     return result;
710 }
711 
AddSlotThenPublishEvent( const sptr<NotificationSlot> &slot, const sptr<NotificationBundleOption> &bundle, bool enabled, bool isForceControl)712 ErrCode AdvancedNotificationService::AddSlotThenPublishEvent(
713     const sptr<NotificationSlot> &slot,
714     const sptr<NotificationBundleOption> &bundle,
715     bool enabled, bool isForceControl)
716 {
717     bool allowed = false;
718     ErrCode result = NotificationPreferences::GetInstance()->GetNotificationsEnabledForBundle(bundle, allowed);
719     if (result == ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST) {
720         result = ERR_OK;
721         allowed = CheckApiCompatibility(bundle);
722         SetDefaultNotificationEnabled(bundle, allowed);
723     }
724 
725     slot->SetEnable(enabled);
726     slot->SetForceControl(isForceControl);
727     slot->SetAuthorizedStatus(NotificationSlot::AuthorizedStatus::AUTHORIZED);
728     std::vector<sptr<NotificationSlot>> slots;
729     slots.push_back(slot);
730     result = NotificationPreferences::GetInstance()->AddNotificationSlots(bundle, slots);
731     if (result != ERR_OK) {
732         ANS_LOGE("Set enable slot: AddNotificationSlot failed");
733         return result;
734     }
735 
736     if (!slot->GetEnable()) {
737         RemoveNotificationBySlot(bundle, slot, NotificationConstant::DISABLE_SLOT_REASON_DELETE);
738     } else {
739         if (!slot->GetForceControl() && !allowed) {
740             RemoveNotificationBySlot(bundle, slot, NotificationConstant::DISABLE_NOTIFICATION_REASON_DELETE);
741         }
742     }
743 
744     PublishSlotChangeCommonEvent(bundle);
745     return result;
746 }
747 
SetEnabledForBundleSlotInner( const sptr<NotificationBundleOption> &bundleOption, const sptr<NotificationBundleOption> &bundle, const NotificationConstant::SlotType &slotType, bool enabled, bool isForceControl)748 ErrCode AdvancedNotificationService::SetEnabledForBundleSlotInner(
749     const sptr<NotificationBundleOption> &bundleOption,
750     const sptr<NotificationBundleOption> &bundle,
751     const NotificationConstant::SlotType &slotType, bool enabled, bool isForceControl)
752 {
753     sptr<NotificationSlot> slot;
754     ErrCode result = NotificationPreferences::GetInstance()->GetNotificationSlot(bundle, slotType, slot);
755     if (result == ERR_ANS_PREFERENCES_NOTIFICATION_SLOT_TYPE_NOT_EXIST ||
756         result == ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST) {
757         slot = new (std::nothrow) NotificationSlot(slotType);
758         if (slot == nullptr) {
759             ANS_LOGE("Failed to create NotificationSlot ptr.");
760             return ERR_ANS_NO_MEMORY;
761         }
762         GenerateSlotReminderMode(slot, bundleOption);
763         return AddSlotThenPublishEvent(slot, bundle, enabled, isForceControl);
764     } else if ((result == ERR_OK) && (slot != nullptr)) {
765         if (slot->GetEnable() == enabled && slot->GetForceControl() == isForceControl) {
766             slot->SetAuthorizedStatus(NotificationSlot::AuthorizedStatus::AUTHORIZED);
767             std::vector<sptr<NotificationSlot>> slots;
768             slots.push_back(slot);
769             return NotificationPreferences::GetInstance()->AddNotificationSlots(bundle, slots);
770         }
771         NotificationPreferences::GetInstance()->RemoveNotificationSlot(bundle, slotType);
772         return AddSlotThenPublishEvent(slot, bundle, enabled, isForceControl);
773     } else {
774         ANS_LOGE("Set enable slot: GetNotificationSlot failed");
775         return result;
776     }
777 }
778 
SetEnabledForBundleSlot(const sptr<NotificationBundleOption> &bundleOption, const NotificationConstant::SlotType &slotType, bool enabled, bool isForceControl)779 ErrCode AdvancedNotificationService::SetEnabledForBundleSlot(const sptr<NotificationBundleOption> &bundleOption,
780     const NotificationConstant::SlotType &slotType, bool enabled, bool isForceControl)
781 {
782     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
783     ANS_LOGD("slotType: %{public}d, enabled: %{public}d, isForceControl: %{public}d",
784         slotType, enabled, isForceControl);
785 
786     ErrCode result = CheckCommonParams();
787     if (result != ERR_OK) {
788         return result;
789     }
790 
791     sptr<NotificationBundleOption> bundle = GenerateValidBundleOption(bundleOption);
792     if (bundle == nullptr) {
793         return ERR_ANS_INVALID_BUNDLE;
794     }
795 
796     ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
797         result = SetEnabledForBundleSlotInner(bundleOption, bundle, slotType, enabled, isForceControl);
798     }));
799     notificationSvrQueue_->wait(handler);
800 
801     SendEnableNotificationSlotHiSysEvent(bundleOption, slotType, enabled, result);
802     return result;
803 }
804 
GetEnabledForBundleSlot( const sptr<NotificationBundleOption> &bundleOption, const NotificationConstant::SlotType &slotType, bool &enabled)805 ErrCode AdvancedNotificationService::GetEnabledForBundleSlot(
806     const sptr<NotificationBundleOption> &bundleOption, const NotificationConstant::SlotType &slotType, bool &enabled)
807 {
808     ANS_LOGD("slotType: %{public}d", slotType);
809 
810     bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
811     if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
812         ANS_LOGD("VerifyNativeToken and isSystemApp failed.");
813         return ERR_ANS_NON_SYSTEM_APP;
814     }
815 
816     if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) {
817         return ERR_ANS_PERMISSION_DENIED;
818     }
819 
820     sptr<NotificationBundleOption> bundle = GenerateValidBundleOption(bundleOption);
821     if (bundle == nullptr) {
822         return ERR_ANS_INVALID_BUNDLE;
823     }
824 
825     if (notificationSvrQueue_ == nullptr) {
826         ANS_LOGE("Serial queue is invalid.");
827         return ERR_ANS_INVALID_PARAM;
828     }
829     ErrCode result = ERR_OK;
830     ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
831         ANS_LOGD("ffrt enter!");
832         sptr<NotificationSlot> slot;
833         result = NotificationPreferences::GetInstance()->GetNotificationSlot(bundle, slotType, slot);
834         if (result != ERR_OK) {
835             ANS_LOGE("Get enable slot: GetNotificationSlot failed");
836             return;
837         }
838         if (slot == nullptr) {
839             ANS_LOGW("Get enable slot: object is null, enabled default true");
840             enabled = true;
841             result = ERR_OK;
842             return;
843         }
844         enabled = slot->GetEnable();
845     }));
846     notificationSvrQueue_->wait(handler);
847 
848     return result;
849 }
850 
GetAllNotificationEnabledBundles( std::vector<NotificationBundleOption> &bundleOption)851 ErrCode AdvancedNotificationService::GetAllNotificationEnabledBundles(
852     std::vector<NotificationBundleOption> &bundleOption)
853 {
854     ANS_LOGD("Called.");
855     if (!AccessTokenHelper::IsSystemApp()) {
856         ANS_LOGE("Is not system app.");
857         return ERR_ANS_NON_SYSTEM_APP;
858     }
859     if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) {
860         ANS_LOGE("Permission denied.");
861         return ERR_ANS_PERMISSION_DENIED;
862     }
863     if (notificationSvrQueue_ == nullptr) {
864         ANS_LOGE("Serial queue is invalid.");
865         return ERR_ANS_INVALID_PARAM;
866     }
867     ErrCode result = ERR_OK;
868     ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
869         ANS_LOGD("ffrt enter!");
870         result = NotificationPreferences::GetInstance()->GetAllNotificationEnabledBundles(bundleOption);
871         if (result != ERR_OK) {
872             ANS_LOGE("Get all notification enable status failed");
873             return;
874         }
875     }));
876     notificationSvrQueue_->wait(handler);
877 
878     return result;
879 }
880 
PublishSlotChangeCommonEvent(const sptr<NotificationBundleOption> &bundleOption)881 bool AdvancedNotificationService::PublishSlotChangeCommonEvent(const sptr<NotificationBundleOption> &bundleOption)
882 {
883     if (bundleOption == nullptr) {
884         return false;
885     }
886     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
887     ANS_LOGD("bundle [%{public}s : %{public}d]", bundleOption->GetBundleName().c_str(), bundleOption->GetUid());
888 
889     EventFwk::Want want;
890     AppExecFwk::ElementName element;
891     element.SetBundleName(bundleOption->GetBundleName());
892     want.SetElement(element);
893     want.SetParam(AppExecFwk::Constants::UID, bundleOption->GetUid());
894     want.SetAction(EventFwk::CommonEventSupport::COMMON_EVENT_SLOT_CHANGE);
895     EventFwk::CommonEventData commonData {want};
896     if (!EventFwk::CommonEventManager::PublishCommonEvent(commonData)) {
897         ANS_LOGE("PublishCommonEvent failed");
898         return false;
899     }
900 
901     return true;
902 }
903 
SetAdditionConfig(const std::string &key, const std::string &value)904 ErrCode AdvancedNotificationService::SetAdditionConfig(const std::string &key, const std::string &value)
905 {
906     ANS_LOGD("SetAdditionConfig called (%{public}s, %{public}s).", key.c_str(), value.c_str());
907     if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_AGENT_CONTROLLER)) {
908         return ERR_ANS_PERMISSION_DENIED;
909     }
910 
911     HaMetaMessage message = HaMetaMessage(EventSceneId::SCENE_8, EventBranchId::BRANCH_1);
912     if (notificationSvrQueue_ == nullptr) {
913         ANS_LOGE("Serial queue is invalid.");
914         return ERR_ANS_INVALID_PARAM;
915     }
916 
917     if (key == RING_TRUST_PKG_KEY) {
918         std::lock_guard<std::mutex> lock(soundPermissionInfo_->dbMutex_);
919         soundPermissionInfo_->needUpdateCache_ = true;
920     }
921 
922     bool isSyncConfig = (strcmp(key.c_str(), KEY_NAME) == 0 ||
923         strcmp(key.c_str(), CTRL_LIST_KEY_NAME) == 0);
924     if (isSyncConfig) {
925 #ifdef ENABLE_ANS_EXT_WRAPPER
926     ErrCode sync_result = EXTENTION_WRAPPER->SyncAdditionConfig(key, value);
927     if (sync_result != ERR_OK) {
928         message.Message("Set addition config " + key + " ret " + std::to_string(sync_result));
929         message.ErrorCode(sync_result);
930         NotificationAnalyticsUtil::ReportModifyEvent(message);
931         return sync_result;
932     }
933 #endif
934     }
935     ErrCode result = ERR_OK;
936     ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
937         ANS_LOGD("ffrt enter!");
938         result = NotificationPreferences::GetInstance()->SetKvToDb(key, value, SUBSCRIBE_USER_INIT);
939     }));
940     notificationSvrQueue_->wait(handler);
941     if (result != ERR_OK) {
942         message.ErrorCode(result);
943         message.Message("Set addition config " + key + " ret " + std::to_string(result));
944         NotificationAnalyticsUtil::ReportModifyEvent(message);
945     }
946     return result;
947 }
948 
IsAgentRelationship(const std::string &agentBundleName, const std::string &sourceBundleName)949 bool AdvancedNotificationService::IsAgentRelationship(const std::string &agentBundleName,
950     const std::string &sourceBundleName)
951 {
952     return NotificationPreferences::GetInstance()->IsAgentRelationship(agentBundleName, sourceBundleName);
953 }
954 }  // namespace Notification
955 }  // namespace OHOS
956