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