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