1 /*
2 * Copyright (c) 2023-2023 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 "cpp/task.h"
19 #include "errors.h"
20 #include "ans_inner_errors.h"
21 #include "notification_constant.h"
22 #include "notification_record.h"
23 #include "notification_request.h"
24 #include "want_params_wrapper.h"
25 #include "notification_preferences.h"
26 #include "access_token_helper.h"
27 #include "accesstoken_kit.h"
28 #include "ipc_skeleton.h"
29 #include "image_source.h"
30 #include "os_account_manager_helper.h"
31 #include "time_service_client.h"
32 #include "notification_timer_info.h"
33 #include "advanced_notification_inline.h"
34 #include <cstdint>
35 #include <memory>
36 #include "notification_analytics_util.h"
37 #include "aes_gcm_helper.h"
38
39 namespace OHOS {
40 namespace Notification {
41 const std::string LOCK_SCREEN_PICTURE_TAG = "lock_screen_picture";
42 const std::string PROGRESS_VALUE = "progressValue";
43 constexpr int32_t BGTASK_UID = 3051;
44 constexpr int32_t TYPE_CODE_DOWNLOAD = 8;
RecoverLiveViewFromDb(int32_t userId)45 void AdvancedNotificationService::RecoverLiveViewFromDb(int32_t userId)
46 {
47 if (notificationSvrQueue_ == nullptr) {
48 ANS_LOGE("notificationSvrQueue_ is nullptr.");
49 return;
50 }
51 ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([=]() {
52 ANS_LOGI("Start recover live view from db. userId:%{public}d", userId);
53 std::vector<NotificationRequestDb> requestsdb;
54 if (GetBatchNotificationRequestsFromDb(requestsdb, userId) != ERR_OK) {
55 ANS_LOGE("Get liveView from db failed.");
56 return;
57 }
58 ANS_LOGI("The number of live views to recover: %{public}zu.", requestsdb.size());
59 std::vector<std::string> keys;
60 for (const auto &requestObj : requestsdb) {
61 if (!IsLiveViewCanRecover(requestObj.request)) {
62 int32_t userId = requestObj.request->GetReceiverUserId();
63 keys.emplace_back(requestObj.request->GetBaseKey(""));
64 if (DoubleDeleteNotificationFromDb(requestObj.request->GetKey(),
65 requestObj.request->GetSecureKey(), userId) != ERR_OK) {
66 ANS_LOGE("Delete notification failed.");
67 }
68 continue;
69 }
70
71 auto record = std::make_shared<NotificationRecord>();
72 record->isNeedFlowCtrl = false;
73 if (FillNotificationRecord(requestObj, record) != ERR_OK) {
74 ANS_LOGE("Fill notification record failed.");
75 continue;
76 }
77
78 if (Filter(record, true) != ERR_OK) {
79 ANS_LOGE("Filter record failed.");
80 continue;
81 }
82
83 // Turn off ringtone and vibration during recovery process
84 record->request->SetDistributedFlagBit(NotificationConstant::ReminderFlag::SOUND_FLAG, false);
85 record->request->SetDistributedFlagBit(NotificationConstant::ReminderFlag::VIBRATION_FLAG, false);
86 ANS_LOGI("SetFlags-Recovery, notificationKey = %{public}s flags = %{public}d",
87 record->request->GetKey().c_str(), record->request->GetFlags()->GetReminderFlags());
88 if (AssignToNotificationList(record) != ERR_OK) {
89 ANS_LOGE("Add notification to record list failed.");
90 continue;
91 }
92 UpdateRecentNotification(record->notification, false, 0);
93
94 StartFinishTimer(record, requestObj.request->GetFinishDeadLine(),
95 NotificationConstant::TRIGGER_EIGHT_HOUR_REASON_DELETE);
96 StartUpdateTimer(record, requestObj.request->GetUpdateDeadLine(),
97 NotificationConstant::TRIGGER_FOUR_HOUR_REASON_DELETE);
98 }
99
100 if (!keys.empty()) {
101 OnRecoverLiveView(keys);
102 }
103 // publish notifications
104 for (const auto &subscriber : NotificationSubscriberManager::GetInstance()->GetSubscriberRecords()) {
105 OnSubscriberAdd(subscriber, userId);
106 }
107 ANS_LOGI("End recover live view from db.");
108 }));
109 }
110
UpdateNotificationTimerInfo(const std::shared_ptr<NotificationRecord> & record)111 ErrCode AdvancedNotificationService::UpdateNotificationTimerInfo(const std::shared_ptr<NotificationRecord> &record)
112 {
113 ErrCode result = ERR_OK;
114
115 if (!record->request->IsCommonLiveView()) {
116 if ((record->request->GetAutoDeletedTime() > GetCurrentTime())) {
117 StartAutoDeletedTimer(record);
118 }
119 return ERR_OK;
120 }
121
122 auto content = record->request->GetContent()->GetNotificationContent();
123 auto liveViewContent = std::static_pointer_cast<NotificationLiveViewContent>(content);
124 auto status = liveViewContent->GetLiveViewStatus();
125 switch (status) {
126 case NotificationLiveViewContent::LiveViewStatus::LIVE_VIEW_CREATE:
127 result = SetFinishTimer(record);
128 if (result != ERR_OK) {
129 return result;
130 }
131
132 result = SetUpdateTimer(record);
133 return result;
134 case NotificationLiveViewContent::LiveViewStatus::LIVE_VIEW_INCREMENTAL_UPDATE:
135 case NotificationLiveViewContent::LiveViewStatus::LIVE_VIEW_FULL_UPDATE:
136 // delete old, then add new
137 CancelUpdateTimer(record);
138 result = SetUpdateTimer(record);
139 return result;
140
141 case NotificationLiveViewContent::LiveViewStatus::LIVE_VIEW_END:
142 CancelUpdateTimer(record);
143 CancelFinishTimer(record);
144 StartArchiveTimer(record);
145 break;
146 default:
147 ANS_LOGE("Invalid status %{public}d.", status);
148 return ERR_ANS_INVALID_PARAM;
149 }
150 return result;
151 }
152
ProcForDeleteLiveView(const std::shared_ptr<NotificationRecord> & record)153 void AdvancedNotificationService::ProcForDeleteLiveView(const std::shared_ptr<NotificationRecord> &record)
154 {
155 if ((record->request == nullptr) ||
156 (!(record->request->IsCommonLiveView()) && !(record->request->IsSystemLiveView()))) {
157 return;
158 }
159 int32_t userId = record->request->GetReceiverUserId();
160 if (DoubleDeleteNotificationFromDb(record->request->GetKey(),
161 record->request->GetSecureKey(), userId) != ERR_OK) {
162 ANS_LOGE("Live View cancel, delete notification failed.");
163 }
164
165 CancelUpdateTimer(record);
166 CancelFinishTimer(record);
167 CancelArchiveTimer(record);
168 }
169
OnSubscriberAdd(const std::shared_ptr<NotificationSubscriberManager::SubscriberRecord> & record,const int32_t userId)170 ErrCode AdvancedNotificationService::OnSubscriberAdd(
171 const std::shared_ptr<NotificationSubscriberManager::SubscriberRecord> &record, const int32_t userId)
172 {
173 if (record == nullptr) {
174 ANS_LOGE("No subscriber to notify.");
175 return ERR_ANS_INVALID_PARAM;
176 }
177
178 sptr<NotificationSortingMap> sortingMap = GenerateSortingMap();
179 std::vector<sptr<Notification>> notifications;
180 for (auto notificationRecord : notificationList_) {
181 if (notificationRecord != nullptr &&
182 notificationRecord->notification != nullptr &&
183 notificationRecord->notification->GetNotificationRequest().IsCommonLiveView()) {
184 notifications.emplace_back(notificationRecord->notification);
185 }
186 }
187
188 if (notifications.empty() || currentUserId.count(userId)) {
189 ANS_LOGI("No notification to consume %{public}d %{public}zu.", userId, currentUserId.count(userId));
190 return ERR_ANS_NOTIFICATION_NOT_EXISTS;
191 }
192 if (userId != INVALID_USER_ID) {
193 currentUserId.insert(userId);
194 }
195 ANS_LOGI("Consume notification count is %{public}zu %{public}d.", notifications.size(), userId);
196 NotificationSubscriberManager::GetInstance()->BatchNotifyConsumed(notifications, sortingMap, record);
197 return ERR_OK;
198 }
199
IsLiveViewCanRecover(const sptr<NotificationRequest> request)200 bool AdvancedNotificationService::IsLiveViewCanRecover(const sptr<NotificationRequest> request)
201 {
202 if (request == nullptr) {
203 ANS_LOGE("Invalid liveview.");
204 return false;
205 }
206
207 using StatusType = NotificationLiveViewContent::LiveViewStatus;
208 auto liveViewContent =
209 std::static_pointer_cast<NotificationLiveViewContent>(request->GetContent()->GetNotificationContent());
210 auto liveViewStatus = liveViewContent->GetLiveViewStatus();
211 if (liveViewStatus == StatusType::LIVE_VIEW_BUTT || liveViewStatus == StatusType::LIVE_VIEW_END) {
212 ANS_LOGE("Only update or create status can reconver.");
213 return false;
214 }
215
216 auto epoch = std::chrono::system_clock::now().time_since_epoch();
217 auto curTime = std::chrono::duration_cast<std::chrono::milliseconds>(epoch).count();
218 if (curTime > request->GetUpdateDeadLine() || curTime > request->GetFinishDeadLine()) {
219 ANS_LOGE("The liveView has expired.");
220 return false;
221 }
222
223 return true;
224 }
225
SetNotificationRequestToDb(const NotificationRequestDb & requestDb)226 int32_t AdvancedNotificationService::SetNotificationRequestToDb(const NotificationRequestDb &requestDb)
227 {
228 auto request = requestDb.request;
229 if (!request->IsCommonLiveView()) {
230 ANS_LOGD("Slot type %{public}d, content type %{public}d.",
231 request->GetSlotType(), request->GetNotificationType());
232
233 return ERR_OK;
234 }
235
236 ANS_LOGI("Enter.");
237 auto content = std::static_pointer_cast<NotificationLiveViewContent>(
238 request->GetContent()->GetNotificationContent());
239 if (request->GetOwnerUid() != DEFAULT_UID) {
240 content->SetUid(request->GetOwnerUid());
241 }
242 if (content->GetLiveViewStatus() == NotificationLiveViewContent::LiveViewStatus::LIVE_VIEW_END &&
243 request->GetAutoDeletedTime() == NotificationConstant::NO_DELAY_DELETE_TIME) {
244 ANS_LOGI("Don't need set to db when liveview is in end status and no delay delete time.");
245 return ERR_OK;
246 }
247
248 if (content->GetIsOnlyLocalUpdate()) {
249 ANS_LOGI("Not saving notification request to db for common live view with isOnlyLocalUpdate set to true.");
250 return ERR_OK;
251 }
252 HaMetaMessage message = HaMetaMessage(EventSceneId::SCENE_6, EventBranchId::BRANCH_3).
253 BundleName(request->GetCreatorBundleName()).NotificationId(request->GetNotificationId());
254 nlohmann::json jsonObject;
255 if (!NotificationJsonConverter::ConvertToJson(request, jsonObject)) {
256 ANS_LOGE("Convert request to json object failed, bundle name %{public}s, id %{public}d.",
257 request->GetCreatorBundleName().c_str(), request->GetNotificationId());
258 NotificationAnalyticsUtil::ReportModifyEvent(message.Message("convert request failed"));
259 return ERR_ANS_TASK_ERR;
260 }
261 auto bundleOption = requestDb.bundleOption;
262 if (!NotificationJsonConverter::ConvertToJson(bundleOption, jsonObject)) {
263 ANS_LOGE("Convert bundle to json object failed, bundle name %{public}s, id %{public}d.",
264 bundleOption->GetBundleName().c_str(), request->GetNotificationId());
265 NotificationAnalyticsUtil::ReportModifyEvent(message.Message("convert option failed"));
266 return ERR_ANS_TASK_ERR;
267 }
268
269 std::string encryptValue;
270 ErrCode errorCode = AesGcmHelper::Encrypt(jsonObject.dump(), encryptValue);
271 if (errorCode != ERR_OK) {
272 ANS_LOGE("SetNotificationRequestToDb encrypt error");
273 return static_cast<int>(errorCode);
274 }
275 auto result = NotificationPreferences::GetInstance()->SetKvToDb(
276 request->GetSecureKey(), encryptValue, request->GetReceiverUserId());
277 if (result != ERR_OK) {
278 ANS_LOGE("Set failed, bundle name %{public}s, id %{public}d, key %{public}s, ret %{public}d.",
279 request->GetCreatorBundleName().c_str(), request->GetNotificationId(), request->GetKey().c_str(), result);
280 NotificationAnalyticsUtil::ReportModifyEvent(message.ErrorCode(result).Message("set failed"));
281 return result;
282 } else {
283 DeleteNotificationRequestFromDb(request->GetKey(), request->GetReceiverUserId());
284 }
285
286 result = SetLockScreenPictureToDb(request);
287 if (result != ERR_OK) {
288 ANS_LOGE("Failed to set lock screen picture to db");
289 NotificationAnalyticsUtil::ReportModifyEvent(message.ErrorCode(result).Message("SetToDb failed"));
290 }
291 return result;
292 }
293
GetBatchNotificationRequestsFromDb(std::vector<NotificationRequestDb> & requests,int32_t userId)294 int32_t AdvancedNotificationService::GetBatchNotificationRequestsFromDb(
295 std::vector<NotificationRequestDb> &requests, int32_t userId)
296 {
297 std::unordered_map<std::string, std::string> dbRecords;
298 std::vector<int32_t> userIds;
299 int ret = ERR_OK;
300 if (userId == -1) {
301 ret = OsAccountManagerHelper::GetInstance().GetAllActiveOsAccount(userIds);
302 } else {
303 userIds.push_back(userId);
304 }
305
306 if (ret != ERR_OK) {
307 ANS_LOGE("Get all os account failed.");
308 return ret;
309 }
310 for (const int32_t userId : userIds) {
311 int32_t result =
312 NotificationPreferences::GetInstance()->GetBatchKvsFromDb(REQUEST_STORAGE_KEY_PREFIX, dbRecords, userId);
313 int32_t secureResult =
314 NotificationPreferences::GetInstance()->GetBatchKvsFromDb(
315 REQUEST_STORAGE_SECURE_KEY_PREFIX, dbRecords, userId);
316 if (result != ERR_OK && secureResult != ERR_OK) {
317 ANS_LOGE("Get batch notification request failed.");
318 return result;
319 }
320 }
321 for (const auto &iter : dbRecords) {
322 std::string decryptValue = iter.second;
323 if (iter.first.rfind(REQUEST_STORAGE_SECURE_KEY_PREFIX, 0) == 0) {
324 ErrCode errorCode = AesGcmHelper::Decrypt(decryptValue, iter.second);
325 if (errorCode != ERR_OK) {
326 ANS_LOGE("GetBatchNotificationRequestsFromDb decrypt error");
327 return static_cast<int>(errorCode);
328 }
329 }
330 if (decryptValue.empty() || !nlohmann::json::accept(decryptValue)) {
331 ANS_LOGE("Invalid json");
332 continue;
333 }
334 auto jsonObject = nlohmann::json::parse(decryptValue);
335 auto *request = NotificationJsonConverter::ConvertFromJson<NotificationRequest>(jsonObject);
336 if (request == nullptr) {
337 ANS_LOGE("Parse json string to request failed.");
338 continue;
339 }
340 auto *bundleOption = NotificationJsonConverter::ConvertFromJson<NotificationBundleOption>(jsonObject);
341 if (bundleOption == nullptr) {
342 ANS_LOGE("Parse json string to bundle option failed.");
343 (void)DoubleDeleteNotificationFromDb(request->GetKey(),
344 request->GetSecureKey(), request->GetReceiverUserId());
345 continue;
346 }
347
348 if (GetLockScreenPictureFromDb(request) != ERR_OK) {
349 ANS_LOGE("Get request lock screen picture failed.");
350 }
351 NotificationRequestDb requestDb = { .request = request, .bundleOption = bundleOption };
352 requests.emplace_back(requestDb);
353 }
354 return ERR_OK;
355 }
356
357
DoubleDeleteNotificationFromDb(const std::string & key,const std::string & secureKey,const int32_t userId)358 int32_t AdvancedNotificationService::DoubleDeleteNotificationFromDb(const std::string &key,
359 const std::string &secureKey, const int32_t userId)
360 {
361 auto result = NotificationPreferences::GetInstance()->DeleteKvFromDb(secureKey, userId);
362 if (result != ERR_OK) {
363 ANS_LOGE("Delete notification request failed, key %{public}s.", key.c_str());
364 return result;
365 }
366 result = DeleteNotificationRequestFromDb(key, userId);
367 return result;
368 }
369
DeleteNotificationRequestFromDb(const std::string & key,const int32_t userId)370 int32_t AdvancedNotificationService::DeleteNotificationRequestFromDb(const std::string &key, const int32_t userId)
371 {
372 auto result = NotificationPreferences::GetInstance()->DeleteKvFromDb(key, userId);
373 if (result != ERR_OK) {
374 ANS_LOGE("Delete notification request failed, key %{public}s.", key.c_str());
375 return result;
376 }
377
378 std::string lockScreenPictureKey = LOCK_SCREEN_PICTURE_TAG + key;
379 result = NotificationPreferences::GetInstance()->DeleteKvFromDb(lockScreenPictureKey, userId);
380 if (result != ERR_OK) {
381 ANS_LOGE("Delete notification lock screen picture failed, key %{public}s.", lockScreenPictureKey.c_str());
382 return result;
383 }
384 return ERR_OK;
385 }
386
IsAllowedRemoveSlot(const sptr<NotificationBundleOption> & bundleOption,const NotificationConstant::SlotType & slotType)387 ErrCode AdvancedNotificationService::IsAllowedRemoveSlot(const sptr<NotificationBundleOption> &bundleOption,
388 const NotificationConstant::SlotType &slotType)
389 {
390 if (slotType != NotificationConstant::SlotType::LIVE_VIEW) {
391 return ERR_OK;
392 }
393
394 sptr<NotificationSlot> slot;
395 if (NotificationPreferences::GetInstance()->GetNotificationSlot(bundleOption, slotType, slot) != ERR_OK) {
396 ANS_LOGE("Failed to get slot.");
397 return ERR_OK;
398 }
399
400 if (!slot->GetForceControl()) {
401 ANS_LOGI("Liveview slot is not force control.");
402 return ERR_OK;
403 }
404
405 bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
406 if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
407 ANS_LOGE("Only sa or systemapp can remove liveview slot.");
408 return ERR_ANS_NON_SYSTEM_APP;
409 }
410
411 return ERR_OK;
412 }
413
FillLockScreenPicture(const sptr<NotificationRequest> & newRequest,const sptr<NotificationRequest> & oldRequest)414 void AdvancedNotificationService::FillLockScreenPicture(const sptr<NotificationRequest> &newRequest,
415 const sptr<NotificationRequest> &oldRequest)
416 {
417 if (oldRequest->GetContent() == nullptr ||
418 newRequest->GetContent() == nullptr) {
419 return;
420 }
421 if (oldRequest->GetContent()->GetNotificationContent() == nullptr ||
422 newRequest->GetContent()->GetNotificationContent() == nullptr) {
423 return;
424 }
425 if (newRequest->GetSlotType() != NotificationConstant::SlotType::LIVE_VIEW) {
426 return;
427 }
428
429 auto oldContent = oldRequest->GetContent()->GetNotificationContent();
430 auto newContent = newRequest->GetContent()->GetNotificationContent();
431 if (newContent->GetLockScreenPicture() == nullptr) {
432 newContent->SetLockScreenPicture(oldContent->GetLockScreenPicture());
433 }
434 }
435
SetLockScreenPictureToDb(const sptr<NotificationRequest> & request)436 ErrCode AdvancedNotificationService::SetLockScreenPictureToDb(const sptr<NotificationRequest> &request)
437 {
438 auto lockScreenPicture = request->GetContent()->GetNotificationContent()->GetLockScreenPicture();
439 if (!request->IsCommonLiveView() || lockScreenPicture == nullptr) {
440 return ERR_OK;
441 }
442
443 auto size = static_cast<size_t>(lockScreenPicture->GetCapacity());
444 auto pixels = lockScreenPicture->GetPixels();
445 std::vector<uint8_t> pixelsVec(pixels, pixels + size);
446
447 std::string key = LOCK_SCREEN_PICTURE_TAG + request->GetKey();
448 auto res = NotificationPreferences::GetInstance()->SetByteToDb(key, pixelsVec, request->GetReceiverUserId());
449 if (res != ERR_OK) {
450 ANS_LOGE("Failed to set lock screen picture to db, res is %{public}d.", res);
451 return res;
452 }
453
454 return ERR_OK;
455 }
456
GetLockScreenPictureFromDb(NotificationRequest * request)457 ErrCode AdvancedNotificationService::GetLockScreenPictureFromDb(NotificationRequest *request)
458 {
459 HaMetaMessage message = HaMetaMessage(EventSceneId::SCENE_12, EventBranchId::BRANCH_0);
460 if (request == nullptr) {
461 ANS_LOGE("Request is nullptr");
462 NotificationAnalyticsUtil::ReportModifyEvent(message.ErrorCode(ERR_ANS_INVALID_PARAM));
463 return ERR_ANS_INVALID_PARAM;
464 }
465 std::string key = LOCK_SCREEN_PICTURE_TAG + request->GetKey();
466 std::vector<uint8_t> pixelsVec;
467 uint32_t res = NotificationPreferences::GetInstance()->GetByteFromDb(key, pixelsVec, request->GetReceiverUserId());
468 if (res != ERR_OK) {
469 NotificationAnalyticsUtil::ReportModifyEvent(message.ErrorCode(res).BranchId(BRANCH_1));
470 ANS_LOGE("Failed to get lock screen picture from db, res is %{public}d.", res);
471 return res;
472 }
473
474 Media::SourceOptions sourceOptions;
475 auto imageSource = Media::ImageSource::CreateImageSource((const uint8_t *)pixelsVec.data(), pixelsVec.size(),
476 sourceOptions, res);
477 if (res != ERR_OK) {
478 NotificationAnalyticsUtil::ReportModifyEvent(message.ErrorCode(res).BranchId(BRANCH_2));
479 ANS_LOGE("Failed to create image source, res is %{public}d.", res);
480 return res;
481 }
482
483 Media::DecodeOptions decodeOpts;
484 auto pixelMapPtr = imageSource->CreatePixelMap(decodeOpts, res);
485 if (res != ERR_OK) {
486 NotificationAnalyticsUtil::ReportModifyEvent(message.ErrorCode(res).BranchId(BRANCH_3));
487 ANS_LOGE("Failed to create pixel map, res is %{public}d.", res);
488 return res;
489 }
490
491 std::shared_ptr<Media::PixelMap> picture = std::shared_ptr<Media::PixelMap>(pixelMapPtr.release());
492 request->GetContent()->GetNotificationContent()->SetLockScreenPicture(picture);
493
494 return ERR_OK;
495 }
496
UpdateInDelayNotificationList(const std::shared_ptr<NotificationRecord> & record)497 void AdvancedNotificationService::UpdateInDelayNotificationList(const std::shared_ptr<NotificationRecord> &record)
498 {
499 std::lock_guard<ffrt::mutex> lock(delayNotificationMutext_);
500 auto iter = delayNotificationList_.begin();
501 while (iter != delayNotificationList_.end()) {
502 if ((*iter).first->notification->GetKey() == record->notification->GetKey()) {
503 CancelTimer((*iter).second);
504 (*iter).first = record;
505 auto request = record->notification->GetNotificationRequest();
506 (*iter).second = StartDelayPublishTimer(request.GetOwnerUid(),
507 request.GetNotificationId(), request.GetPublishDelayTime());
508 break;
509 }
510 iter++;
511 }
512 }
513
AddToDelayNotificationList(const std::shared_ptr<NotificationRecord> & record)514 void AdvancedNotificationService::AddToDelayNotificationList(const std::shared_ptr<NotificationRecord> &record)
515 {
516 std::lock_guard<ffrt::mutex> lock(delayNotificationMutext_);
517 auto request = record->notification->GetNotificationRequest();
518 auto timerId = StartDelayPublishTimer(
519 request.GetOwnerUid(), request.GetNotificationId(), request.GetPublishDelayTime());
520 delayNotificationList_.emplace_back(std::make_pair(record, timerId));
521 }
522
SaPublishSystemLiveViewAsBundle(const std::shared_ptr<NotificationRecord> & record)523 ErrCode AdvancedNotificationService::SaPublishSystemLiveViewAsBundle(const std::shared_ptr<NotificationRecord> &record)
524 {
525 uint32_t delayTime = record->notification->GetNotificationRequest().GetPublishDelayTime();
526 if (delayTime == 0) {
527 return StartPublishDelayedNotification(record);
528 }
529
530 if (IsNotificationExistsInDelayList(record->notification->GetKey())) {
531 UpdateInDelayNotificationList(record);
532 return ERR_OK;
533 }
534
535 AddToDelayNotificationList(record);
536 return ERR_OK;
537 }
538
IsNotificationExistsInDelayList(const std::string & key)539 bool AdvancedNotificationService::IsNotificationExistsInDelayList(const std::string &key)
540 {
541 std::lock_guard<ffrt::mutex> lock(delayNotificationMutext_);
542 for (auto delayNotification : delayNotificationList_) {
543 if (delayNotification.first->notification->GetKey() == key) {
544 return true;
545 }
546 }
547
548 return false;
549 }
550
StartDelayPublishTimer(const int32_t ownerUid,const int32_t notificationId,const uint32_t delayTime)551 uint64_t AdvancedNotificationService::StartDelayPublishTimer(
552 const int32_t ownerUid, const int32_t notificationId, const uint32_t delayTime)
553 {
554 ANS_LOGD("Enter");
555
556 HaMetaMessage message = HaMetaMessage(EventSceneId::SCENE_12, EventBranchId::BRANCH_4);
557 wptr<AdvancedNotificationService> wThis = this;
558 auto timeoutFunc = [wThis, ownerUid, notificationId] {
559 sptr<AdvancedNotificationService> sThis = wThis.promote();
560 if (sThis != nullptr) {
561 sThis->StartPublishDelayedNotificationTimeOut(ownerUid, notificationId);
562 }
563 };
564 std::shared_ptr<NotificationTimerInfo> notificationTimerInfo = std::make_shared<NotificationTimerInfo>();
565 notificationTimerInfo->SetCallbackInfo(timeoutFunc);
566
567 sptr<MiscServices::TimeServiceClient> timer = MiscServices::TimeServiceClient::GetInstance();
568 if (timer == nullptr) {
569 ANS_LOGE("Failed to start timer due to get TimeServiceClient is null.");
570 NotificationAnalyticsUtil::ReportModifyEvent(message.ErrorCode(NotificationConstant::INVALID_TIMER_ID));
571 return NotificationConstant::INVALID_TIMER_ID;
572 }
573
574 uint64_t timerId = timer->CreateTimer(notificationTimerInfo);
575 int64_t delayPublishPoint = GetCurrentTime() + delayTime * NotificationConstant::SECOND_TO_MS;
576 timer->StartTimer(timerId, delayPublishPoint);
577 return timerId;
578 }
579
StartPublishDelayedNotificationTimeOut(const int32_t ownerUid,const int32_t notificationId)580 void AdvancedNotificationService::StartPublishDelayedNotificationTimeOut(
581 const int32_t ownerUid, const int32_t notificationId)
582 {
583 auto record = GetFromDelayedNotificationList(ownerUid, notificationId);
584 if (record == nullptr) {
585 ANS_LOGE("Failed to get delayed notification from list.");
586 return;
587 }
588
589 int ret = StartPublishDelayedNotification(record);
590 if (ret != ERR_OK) {
591 ANS_LOGE("Failed to StartPublishDelayedNotification, ret is %{public}d", ret);
592 return;
593 }
594 }
595
StartPublishDelayedNotification(const std::shared_ptr<NotificationRecord> & record)596 ErrCode AdvancedNotificationService::StartPublishDelayedNotification(const std::shared_ptr<NotificationRecord> &record)
597 {
598 RemoveFromDelayedNotificationList(record->notification->GetKey());
599 ErrCode result = AssignToNotificationList(record);
600 if (result != ERR_OK) {
601 ANS_LOGE("Failed to assign notification list");
602 return result;
603 }
604
605 UpdateRecentNotification(record->notification, false, 0);
606 NotificationSubscriberManager::GetInstance()->NotifyConsumed(record->notification, GenerateSortingMap());
607 if ((record->request->GetAutoDeletedTime() > GetCurrentTime())) {
608 StartAutoDeletedTimer(record);
609 }
610
611 record->finish_status = UploadStatus::FIRST_UPDATE_TIME_OUT;
612 StartFinishTimer(record, GetCurrentTime() + NotificationConstant::TEN_MINUTES,
613 NotificationConstant::TRIGGER_TEN_MINUTES_REASON_DELETE);
614
615 return ERR_OK;
616 }
617
IsUpdateSystemLiveviewByOwner(const sptr<NotificationRequest> & request)618 bool AdvancedNotificationService::IsUpdateSystemLiveviewByOwner(const sptr<NotificationRequest> &request)
619 {
620 if (!request->IsSystemLiveView()) {
621 return false;
622 }
623
624 auto ownerUid = IPCSkeleton::GetCallingUid();
625 auto oldRecord = GetFromDelayedNotificationList(ownerUid, request->GetNotificationId());
626 if (oldRecord != nullptr) {
627 return true;
628 }
629
630 if (notificationSvrQueue_ == nullptr) {
631 ANS_LOGE("Serial queue is invalid.");
632 return false;
633 }
634
635 ffrt::task_handle handler = notificationSvrQueue_->submit_h([&]() {
636 oldRecord = GetFromNotificationList(ownerUid, request->GetNotificationId());
637 });
638 notificationSvrQueue_->wait(handler);
639
640 return oldRecord != nullptr;
641 }
642
IsSaCreateSystemLiveViewAsBundle(const std::shared_ptr<NotificationRecord> & record,int32_t ipcUid)643 bool AdvancedNotificationService::IsSaCreateSystemLiveViewAsBundle(
644 const std::shared_ptr<NotificationRecord> &record, int32_t ipcUid)
645 {
646 if (record == nullptr) {
647 ANS_LOGE("Invalid record.");
648 return false;
649 }
650
651 auto request = record->notification->GetNotificationRequest();
652 if (!request.IsSystemLiveView()) {
653 return false;
654 }
655
656 if (request.GetCreatorUid() == ipcUid &&
657 request.GetCreatorUid() != request.GetOwnerUid() &&
658 !IsNotificationExists(record->notification->GetKey())) {
659 return true;
660 }
661
662 return false;
663 }
664
UpdateRecordByOwner(const std::shared_ptr<NotificationRecord> & record,bool isSystemApp)665 void AdvancedNotificationService::UpdateRecordByOwner(
666 const std::shared_ptr<NotificationRecord> &record, bool isSystemApp)
667 {
668 auto creatorUid = record->notification->GetNotificationRequest().GetCreatorUid();
669 auto notificationId = record->notification->GetNotificationRequest().GetNotificationId();
670 auto oldRecord = GetFromDelayedNotificationList(creatorUid, notificationId);
671 if (oldRecord == nullptr) {
672 oldRecord = GetFromNotificationList(creatorUid, notificationId);
673 }
674 if (oldRecord == nullptr) {
675 return;
676 }
677 auto downloadTemplate = record->notification->GetNotificationRequest().GetTemplate();
678 auto content = record->notification->GetNotificationRequest().GetContent();
679 auto wantAgent = record->notification->GetNotificationRequest().GetWantAgent();
680 record->request = new (std::nothrow) NotificationRequest(*(oldRecord->request));
681 if (record->request == nullptr) {
682 ANS_LOGE("request is nullptr.");
683 return;
684 }
685 if (wantAgent != nullptr) {
686 record->request->SetWantAgent(wantAgent);
687 }
688 uint64_t timerId = 0;
689 if (isSystemApp) {
690 record->request->SetContent(content);
691 } else {
692 record->request->SetTemplate(downloadTemplate);
693 auto data = downloadTemplate->GetTemplateData();
694 AAFwk::WantParamWrapper wrapper(*data);
695 ANS_LOGD("Update the template data: %{public}s.", wrapper.ToString().c_str());
696 CancelTimer(oldRecord->notification->GetFinishTimer());
697 uint64_t process = 0;
698 if (data->HasParam(PROGRESS_VALUE)) {
699 process = data->GetIntParam(PROGRESS_VALUE, 0);
700 }
701 StartFinishTimerForUpdate(record, process);
702 timerId = record->notification->GetFinishTimer();
703 ANS_LOGI("TimerForUpdate,oldTimeId:%{public}d,newTimeId:%{public}d",
704 (int)(oldRecord->notification->GetFinishTimer()), (int)timerId);
705 }
706 record->notification = new (std::nothrow) Notification(record->request);
707 if (record->notification == nullptr) {
708 ANS_LOGE("Failed to create notification.");
709 return;
710 }
711 record->bundleOption = oldRecord->bundleOption;
712 record->notification->SetFinishTimer(timerId);
713 }
714
StartFinishTimerForUpdate(const std::shared_ptr<NotificationRecord> & record,uint64_t process)715 void AdvancedNotificationService::StartFinishTimerForUpdate(
716 const std::shared_ptr<NotificationRecord> &record, uint64_t process)
717 {
718 if (process == NotificationConstant::FINISH_PER) {
719 record->finish_status = UploadStatus::FINISH;
720 StartFinishTimer(record, GetCurrentTime() + NotificationConstant::THIRTY_MINUTES,
721 NotificationConstant::TRIGGER_FIFTEEN_MINUTES_REASON_DELETE);
722 } else {
723 record->finish_status = UploadStatus::CONTINUOUS_UPDATE_TIME_OUT;
724 StartFinishTimer(record, GetCurrentTime() + NotificationConstant::FIFTEEN_MINUTES,
725 NotificationConstant::TRIGGER_THIRTY_MINUTES_REASON_DELETE);
726 }
727 }
728
HandleUpdateLiveViewNotificationTimer(const int32_t uid,const bool isPaused)729 void AdvancedNotificationService::HandleUpdateLiveViewNotificationTimer(const int32_t uid, const bool isPaused)
730 {
731 for (const auto &record : notificationList_) {
732 const auto &request = record->request;
733 if (!request || request->GetOwnerUid() != uid) {
734 continue;
735 }
736 if (!request->GetContent() || !request->GetContent()->GetNotificationContent()) {
737 continue;
738 }
739 bool isContinuousLiveView = request->IsSystemLiveView() && request->GetCreatorUid() == BGTASK_UID;
740 if (!isContinuousLiveView) {
741 continue;
742 }
743 const auto &liveViewContent = std::static_pointer_cast<NotificationLocalLiveViewContent>(
744 request->GetContent()->GetNotificationContent());
745 if (liveViewContent->GetType() == TYPE_CODE_DOWNLOAD) {
746 if (isPaused) {
747 ANS_LOGI("liveview notification timer is being cancelled, uid: %{public}d", uid);
748 CancelTimer(record->notification->GetFinishTimer());
749 } else {
750 ANS_LOGI("liveview notification timer is being reset, uid: %{public}d", uid);
751 StartFinishTimer(record, GetCurrentTime() + NotificationConstant::FIFTEEN_MINUTES,
752 NotificationConstant::TRIGGER_THIRTY_MINUTES_REASON_DELETE);
753 }
754 }
755 }
756 }
757 }
758 }
759