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