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