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