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