• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 "reminder_data_manager.h"
17 
18 #include "ability_manager_client.h"
19 #include "access_token_helper.h"
20 #include "ans_log_wrapper.h"
21 #include "ans_const_define.h"
22 #include "common_event_support.h"
23 #include "common_event_manager.h"
24 #ifdef DEVICE_STANDBY_ENABLE
25 #include "standby_service_client.h"
26 #include "allow_type.h"
27 #endif
28 #include "ipc_skeleton.h"
29 #include "notification_slot.h"
30 #include "os_account_manager.h"
31 #include "reminder_event_manager.h"
32 #include "time_service_client.h"
33 #include "singleton.h"
34 #include "locale_config.h"
35 #include "bundle_manager_helper.h"
36 #include "datashare_predicates_object.h"
37 #include "datashare_value_object.h"
38 #include "datashare_helper.h"
39 #include "datashare_template.h"
40 #include "system_ability_definition.h"
41 #include "app_mgr_constants.h"
42 #include "iservice_registry.h"
43 
44 namespace OHOS {
45 namespace Notification {
46 namespace {
47 const std::string ALL_PACKAGES = "allPackages";
48 const int32_t MAIN_USER_ID = 100;
49 #ifdef DEVICE_STANDBY_ENABLE
50 const int REASON_APP_API = 1;
51 #endif
52 const int INDEX_KEY = 0;
53 const int INDEX_TYPE = 1;
54 const int INDEX_VALUE = 2;
55 }
56 
57 /**
58  * Default reminder sound.
59  */
60 const static Uri DEFAULT_REMINDER_SOUND("file://system/etc/capture.ogg");
61 
62 const int16_t ReminderDataManager::MAX_NUM_REMINDER_LIMIT_SYSTEM = 12000;
63 const int16_t ReminderDataManager::MAX_NUM_REMINDER_LIMIT_SYS_APP = 10000;
64 const int16_t ReminderDataManager::MAX_NUM_REMINDER_LIMIT_APP = 30;
65 const uint8_t ReminderDataManager::TIME_ZONE_CHANGE = 0;
66 const uint8_t ReminderDataManager::DATE_TIME_CHANGE = 1;
67 std::shared_ptr<ReminderDataManager> ReminderDataManager::REMINDER_DATA_MANAGER = nullptr;
68 std::mutex ReminderDataManager::MUTEX;
69 std::mutex ReminderDataManager::SHOW_MUTEX;
70 std::mutex ReminderDataManager::ALERT_MUTEX;
71 std::mutex ReminderDataManager::TIMER_MUTEX;
72 
73 ReminderDataManager::~ReminderDataManager() = default;
74 
PublishReminder(const sptr<ReminderRequest> & reminder,const sptr<NotificationBundleOption> & bundleOption)75 ErrCode ReminderDataManager::PublishReminder(const sptr<ReminderRequest> &reminder,
76     const sptr<NotificationBundleOption> &bundleOption)
77 {
78     if (CheckReminderLimitExceededLocked(bundleOption, reminder)) {
79         return ERR_REMINDER_NUMBER_OVERLOAD;
80     }
81     UpdateAndSaveReminderLocked(reminder, bundleOption);
82     queue_->submit([this, reminder]() {
83         UpdateReminderLanguageLocked(reminder);
84         StartRecentReminder();
85     });
86     return ERR_OK;
87 }
88 
CancelReminder(const int32_t & reminderId,const sptr<NotificationBundleOption> & bundleOption)89 ErrCode ReminderDataManager::CancelReminder(
90     const int32_t &reminderId, const sptr<NotificationBundleOption> &bundleOption)
91 {
92     sptr<ReminderRequest> reminder = FindReminderRequestLocked(reminderId, bundleOption->GetBundleName());
93     if (reminder == nullptr) {
94         ANSR_LOGW("Cancel reminder, not find the reminder");
95         return ERR_REMINDER_NOT_EXIST;
96     }
97     if (activeReminderId_ == reminderId) {
98         ANSR_LOGD("Cancel active reminder, id=%{public}d", reminderId);
99         activeReminder_->OnStop();
100         StopTimerLocked(TimerType::TRIGGER_TIMER);
101     }
102     if (alertingReminderId_ == reminderId) {
103         StopSoundAndVibrationLocked(reminder);
104         StopTimerLocked(TimerType::ALERTING_TIMER);
105     }
106     int32_t id = reminderId;
107     CancelNotification(reminder);
108     RemoveReminderLocked(id);
109     StartRecentReminder();
110     return ERR_OK;
111 }
112 
CancelAllReminders(const std::string & packageName,const int32_t & userId)113 ErrCode ReminderDataManager::CancelAllReminders(const std::string &packageName, const int32_t &userId)
114 {
115     ANSR_LOGD("CancelAllReminders, userId=%{public}d, pkgName=%{public}s",
116         userId, packageName.c_str());
117     CancelRemindersImplLocked(packageName, userId);
118     return ERR_OK;
119 }
120 
GetValidReminders(const sptr<NotificationBundleOption> & bundleOption,std::vector<sptr<ReminderRequest>> & reminders)121 void ReminderDataManager::GetValidReminders(
122     const sptr<NotificationBundleOption> &bundleOption, std::vector<sptr<ReminderRequest>> &reminders)
123 {
124     std::lock_guard<std::mutex> lock(ReminderDataManager::MUTEX);
125     for (auto it = reminderVector_.begin(); it != reminderVector_.end(); ++it) {
126         if ((*it)->IsExpired()) {
127             continue;
128         }
129         int32_t reminderId = (*it)->GetReminderId();
130         auto mit = notificationBundleOptionMap_.find(reminderId);
131         if (mit == notificationBundleOptionMap_.end()) {
132             ANSR_LOGE("Get bundle option occur error, reminderId=%{public}d", reminderId);
133         } else {
134             if (IsBelongToSameApp(mit->second, bundleOption)) {
135                 reminders.push_back(*it);
136             }
137         }
138     }
139 }
140 
CancelAllReminders(const int32_t & userId)141 void ReminderDataManager::CancelAllReminders(const int32_t &userId)
142 {
143     ANSR_LOGD("CancelAllReminders, userId=%{public}d", userId);
144     CancelRemindersImplLocked(ALL_PACKAGES, userId);
145 }
146 
CancelRemindersImplLocked(const std::string & packageName,const int32_t & userId)147 void ReminderDataManager::CancelRemindersImplLocked(const std::string &packageName, const int32_t &userId)
148 {
149     MUTEX.lock();
150     if (activeReminderId_ != -1 && IsMatched(activeReminder_, packageName, userId)) {
151         activeReminder_->OnStop();
152         StopTimer(TimerType::TRIGGER_TIMER);
153         ANSR_LOGD("Stop active reminder, reminderId=%{public}d", activeReminderId_);
154     }
155     for (auto vit = reminderVector_.begin(); vit != reminderVector_.end();) {
156         int32_t reminderId = (*vit)->GetReminderId();
157         auto mit = notificationBundleOptionMap_.find(reminderId);
158         if (mit == notificationBundleOptionMap_.end()) {
159             ANSR_LOGE("Get bundle option occur error, reminderId=%{public}d", reminderId);
160             ++vit;
161             continue;
162         }
163         if (IsMatched(*vit, packageName, userId)) {
164             if ((*vit)->IsAlerting()) {
165                 StopAlertingReminder(*vit);
166             }
167             CancelNotification(*vit);
168             RemoveFromShowedReminders(*vit);
169             ANSR_LOGD("Containers(vector/map) remove. reminderId=%{public}d", reminderId);
170             vit = reminderVector_.erase(vit);
171             notificationBundleOptionMap_.erase(mit);
172             totalCount_--;
173             continue;
174         }
175         ++vit;
176     }
177     if (packageName == ALL_PACKAGES) {
178         store_->DeleteUser(userId);
179     } else {
180         store_->Delete(packageName, userId);
181     }
182     MUTEX.unlock();
183     StartRecentReminder();
184 }
185 
IsMatchedForGroupIdAndPkgName(const sptr<ReminderRequest> & reminder,const std::string & packageName,const std::string & groupId) const186 bool ReminderDataManager::IsMatchedForGroupIdAndPkgName(const sptr<ReminderRequest> &reminder,
187     const std::string &packageName, const std::string &groupId) const
188 {
189     std::string packageNameTemp = reminder->GetBundleName();
190     if (packageNameTemp.empty()) {
191         ANSR_LOGW("reminder package name is null");
192         return false;
193     }
194     if (packageNameTemp == packageName && reminder->GetGroupId() == groupId) {
195         return true;
196     }
197     return false;
198 }
199 
IsMatched(const sptr<ReminderRequest> & reminder,const std::string & packageName,const int32_t & userId) const200 bool ReminderDataManager::IsMatched(const sptr<ReminderRequest> &reminder,
201     const std::string &packageName, const int32_t &userId) const
202 {
203     auto mit = notificationBundleOptionMap_.find(reminder->GetReminderId());
204     if (mit == notificationBundleOptionMap_.end()) {
205         ANS_LOGE("Failed to get bundle information. reminderId=%{public}d", reminder->GetReminderId());
206         return true;
207     }
208     if (ReminderRequest::GetUserId(mit->second->GetUid()) != userId) {
209         return false;
210     }
211     if (packageName == ALL_PACKAGES) {
212         return true;
213     }
214     if (mit->second->GetBundleName() == packageName) {
215         return true;
216     }
217     return false;
218 }
219 
CancelNotification(const sptr<ReminderRequest> & reminder) const220 void ReminderDataManager::CancelNotification(const sptr<ReminderRequest> &reminder) const
221 {
222     if (!(reminder->IsShowing())) {
223         ANSR_LOGD("No need to cancel notification");
224         return;
225     }
226     sptr<NotificationRequest> notification = reminder->GetNotificationRequest();
227     if (notification == nullptr) {
228         ANSR_LOGW("Cancel notification fail");
229         return;
230     }
231     ANSR_LOGD("Cancel notification");
232     if (advancedNotificationService_ == nullptr) {
233         ANSR_LOGE("Cancel notification fail");
234         return;
235     }
236     sptr<NotificationBundleOption> bundleOption = FindNotificationBundleOption(reminder->GetReminderId());
237     advancedNotificationService_->CancelPreparedNotification(
238         notification->GetNotificationId(), ReminderRequest::NOTIFICATION_LABEL, bundleOption);
239 }
240 
CheckReminderLimitExceededLocked(const sptr<NotificationBundleOption> & bundleOption,const sptr<ReminderRequest> & reminder) const241 bool ReminderDataManager::CheckReminderLimitExceededLocked(const sptr<NotificationBundleOption> &bundleOption,
242     const sptr<ReminderRequest> &reminder) const
243 {
244     std::lock_guard<std::mutex> lock(ReminderDataManager::MUTEX);
245     if (totalCount_ >= ReminderDataManager::MAX_NUM_REMINDER_LIMIT_SYSTEM) {
246         ANSR_LOGW("The number of validate reminders exceeds the system upper limit:%{public}d, \
247             and new reminder can not be published", MAX_NUM_REMINDER_LIMIT_SYSTEM);
248         return true;
249     }
250     int32_t count = 0;
251     for (auto it = reminderVector_.begin(); it != reminderVector_.end(); ++it) {
252         if ((*it)->IsExpired()) {
253             continue;
254         }
255         auto mit = notificationBundleOptionMap_.find((*it)->GetReminderId());
256         if (mit == notificationBundleOptionMap_.end()) {
257             ANSR_LOGE("Error occur when get bundle option, reminderId=%{public}d", (*it)->GetReminderId());
258         } else {
259             if (IsBelongToSameApp(mit->second, bundleOption)) {
260                 count++;
261             }
262         }
263     }
264     auto maxReminderNum = reminder->IsSystemApp() ? MAX_NUM_REMINDER_LIMIT_SYS_APP : MAX_NUM_REMINDER_LIMIT_APP;
265     if (count >= maxReminderNum) {
266         ANSR_LOGW("The number of validate reminders exceeds the application upper limit:%{public}d, and new \
267             reminder can not be published", maxReminderNum);
268         return true;
269     }
270     return false;
271 }
272 
AddToShowedReminders(const sptr<ReminderRequest> & reminder)273 void ReminderDataManager::AddToShowedReminders(const sptr<ReminderRequest> &reminder)
274 {
275     std::lock_guard<std::mutex> lock(ReminderDataManager::SHOW_MUTEX);
276     for (auto it = showedReminderVector_.begin(); it != showedReminderVector_.end(); ++it) {
277         if (reminder->GetReminderId() == (*it)->GetReminderId()) {
278             ANSR_LOGD("Showed reminder is already exist");
279             return;
280         }
281     }
282     ANSR_LOGD("Containers(shownVector) add. reminderId=%{public}d", reminder->GetReminderId());
283     showedReminderVector_.push_back(reminder);
284 }
285 
OnUserRemove(const int32_t & userId)286 void ReminderDataManager::OnUserRemove(const int32_t& userId)
287 {
288     ANSR_LOGD("Remove user id: %{public}d", userId);
289     if (!IsReminderAgentReady()) {
290         ANSR_LOGW("Give up to remove user id: %{public}d for reminderAgent is not ready", userId);
291         return;
292     }
293     CancelAllReminders(userId);
294 }
295 
OnServiceStart()296 void ReminderDataManager::OnServiceStart()
297 {
298     std::vector<sptr<ReminderRequest>> immediatelyShowReminders;
299     GetImmediatelyShowRemindersLocked(immediatelyShowReminders);
300     ANSR_LOGD("immediatelyShowReminders size=%{public}zu", immediatelyShowReminders.size());
301     HandleImmediatelyShow(immediatelyShowReminders, false);
302     StartRecentReminder();
303 }
304 
OnUserSwitch(const int32_t & userId)305 void ReminderDataManager::OnUserSwitch(const int32_t& userId)
306 {
307     ANSR_LOGD("Switch user id from %{public}d to %{public}d", currentUserId_, userId);
308     currentUserId_ = userId;
309     std::lock_guard<std::mutex> lock(ReminderDataManager::MUTEX);
310     if ((alertingReminderId_ != -1) && IsReminderAgentReady()) {
311         TerminateAlerting(alertingReminder_, "OnUserSwitch");
312     }
313 }
314 
OnProcessDiedLocked(const sptr<NotificationBundleOption> & bundleOption)315 void ReminderDataManager::OnProcessDiedLocked(const sptr<NotificationBundleOption> &bundleOption)
316 {
317     std::string bundleName = bundleOption->GetBundleName();
318     int32_t uid = bundleOption->GetUid();
319     ANSR_LOGD("OnProcessDiedLocked, bundleName=%{public}s, uid=%{public}d", bundleName.c_str(), uid);
320     std::lock_guard<std::mutex> lock(ReminderDataManager::SHOW_MUTEX);
321     for (auto it = showedReminderVector_.begin(); it != showedReminderVector_.end(); ++it) {
322         int32_t reminderId = (*it)->GetReminderId();
323         auto mit = notificationBundleOptionMap_.find(reminderId);
324         if (mit == notificationBundleOptionMap_.end()) {
325             ANSR_LOGD(
326                 "Not get bundle option, the reminder may has been cancelled, reminderId=%{public}d", reminderId);
327             CancelNotification(*it);
328             showedReminderVector_.erase(it);
329             --it;
330             continue;
331         }
332         if (mit->second->GetBundleName() != bundleName || mit->second->GetUid() != uid) {
333             continue;
334         }
335         if ((*it)->IsAlerting()) {
336             TerminateAlerting((*it), "onProcessDied");
337         } else {
338             CancelNotification(*it);
339             (*it)->OnClose(false);
340             ANSR_LOGD("Containers(shownVector) remove. reminderId=%{public}d", reminderId);
341             showedReminderVector_.erase(it);
342             --it;
343         }
344         store_->UpdateOrInsert((*it), bundleOption);
345     }
346 }
347 
InitTimerInfo(std::shared_ptr<ReminderTimerInfo> & sharedTimerInfo,const sptr<ReminderRequest> & reminderRequest,TimerType reminderType) const348 void ReminderDataManager::InitTimerInfo(std::shared_ptr<ReminderTimerInfo> &sharedTimerInfo,
349     const sptr<ReminderRequest> &reminderRequest, TimerType reminderType) const
350 {
351     uint8_t timerTypeWakeup = static_cast<uint8_t>(sharedTimerInfo->TIMER_TYPE_WAKEUP);
352     uint8_t timerTypeExact = static_cast<uint8_t>(sharedTimerInfo->TIMER_TYPE_EXACT);
353     sharedTimerInfo->SetRepeat(false);
354     sharedTimerInfo->SetInterval(0);
355 
356     auto mit = notificationBundleOptionMap_.find(reminderRequest->GetReminderId());
357     if (mit == notificationBundleOptionMap_.end()) {
358         ANS_LOGE("Failed to get bundle information. reminderId=%{public}d",
359             reminderRequest->GetReminderId());
360         return;
361     }
362     sharedTimerInfo->SetBundleName(mit->second->GetBundleName());
363     sharedTimerInfo->SetUid(mit->second->GetUid());
364 
365     // The systemtimer type will be set TIMER_TYPE_INEXACT_REMINDER&&EXACT if reminder type is CALENDAR or TIMER,
366     // and set WAKEUP&&EXACT if ALARM.
367     int32_t timerType;
368     if (reminderType == TimerType::TRIGGER_TIMER &&
369         (reminderRequest->GetReminderType() == ReminderRequest::ReminderType::CALENDAR ||
370         reminderRequest->GetReminderType() == ReminderRequest::ReminderType::TIMER)) {
371 #ifdef DEVICE_STANDBY_ENABLE
372         // Get allow list.
373         std::string name = mit->second->GetBundleName();
374         std::vector<DevStandbyMgr::AllowInfo> allowInfoList;
375         DevStandbyMgr::StandbyServiceClient::GetInstance().GetAllowList(DevStandbyMgr::AllowType::TIMER,
376             allowInfoList, REASON_APP_API);
377         auto it = std::find_if(allowInfoList.begin(),
378             allowInfoList.end(),
379             [&name](const DevStandbyMgr::AllowInfo &allowInfo) {
380                 return allowInfo.GetName() == name;
381             });
382         if (reminderRequest->IsSystemApp() || it != allowInfoList.end()) {
383             timerType = static_cast<int32_t>(timerTypeWakeup | timerTypeExact);
384         } else {
385             uint8_t timerTypeAns = static_cast<uint8_t>(sharedTimerInfo->TIMER_TYPE_INEXACT_REMINDER);
386             timerType = static_cast<int32_t>(timerTypeAns | timerTypeExact);
387         }
388 #else
389         timerType = static_cast<int32_t>(timerTypeWakeup | timerTypeExact);
390 #endif
391     } else {
392         timerType = static_cast<int32_t>(timerTypeWakeup | timerTypeExact);
393     }
394     sharedTimerInfo->SetType(timerType);
395 }
396 
CreateTimerInfo(TimerType type,const sptr<ReminderRequest> & reminderRequest) const397 std::shared_ptr<ReminderTimerInfo> ReminderDataManager::CreateTimerInfo(TimerType type,
398     const sptr<ReminderRequest> &reminderRequest) const
399 {
400     auto sharedTimerInfo = std::make_shared<ReminderTimerInfo>();
401     if ((sharedTimerInfo->TIMER_TYPE_WAKEUP > UINT8_MAX) || (sharedTimerInfo->TIMER_TYPE_EXACT > UINT8_MAX)) {
402         ANSR_LOGE("Failed to set timer type.");
403         return nullptr;
404     }
405     InitTimerInfo(sharedTimerInfo, reminderRequest, type);
406 
407     int32_t requestCode = 10;
408     std::vector<AbilityRuntime::WantAgent::WantAgentConstant::Flags> flags;
409     flags.push_back(AbilityRuntime::WantAgent::WantAgentConstant::Flags::UPDATE_PRESENT_FLAG);
410 
411     auto want = std::make_shared<OHOS::AAFwk::Want>();
412     switch (type) {
413         case (TimerType::TRIGGER_TIMER): {
414             want->SetAction(ReminderRequest::REMINDER_EVENT_ALARM_ALERT);
415             sharedTimerInfo->SetAction(ReminderRequest::REMINDER_EVENT_ALARM_ALERT);
416             want->SetParam(ReminderRequest::PARAM_REMINDER_ID, activeReminderId_);
417             break;
418         }
419         case (TimerType::ALERTING_TIMER): {
420             if (alertingReminderId_ == -1) {
421                 ANSR_LOGE("Create alerting time out timer Illegal.");
422                 return sharedTimerInfo;
423             }
424             want->SetAction(ReminderRequest::REMINDER_EVENT_ALERT_TIMEOUT);
425             sharedTimerInfo->SetAction(ReminderRequest::REMINDER_EVENT_ALERT_TIMEOUT);
426             want->SetParam(ReminderRequest::PARAM_REMINDER_ID, alertingReminderId_);
427             break;
428         }
429         default:
430             ANSR_LOGE("TimerType not support");
431             break;
432     }
433     std::vector<std::shared_ptr<AAFwk::Want>> wants;
434     wants.push_back(want);
435     AbilityRuntime::WantAgent::WantAgentInfo wantAgentInfo(
436         requestCode,
437         AbilityRuntime::WantAgent::WantAgentConstant::OperationType::SEND_COMMON_EVENT,
438         flags,
439         wants,
440         nullptr
441     );
442 
443     std::string identity = IPCSkeleton::ResetCallingIdentity();
444     std::shared_ptr<AbilityRuntime::WantAgent::WantAgent> wantAgent =
445         AbilityRuntime::WantAgent::WantAgentHelper::GetWantAgent(wantAgentInfo, 0);
446     IPCSkeleton::SetCallingIdentity(identity);
447 
448     sharedTimerInfo->SetWantAgent(wantAgent);
449     return sharedTimerInfo;
450 }
451 
FindReminderRequestLocked(const int32_t & reminderId)452 sptr<ReminderRequest> ReminderDataManager::FindReminderRequestLocked(const int32_t &reminderId)
453 {
454     std::lock_guard<std::mutex> lock(ReminderDataManager::MUTEX);
455     for (auto it = reminderVector_.begin(); it != reminderVector_.end(); ++it) {
456         if (reminderId == (*it)->GetReminderId()) {
457             return *it;
458         }
459     }
460     ANSR_LOGD("Not find the reminder");
461     return nullptr;
462 }
463 
FindReminderRequestLocked(const int32_t & reminderId,const std::string & pkgName)464 sptr<ReminderRequest> ReminderDataManager::FindReminderRequestLocked(
465     const int32_t &reminderId, const std::string &pkgName)
466 {
467     sptr<ReminderRequest> reminder = FindReminderRequestLocked(reminderId);
468     std::lock_guard<std::mutex> lock(ReminderDataManager::MUTEX);
469     if (reminder == nullptr) {
470         return nullptr;
471     }
472     if (reminder->GetCreatorBundleName() != pkgName) {
473         ANSR_LOGW("Not find the reminder due to package name not match");
474         return nullptr;
475     }
476     return reminder;
477 }
478 
FindNotificationBundleOption(const int32_t & reminderId) const479 sptr<NotificationBundleOption> ReminderDataManager::FindNotificationBundleOption(const int32_t &reminderId) const
480 {
481     auto it = notificationBundleOptionMap_.find(reminderId);
482     if (it == notificationBundleOptionMap_.end()) {
483         ANSR_LOGW("Failed to get bundle option.");
484         return nullptr;
485     } else {
486         return it->second;
487     }
488 }
489 
cmp(sptr<ReminderRequest> & reminderRequest,sptr<ReminderRequest> & other)490 bool ReminderDataManager::cmp(sptr<ReminderRequest> &reminderRequest, sptr<ReminderRequest> &other)
491 {
492     return reminderRequest->GetTriggerTimeInMilli() < other->GetTriggerTimeInMilli();
493 }
494 
CloseReminder(const OHOS::EventFwk::Want & want,bool cancelNotification)495 void ReminderDataManager::CloseReminder(const OHOS::EventFwk::Want &want, bool cancelNotification)
496 {
497     int32_t reminderId = static_cast<int32_t>(want.GetIntParam(ReminderRequest::PARAM_REMINDER_ID, -1));
498     sptr<ReminderRequest> reminder = FindReminderRequestLocked(reminderId);
499     if (reminder == nullptr) {
500         ANSR_LOGW("Invalid reminder id: %{public}d", reminderId);
501         return;
502     }
503     std::string packageName = reminder->GetBundleName();
504     std::string groupId = reminder->GetGroupId();
505     if (packageName.empty() || groupId.empty()) {
506         ANSR_LOGD("reminder packageName is null or default close reminder, \
507             the group id is not set, this reminder can not close by groupId");
508         CloseReminder(reminder, cancelNotification);
509         UpdateAppDatabase(reminder, ReminderRequest::ActionButtonType::CLOSE);
510         StartRecentReminder();
511         return;
512     }
513     CloseRemindersByGroupId(reminderId, packageName, groupId);
514     CloseReminder(reminder, cancelNotification);
515     UpdateAppDatabase(reminder, ReminderRequest::ActionButtonType::CLOSE);
516     StartRecentReminder();
517     CheckNeedNotifyStatus(reminder, ReminderRequest::ActionButtonType::CLOSE);
518 }
519 
CloseRemindersByGroupId(const int32_t & oldReminderId,const std::string & packageName,const std::string & groupId)520 void ReminderDataManager::CloseRemindersByGroupId(const int32_t &oldReminderId, const std::string &packageName,
521     const std::string &groupId)
522 {
523     if (packageName == "") {
524         ANSR_LOGD("packageName is empty");
525         return;
526     }
527     std::lock_guard<std::mutex> lock(ReminderDataManager::MUTEX);
528     for (auto vit = reminderVector_.begin(); vit != reminderVector_.end(); vit++) {
529         sptr<ReminderRequest> reminder = *vit;
530         if (reminder == nullptr) {
531             ANSR_LOGD("reminder is null");
532             continue;
533         }
534         int32_t reminderId = reminder->GetReminderId();
535         if (reminderId == oldReminderId) {
536             ANSR_LOGD("The old and new reminder are the same");
537             continue;
538         }
539         if (IsMatchedForGroupIdAndPkgName(reminder, packageName, groupId)) {
540             reminder->SetExpired(true);
541             reminder->SetStateToInActive();
542             store_->UpdateOrInsert(reminder, FindNotificationBundleOption(reminder->GetReminderId()));
543             ResetStates(TimerType::TRIGGER_TIMER);
544             ANSR_LOGD("Cancel reminders by groupid, reminder is %{public}s", reminder->Dump().c_str());
545         }
546     }
547 }
548 
CloseReminder(const sptr<ReminderRequest> & reminder,bool cancelNotification)549 void ReminderDataManager::CloseReminder(const sptr<ReminderRequest> &reminder, bool cancelNotification)
550 {
551     int32_t reminderId = reminder->GetReminderId();
552     if (activeReminderId_ == reminderId) {
553         ANSR_LOGD("Stop active reminder due to CloseReminder");
554         activeReminder_->OnStop();
555         StopTimerLocked(TimerType::TRIGGER_TIMER);
556     }
557     if (alertingReminderId_ == reminderId) {
558         StopSoundAndVibrationLocked(reminder);
559         StopTimerLocked(TimerType::ALERTING_TIMER);
560     }
561     reminder->OnClose(true);
562     RemoveFromShowedReminders(reminder);
563     store_->UpdateOrInsert(reminder, FindNotificationBundleOption(reminder->GetReminderId()));
564     if (cancelNotification) {
565         CancelNotification(reminder);
566     }
567 }
568 
GetInstance()569 std::shared_ptr<ReminderDataManager> ReminderDataManager::GetInstance()
570 {
571     return REMINDER_DATA_MANAGER;
572 }
573 
InitInstance(const sptr<AdvancedNotificationService> & advancedNotificationService)574 std::shared_ptr<ReminderDataManager> ReminderDataManager::InitInstance(
575     const sptr<AdvancedNotificationService> &advancedNotificationService)
576 {
577     if (REMINDER_DATA_MANAGER == nullptr) {
578         REMINDER_DATA_MANAGER = std::make_shared<ReminderDataManager>();
579         REMINDER_DATA_MANAGER->advancedNotificationService_ = advancedNotificationService;
580         ReminderEventManager reminderEventManager(REMINDER_DATA_MANAGER);
581     }
582     return REMINDER_DATA_MANAGER;
583 }
584 
CheckUpdateConditions(const sptr<ReminderRequest> & reminder,const ReminderRequest::ActionButtonType & actionButtonType,const std::map<ReminderRequest::ActionButtonType,ReminderRequest::ActionButtonInfo> & actionButtonMap)585 bool ReminderDataManager::CheckUpdateConditions(const sptr<ReminderRequest> &reminder,
586     const ReminderRequest::ActionButtonType &actionButtonType,
587     const std::map<ReminderRequest::ActionButtonType, ReminderRequest::ActionButtonInfo> &actionButtonMap)
588 {
589     if (!reminder->IsSystemApp()) {
590         ANSR_LOGI("UpdateAppDatabase faild, is not SystemApp");
591         return false;
592     }
593     if (actionButtonType == ReminderRequest::ActionButtonType::INVALID) {
594         ANSR_LOGI("actionButtonType is NVALID");
595         return false;
596     }
597     if (!actionButtonMap.count(actionButtonType)) {
598         ANSR_LOGI("actionButtonType does not exist");
599         return false;
600     }
601     if (actionButtonMap.at(actionButtonType).dataShareUpdate == nullptr) {
602         ANSR_LOGI("dataShareUpdate is null");
603         return false;
604     }
605     if (actionButtonMap.at(actionButtonType).dataShareUpdate->uri == "" ||
606         actionButtonMap.at(actionButtonType).dataShareUpdate->equalTo == "" ||
607         actionButtonMap.at(actionButtonType).dataShareUpdate->valuesBucket == "") {
608         ANSR_LOGI("datashare parameter is invalid");
609         return false;
610     }
611     return true;
612 }
613 
UpdateAppDatabase(const sptr<ReminderRequest> & reminder,const ReminderRequest::ActionButtonType & actionButtonType)614 void ReminderDataManager::UpdateAppDatabase(const sptr<ReminderRequest> &reminder,
615     const ReminderRequest::ActionButtonType &actionButtonType)
616 {
617     auto actionButtonMap = reminder->GetActionButtons();
618     if (!CheckUpdateConditions(reminder, actionButtonType, actionButtonMap)) {
619         return;
620     }
621     // init default dstBundleName
622     std::string dstBundleName;
623     auto mit = notificationBundleOptionMap_.find(reminder->GetReminderId());
624     if (mit != notificationBundleOptionMap_.end()) {
625         dstBundleName = mit->second->GetBundleName();
626     }
627     GenDstBundleName(dstBundleName, actionButtonMap.at(actionButtonType).dataShareUpdate->uri);
628 
629     DataShare::CreateOptions options;
630     options.enabled_ = true;
631     auto userID = reminder->GetUserId();
632     auto tokenID = IPCSkeleton::GetSelfTokenID();
633     std::string uriStr = actionButtonMap.at(actionButtonType).dataShareUpdate->uri + "?user=" + std::to_string(userID) +
634         "&srcToken=" + std::to_string(tokenID) + "&dstBundleName=" + dstBundleName;
635 
636     // create datashareHelper
637     std::shared_ptr<DataShare::DataShareHelper> dataShareHelper = DataShare::DataShareHelper::Creator(uriStr, options);
638     if (dataShareHelper == nullptr) {
639         ANSR_LOGE("create datashareHelper failed");
640         return;
641     }
642     // gen uri equalTo valuesBucket
643     Uri uri(uriStr);
644 
645     DataShare::DataSharePredicates predicates;
646     std::vector<std::string> equalToVector = ReminderRequest::StringSplit(
647         actionButtonMap.at(actionButtonType).dataShareUpdate->equalTo, ReminderRequest::SEP_BUTTON_VALUE_TYPE);
648     GenPredicates(predicates, equalToVector);
649 
650     DataShare::DataShareValuesBucket valuesBucket;
651     std::vector<std::string> valuesBucketVector = ReminderRequest::StringSplit(
652         actionButtonMap.at(actionButtonType).dataShareUpdate->valuesBucket, ReminderRequest::SEP_BUTTON_VALUE_TYPE);
653     GenValuesBucket(valuesBucket, valuesBucketVector);
654 
655     // update app store
656     int retVal = dataShareHelper->Update(uri, predicates, valuesBucket);
657     if (retVal > 0) {
658         // update success
659         ANSR_LOGI("update app store success retval:%{public}d", retVal);
660     }
661 }
662 
GenPredicates(DataShare::DataSharePredicates & predicates,const std::vector<std::string> & equalToVector)663 void ReminderDataManager::GenPredicates(DataShare::DataSharePredicates &predicates,
664     const std::vector<std::string> &equalToVector)
665 {
666     // predicates
667     for (auto &it : equalToVector) {
668         std::vector<std::string> temp = ReminderRequest::StringSplit(it, ReminderRequest::SEP_BUTTON_VALUE);
669         if (temp.size() <= INDEX_VALUE) {
670             continue;
671         }
672         if (temp[INDEX_TYPE] == "string") {
673             predicates.EqualTo(temp[INDEX_KEY], temp[INDEX_VALUE]);
674         } else if (temp[INDEX_TYPE] == "double") {
675             predicates.EqualTo(temp[INDEX_KEY], std::stod(temp[INDEX_VALUE]));
676         } else if (temp[INDEX_TYPE] == "bool") {
677             bool valueBool = false;
678             if (temp[INDEX_VALUE] == "1" || temp[INDEX_VALUE] == "true" || temp[INDEX_VALUE] == "True") {
679                 valueBool = true;
680             }
681             predicates.EqualTo(temp[INDEX_KEY], valueBool);
682         }
683     }
684 }
685 
GenValuesBucket(DataShare::DataShareValuesBucket & valuesBucket,const std::vector<std::string> & valuesBucketVector)686 void ReminderDataManager::GenValuesBucket(DataShare::DataShareValuesBucket & valuesBucket,
687     const std::vector<std::string> &valuesBucketVector)
688 {
689     // valuesBucket
690     for (auto &it : valuesBucketVector) {
691         std::vector<std::string> temp = ReminderRequest::StringSplit(it, ReminderRequest::SEP_BUTTON_VALUE);
692         if (temp.size() <= INDEX_VALUE) {
693             continue;
694         }
695         if (temp[INDEX_TYPE] == "string") {
696             valuesBucket.Put(temp[INDEX_KEY], temp[INDEX_VALUE]);
697         } else if (temp[INDEX_TYPE] == "double") {
698             valuesBucket.Put(temp[INDEX_KEY], std::stod(temp[INDEX_VALUE]));
699         } else if (temp[INDEX_TYPE] == "bool") {
700             bool valueBool = false;
701             if (temp[INDEX_VALUE] == "1" || temp[INDEX_VALUE] == "true") {
702                 valueBool = true;
703             }
704             valuesBucket.Put(temp[INDEX_KEY], valueBool);
705         } else if (temp[INDEX_TYPE] == "null") {
706             valuesBucket.Put(temp[INDEX_KEY]);
707         } else if (temp[INDEX_TYPE] == "vector") {
708             std::vector<std::string> arr = ReminderRequest::StringSplit(temp[INDEX_VALUE],
709                 ReminderRequest::SEP_BUTTON_VALUE_BLOB);
710             std::vector<uint8_t> value;
711             for (auto &num : arr) {
712                 value.emplace_back(static_cast<uint8_t>(std::atoi(num.c_str())));
713             }
714             valuesBucket.Put(temp[INDEX_KEY], value);
715         }
716     }
717 }
718 
GenDstBundleName(std::string & dstBundleName,const std::string & uri) const719 void ReminderDataManager::GenDstBundleName(std::string &dstBundleName, const std::string &uri) const
720 {
721     size_t left = 0;
722     size_t right = 0;
723     left = uri.find("/", left);
724     right = uri.find("/", left + 1);
725     while (right != std::string::npos && right - left <= 1) {
726         left = right + 1;
727         right = uri.find("/", left);
728     }
729     if (left == std::string::npos) {
730         return;
731     }
732     if (right != std::string::npos) {
733         dstBundleName = uri.substr(left, right - left);
734     } else {
735         dstBundleName = uri.substr(left);
736     }
737 }
738 
RefreshRemindersDueToSysTimeChange(uint8_t type)739 void ReminderDataManager::RefreshRemindersDueToSysTimeChange(uint8_t type)
740 {
741     std::string typeInfo = type == TIME_ZONE_CHANGE ? "timeZone" : "dateTime";
742     ANSR_LOGI("Refresh all reminders due to %{public}s changed by user", typeInfo.c_str());
743     if (activeReminderId_ != -1) {
744         ANSR_LOGD("Stop active reminder due to date/time or timeZone change");
745         activeReminder_->OnStop();
746         StopTimerLocked(TimerType::TRIGGER_TIMER);
747     }
748     std::vector<sptr<ReminderRequest>> showImmediately = RefreshRemindersLocked(type);
749     if (!showImmediately.empty()) {
750         ANSR_LOGD("Refresh all reminders, show expired reminders immediately");
751         HandleImmediatelyShow(showImmediately, true);
752     }
753     StartRecentReminder();
754 }
755 
TerminateAlerting(const OHOS::EventFwk::Want & want)756 void ReminderDataManager::TerminateAlerting(const OHOS::EventFwk::Want &want)
757 {
758     int32_t reminderId = static_cast<int32_t>(want.GetIntParam(ReminderRequest::PARAM_REMINDER_ID, -1));
759     sptr<ReminderRequest> reminder = FindReminderRequestLocked(reminderId);
760     if (reminder == nullptr) {
761         ANSR_LOGE("Invalid reminder id: %{public}d", reminderId);
762         return;
763     }
764     TerminateAlerting(reminder, "timeOut");
765 }
766 
TerminateAlerting(const uint16_t waitInSecond,const sptr<ReminderRequest> & reminder)767 void ReminderDataManager::TerminateAlerting(const uint16_t waitInSecond, const sptr<ReminderRequest> &reminder)
768 {
769     sleep(waitInSecond);
770     TerminateAlerting(reminder, "waitInMillis");
771 }
772 
TerminateAlerting(const sptr<ReminderRequest> & reminder,const std::string & reason)773 void ReminderDataManager::TerminateAlerting(const sptr<ReminderRequest> &reminder, const std::string &reason)
774 {
775     if (reminder == nullptr) {
776         ANSR_LOGE("TerminateAlerting illegal.");
777         return;
778     }
779     ANSR_LOGI("Terminate the alerting reminder, %{public}s, called by %{public}s",
780         reminder->Dump().c_str(), reason.c_str());
781     StopAlertingReminder(reminder);
782 
783     if (!reminder->OnTerminate()) {
784         return;
785     }
786     int32_t reminderId = reminder->GetReminderId();
787     sptr<NotificationBundleOption> bundleOption = FindNotificationBundleOption(reminderId);
788     sptr<NotificationRequest> notificationRequest = reminder->GetNotificationRequest();
789     if (bundleOption == nullptr) {
790         ANSR_LOGE("Get bundle option fail, reminderId=%{public}d", reminderId);
791         return;
792     }
793     ANSR_LOGD("publish(update) notification.(reminderId=%{public}d)", reminder->GetReminderId());
794     UpdateNotification(reminder, false);
795     if (advancedNotificationService_ == nullptr) {
796         ANSR_LOGE("Ans instance is null.");
797         return;
798     }
799     // Set the notification SoundEnabled and VibrationEnabled by soltType
800     advancedNotificationService_->SetRequestBySlotType(notificationRequest);
801     advancedNotificationService_->PublishPreparedNotification(notificationRequest, bundleOption);
802     store_->UpdateOrInsert(reminder, FindNotificationBundleOption(reminder->GetReminderId()));
803 }
804 
UpdateAndSaveReminderLocked(const sptr<ReminderRequest> & reminder,const sptr<NotificationBundleOption> & bundleOption)805 void ReminderDataManager::UpdateAndSaveReminderLocked(
806     const sptr<ReminderRequest> &reminder, const sptr<NotificationBundleOption> &bundleOption)
807 {
808     std::lock_guard<std::mutex> lock(ReminderDataManager::MUTEX);
809     reminder->InitReminderId();
810     reminder->InitUserId(ReminderRequest::GetUserId(bundleOption->GetUid()));
811     reminder->InitUid(bundleOption->GetUid());
812     reminder->InitBundleName(bundleOption->GetBundleName());
813 
814     if (reminder->GetTriggerTimeInMilli() == ReminderRequest::INVALID_LONG_LONG_VALUE) {
815         ANSR_LOGW("now publish reminder is expired. reminder is =%{public}s",
816             reminder->Dump().c_str());
817         reminder->SetExpired(true);
818     }
819     int32_t reminderId = reminder->GetReminderId();
820     ANSR_LOGD("Containers(map) add. reminderId=%{public}d", reminderId);
821     auto ret = notificationBundleOptionMap_.insert(
822         std::pair<int32_t, sptr<NotificationBundleOption>>(reminderId, bundleOption));
823     if (!ret.second) {
824         ANSR_LOGE("Containers add to map error");
825         return;
826     }
827     ANSR_LOGD("Containers(vector) add. reminderId=%{public}d", reminderId);
828     reminderVector_.push_back(reminder);
829     totalCount_++;
830     store_->UpdateOrInsert(reminder, bundleOption);
831 }
832 
SetService(sptr<AdvancedNotificationService> & advancedNotificationService)833 void ReminderDataManager::SetService(sptr<AdvancedNotificationService> &advancedNotificationService)
834 {
835     advancedNotificationService_ = advancedNotificationService;
836 }
837 
ShouldAlert(const sptr<ReminderRequest> & reminder) const838 bool ReminderDataManager::ShouldAlert(const sptr<ReminderRequest> &reminder) const
839 {
840     if (reminder == nullptr) {
841         return false;
842     }
843     int32_t reminderId = reminder->GetReminderId();
844     sptr<NotificationBundleOption> bundleOption = FindNotificationBundleOption(reminderId);
845     if (bundleOption == nullptr) {
846         ANSR_LOGD("The reminder (reminderId=%{public}d) is silent", reminderId);
847         return false;
848     }
849     int32_t userId = ReminderRequest::GetUserId(bundleOption->GetUid());
850     if (currentUserId_ != userId) {
851         ANSR_LOGD("The reminder (reminderId=%{public}d) is silent for not in active user, " \
852             "current user id: %{public}d, reminder user id: %{public}d", reminderId, currentUserId_, userId);
853         return false;
854     }
855 
856     sptr<NotificationDoNotDisturbDate> date;
857     ErrCode errCode = advancedNotificationService_->GetDoNotDisturbDate(date);
858     if (errCode != ERR_OK) {
859         ANSR_LOGE("The reminder (reminderId=%{public}d) is silent for get disturbDate error", reminderId);
860         return false;
861     }
862     if (date->GetDoNotDisturbType() == NotificationConstant::DoNotDisturbType::NONE) {
863         return true;
864     }
865     std::vector<sptr<NotificationSlot>> slots;
866     errCode = advancedNotificationService_->GetSlotsByBundle(bundleOption, slots);
867     if (errCode != ERR_OK) {
868         ANSR_LOGE("The reminder (reminderId=%{public}d) is silent for get slots error", reminderId);
869         return false;
870     }
871     for (auto slot : slots) {
872         if (slot->GetType() != reminder->GetSlotType()) {
873             continue;
874         }
875         if (slot->IsEnableBypassDnd()) {
876             ANSR_LOGD("Not silent for enable by pass Dnd, reminderId=%{public}d", reminderId);
877             return true;
878         }
879     }
880     ANSR_LOGD("The reminder (reminderId=%{public}d) is silent for Dnd", reminderId);
881     return false;
882 }
883 
ShowActiveReminder(const EventFwk::Want & want)884 void ReminderDataManager::ShowActiveReminder(const EventFwk::Want &want)
885 {
886     int32_t reminderId = static_cast<int32_t>(want.GetIntParam(ReminderRequest::PARAM_REMINDER_ID, -1));
887     ANSR_LOGI("Begin to show reminder(reminderId=%{public}d)", reminderId);
888     if (reminderId == activeReminderId_) {
889         ResetStates(TimerType::TRIGGER_TIMER);
890     }
891     sptr<ReminderRequest> reminder = FindReminderRequestLocked(reminderId);
892     if (reminder == nullptr) {
893         ANSR_LOGW("Invalid reminder id: %{public}d", reminderId);
894         return;
895     }
896     if (HandleSysTimeChange(reminder)) {
897         return;
898     }
899     ShowActiveReminderExtendLocked(reminder);
900     StartRecentReminder();
901 }
902 
HandleSysTimeChange(const sptr<ReminderRequest> reminder) const903 bool ReminderDataManager::HandleSysTimeChange(const sptr<ReminderRequest> reminder) const
904 {
905     if (reminder->CanShow()) {
906         return false;
907     } else {
908         ANSR_LOGI("handleSystimeChange, no need to show reminder again.");
909         return true;
910     }
911 }
912 
SetActiveReminder(const sptr<ReminderRequest> & reminder)913 void ReminderDataManager::SetActiveReminder(const sptr<ReminderRequest> &reminder)
914 {
915     if (reminder == nullptr) {
916         // activeReminder_ should not be set with null as it point to actual object.
917         activeReminderId_ = -1;
918     } else {
919         activeReminderId_ = reminder->GetReminderId();
920         activeReminder_ = reminder;
921         ANSR_LOGD("Set activeReminder with id=%{public}d", activeReminderId_);
922     }
923     ANSR_LOGD("Set activeReminderId=%{public}d", activeReminderId_);
924 }
925 
SetAlertingReminder(const sptr<ReminderRequest> & reminder)926 void ReminderDataManager::SetAlertingReminder(const sptr<ReminderRequest> &reminder)
927 {
928     if (reminder == nullptr) {
929         // alertingReminder_ should not be set with null as it point to actual object.
930         alertingReminderId_ = -1;
931     } else {
932         alertingReminderId_ = reminder->GetReminderId();
933         alertingReminder_ = reminder;
934         ANSR_LOGD("Set alertingReminder with id=%{public}d", alertingReminderId_);
935     }
936     ANSR_LOGD("Set alertingReminderId=%{public}d", alertingReminderId_);
937 }
938 
ShowActiveReminderExtendLocked(sptr<ReminderRequest> & reminder)939 void ReminderDataManager::ShowActiveReminderExtendLocked(sptr<ReminderRequest> &reminder)
940 {
941     std::lock_guard<std::mutex> lock(ReminderDataManager::MUTEX);
942     uint64_t triggerTime = reminder->GetTriggerTimeInMilli();
943     bool isAlerting = false;
944     sptr<ReminderRequest> playSoundReminder = nullptr;
945     for (auto it = reminderVector_.begin(); it != reminderVector_.end(); ++it) {
946         if ((*it)->IsExpired()) {
947             continue;
948         }
949         uint64_t tempTriggerTime = (*it)->GetTriggerTimeInMilli();
950         if (tempTriggerTime < triggerTime) {
951             ANSR_LOGE("this reminder triggerTime is less than target triggerTime. "
952                 "now trigger time is %{public}llu.", tempTriggerTime);
953             continue;
954         }
955         if (tempTriggerTime - triggerTime > ReminderRequest::SAME_TIME_DISTINGUISH_MILLISECONDS) {
956             continue;
957         }
958         if (!isAlerting) {
959             playSoundReminder = (*it);
960             isAlerting = true;
961         } else {
962             ShowReminder((*it), false, false, false, false);
963         }
964     }
965     if (playSoundReminder != nullptr) {
966         ShowReminder(playSoundReminder, true, false, false, true);
967     }
968 }
969 
ShowReminder(const sptr<ReminderRequest> & reminder,const bool & isNeedToPlaySound,const bool & isNeedToStartNext,const bool & isSysTimeChanged,const bool & needScheduleTimeout)970 void ReminderDataManager::ShowReminder(const sptr<ReminderRequest> &reminder, const bool &isNeedToPlaySound,
971     const bool &isNeedToStartNext, const bool &isSysTimeChanged, const bool &needScheduleTimeout)
972 {
973     ANSR_LOGD("Show the reminder(Play sound: %{public}d), %{public}s",
974         static_cast<int32_t>(isNeedToPlaySound), reminder->Dump().c_str());
975     int32_t reminderId = reminder->GetReminderId();
976     sptr<NotificationBundleOption> bundleOption = FindNotificationBundleOption(reminderId);
977     sptr<NotificationRequest> notificationRequest = reminder->GetNotificationRequest();
978     if (bundleOption == nullptr) {
979         ANSR_LOGE("Get bundle option fail, reminderId=%{public}d", reminderId);
980         return;
981     }
982     if (advancedNotificationService_ == nullptr) {
983         ANSR_LOGE("ShowReminder fail");
984         reminder->OnShow(false, isSysTimeChanged, false);
985         store_->UpdateOrInsert(reminder, FindNotificationBundleOption(reminder->GetReminderId()));
986         return;
987     }
988     if (!IsAllowedNotify(reminder)) {
989         ANSR_LOGE("Not allow to notify.");
990         reminder->OnShow(false, isSysTimeChanged, false);
991         store_->UpdateOrInsert(reminder, FindNotificationBundleOption(reminder->GetReminderId()));
992         return;
993     }
994     bool toPlaySound = isNeedToPlaySound && ShouldAlert(reminder) ? true : false;
995     reminder->OnShow(toPlaySound, isSysTimeChanged, true);
996     AddToShowedReminders(reminder);
997     UpdateNotification(reminder, false);  // this should be called after OnShow
998 
999     if (alertingReminderId_ != -1) {
1000         TerminateAlerting(alertingReminder_, "PlaySoundAndVibration");
1001     }
1002     // Set the notification SoundEnabled and VibrationEnabled by soltType
1003     advancedNotificationService_->SetRequestBySlotType(notificationRequest);
1004     ANSR_LOGD("publish notification.(reminderId=%{public}d)", reminder->GetReminderId());
1005     ErrCode errCode = advancedNotificationService_->PublishPreparedNotification(notificationRequest, bundleOption);
1006     if (errCode != ERR_OK) {
1007         reminder->OnShowFail();
1008         RemoveFromShowedReminders(reminder);
1009     } else {
1010         if (toPlaySound) {
1011             PlaySoundAndVibration(reminder);  // play sound and vibration
1012             if (needScheduleTimeout) {
1013                 StartTimer(reminder, TimerType::ALERTING_TIMER);
1014             } else {
1015                 TerminateAlerting(1, reminder);
1016             }
1017         }
1018         HandleSameNotificationIdShowing(reminder);
1019     }
1020     store_->UpdateOrInsert(reminder, FindNotificationBundleOption(reminder->GetReminderId()));
1021 
1022     if (isNeedToStartNext) {
1023         StartRecentReminder();
1024     }
1025 }
1026 
UpdateNotification(const sptr<ReminderRequest> & reminder,bool isSnooze)1027 void ReminderDataManager::UpdateNotification(const sptr<ReminderRequest> &reminder, bool isSnooze)
1028 {
1029     int32_t reminderId = reminder->GetReminderId();
1030     sptr<NotificationBundleOption> bundleOption = FindNotificationBundleOption(reminderId);
1031     if (bundleOption == nullptr) {
1032         ANSR_LOGE("Get bundle option fail, reminderId=%{public}d", reminderId);
1033         return;
1034     }
1035     if (isSnooze) {
1036         reminder->UpdateNotificationRequest(ReminderRequest::UpdateNotificationType::COMMON, "snooze");
1037     } else {
1038         reminder->UpdateNotificationRequest(ReminderRequest::UpdateNotificationType::COMMON, "");
1039     }
1040     reminder->UpdateNotificationRequest(ReminderRequest::UpdateNotificationType::REMOVAL_WANT_AGENT, "");
1041     reminder->UpdateNotificationRequest(ReminderRequest::UpdateNotificationType::WANT_AGENT, "");
1042     reminder->UpdateNotificationRequest(ReminderRequest::UpdateNotificationType::MAX_SCREEN_WANT_AGENT, "");
1043     reminder->UpdateNotificationRequest(ReminderRequest::UpdateNotificationType::BUNDLE_INFO, "");
1044 }
1045 
SnoozeReminder(const OHOS::EventFwk::Want & want)1046 void ReminderDataManager::SnoozeReminder(const OHOS::EventFwk::Want &want)
1047 {
1048     int32_t reminderId = static_cast<int32_t>(want.GetIntParam(ReminderRequest::PARAM_REMINDER_ID, -1));
1049     sptr<ReminderRequest> reminder = FindReminderRequestLocked(reminderId);
1050     if (reminder == nullptr) {
1051         ANSR_LOGW("Invalid reminder id: %{public}d", reminderId);
1052         return;
1053     }
1054     SnoozeReminderImpl(reminder);
1055     UpdateAppDatabase(reminder, ReminderRequest::ActionButtonType::SNOOZE);
1056     CheckNeedNotifyStatus(reminder, ReminderRequest::ActionButtonType::SNOOZE);
1057 }
1058 
SnoozeReminderImpl(sptr<ReminderRequest> & reminder)1059 void ReminderDataManager::SnoozeReminderImpl(sptr<ReminderRequest> &reminder)
1060 {
1061     ANSR_LOGI("Snooze the reminder request, %{public}s", reminder->Dump().c_str());
1062     int32_t reminderId = reminder->GetReminderId();
1063     if (activeReminderId_ == reminderId) {
1064         ANSR_LOGD("Cancel active reminder, id=%{public}d", activeReminderId_);
1065         activeReminder_->OnStop();
1066         StopTimerLocked(TimerType::TRIGGER_TIMER);
1067     }
1068 
1069     // 1) Snooze the reminder by manual
1070     if (alertingReminderId_ == reminder->GetReminderId()) {
1071         StopSoundAndVibrationLocked(reminder);
1072         StopTimerLocked(TimerType::ALERTING_TIMER);
1073     }
1074     reminder->OnSnooze();
1075     store_->UpdateOrInsert(reminder, FindNotificationBundleOption(reminder->GetReminderId()));
1076 
1077     // 2) Show the notification dialog in the systemUI
1078     sptr<NotificationBundleOption> bundleOption = FindNotificationBundleOption(reminderId);
1079     sptr<NotificationRequest> notificationRequest = reminder->GetNotificationRequest();
1080     if (bundleOption == nullptr) {
1081         ANSR_LOGW("snoozeReminder, invalid bundle option");
1082         return;
1083     }
1084     ANSR_LOGD("publish(update) notification.(reminderId=%{public}d)", reminder->GetReminderId());
1085     UpdateNotification(reminder, true);
1086     if (advancedNotificationService_ == nullptr) {
1087         ANSR_LOGE("Ans instance is null");
1088         return;
1089     }
1090     // Set the notification SoundEnabled and VibrationEnabled by soltType
1091     advancedNotificationService_->SetRequestBySlotType(notificationRequest);
1092     advancedNotificationService_->PublishPreparedNotification(notificationRequest, bundleOption);
1093     StartRecentReminder();
1094 }
1095 
StartRecentReminder()1096 void ReminderDataManager::StartRecentReminder()
1097 {
1098     sptr<ReminderRequest> reminder = GetRecentReminderLocked();
1099     if (reminder == nullptr) {
1100         ANSR_LOGI("No reminder need to start");
1101         SetActiveReminder(reminder);
1102         return;
1103     }
1104     if (activeReminderId_ == reminder->GetReminderId()) {
1105         ANSR_LOGI("Recent reminder has already run, no need to start again.");
1106         return;
1107     }
1108     if (activeReminderId_ != -1) {
1109         activeReminder_->OnStop();
1110         store_->UpdateOrInsert(activeReminder_, FindNotificationBundleOption(activeReminderId_));
1111         StopTimerLocked(TimerType::TRIGGER_TIMER);
1112     }
1113     ANSR_LOGI("Start recent reminder");
1114     StartTimerLocked(reminder, TimerType::TRIGGER_TIMER);
1115     reminder->OnStart();
1116     store_->UpdateOrInsert(reminder, FindNotificationBundleOption(reminder->GetReminderId()));
1117 }
1118 
StopAlertingReminder(const sptr<ReminderRequest> & reminder)1119 void ReminderDataManager::StopAlertingReminder(const sptr<ReminderRequest> &reminder)
1120 {
1121     if (reminder == nullptr) {
1122         ANSR_LOGE("StopAlertingReminder illegal.");
1123         return;
1124     }
1125     if ((alertingReminderId_ == -1) || (reminder->GetReminderId() != alertingReminderId_)) {
1126         ANSR_LOGE("StopAlertingReminder is illegal.");
1127         return;
1128     }
1129     StopSoundAndVibration(alertingReminder_);
1130     StopTimer(TimerType::ALERTING_TIMER);
1131 }
1132 
Dump() const1133 std::string ReminderDataManager::Dump() const
1134 {
1135     std::lock_guard<std::mutex> lock(ReminderDataManager::MUTEX);
1136     std::map<std::string, std::vector<sptr<ReminderRequest>>> bundleNameMap;
1137     for (auto it = reminderVector_.begin(); it != reminderVector_.end(); ++it) {
1138         if ((*it)->IsExpired()) {
1139             continue;
1140         }
1141         int32_t reminderId = (*it)->GetReminderId();
1142         auto mit = notificationBundleOptionMap_.find(reminderId);
1143         if (mit == notificationBundleOptionMap_.end()) {
1144             ANSR_LOGE("Dump get notificationBundleOption(reminderId=%{public}d) fail", reminderId);
1145             continue;
1146         }
1147         std::string bundleName = mit->second->GetBundleName();
1148         auto val = bundleNameMap.find(bundleName);
1149         if (val == bundleNameMap.end()) {
1150             std::vector<sptr<ReminderRequest>> reminders;
1151             reminders.push_back(*it);
1152             bundleNameMap.insert(std::pair<std::string, std::vector<sptr<ReminderRequest>>>(bundleName, reminders));
1153         } else {
1154             val->second.push_back(*it);
1155         }
1156     }
1157 
1158     std::string allReminders = "";
1159     for (auto it = bundleNameMap.begin(); it != bundleNameMap.end(); ++it) {
1160         std::string bundleName = it->first;
1161         std::vector<sptr<ReminderRequest>> reminders = it->second;
1162         sort(reminders.begin(), reminders.end(), cmp);
1163         std::string oneBundleReminders = bundleName + ":{\n";
1164         oneBundleReminders += "    totalCount:" + std::to_string(reminders.size()) + ",\n";
1165         oneBundleReminders += "    reminders:{\n";
1166         for (auto vit = reminders.begin(); vit != reminders.end(); ++vit) {
1167             oneBundleReminders += "        [\n";
1168             std::string reminderInfo = (*vit)->Dump();
1169             oneBundleReminders += "            " + reminderInfo + "\n";
1170             oneBundleReminders += "        ],\n";
1171         }
1172         oneBundleReminders += "    },\n";
1173         oneBundleReminders += "},\n";
1174         allReminders += oneBundleReminders;
1175     }
1176 
1177     return "ReminderDataManager{ totalCount:" + std::to_string(totalCount_) + ",\n" +
1178            "timerId:" + std::to_string(timerId_) + ",\n" +
1179            "activeReminderId:" + std::to_string(activeReminderId_) + ",\n" +
1180            allReminders + "}";
1181 }
1182 
GetRecentReminderLocked()1183 sptr<ReminderRequest> ReminderDataManager::GetRecentReminderLocked()
1184 {
1185     std::lock_guard<std::mutex> lock(ReminderDataManager::MUTEX);
1186     sort(reminderVector_.begin(), reminderVector_.end(), cmp);
1187     for (auto it = reminderVector_.begin(); it != reminderVector_.end();) {
1188         if (!(*it)->IsExpired()) {
1189             ANSR_LOGI("GetRecentReminderLocked: %{public}s", (*it)->Dump().c_str());
1190             time_t now;
1191             (void)time(&now);  // unit is seconds.
1192             if (now < 0
1193                 || ReminderRequest::GetDurationSinceEpochInMilli(now) > (*it)->GetTriggerTimeInMilli()) {
1194                 ANSR_LOGE("Get recent reminder while the trigger time is overdue.");
1195                 it++;
1196                 continue;
1197             }
1198             return *it;
1199         }
1200         if (!(*it)->CanRemove()) {
1201             ANSR_LOGD("Reminder has been expired: %{public}s", (*it)->Dump().c_str());
1202             it++;
1203             continue;
1204         }
1205         int32_t reminderId = (*it)->GetReminderId();
1206         ANSR_LOGD("Containers(vector) remove. reminderId=%{public}d", reminderId);
1207         auto mit = notificationBundleOptionMap_.find(reminderId);
1208         if (mit == notificationBundleOptionMap_.end()) {
1209             ANSR_LOGE("Remove notificationBundleOption(reminderId=%{public}d) fail", reminderId);
1210         } else {
1211             ANSR_LOGD("Containers(map) remove. reminderId=%{public}d", reminderId);
1212             notificationBundleOptionMap_.erase(mit);
1213         }
1214         it = reminderVector_.erase(it);
1215         totalCount_--;
1216         store_->Delete(reminderId);
1217     }
1218     return nullptr;
1219 }
1220 
HandleImmediatelyShow(std::vector<sptr<ReminderRequest>> & showImmediately,bool isSysTimeChanged)1221 void ReminderDataManager::HandleImmediatelyShow(
1222     std::vector<sptr<ReminderRequest>> &showImmediately, bool isSysTimeChanged)
1223 {
1224     bool isAlerting = false;
1225     for (auto it = showImmediately.begin(); it != showImmediately.end(); ++it) {
1226         if (!isAlerting) {
1227             ShowReminder((*it), true, false, isSysTimeChanged, false);
1228             isAlerting = true;
1229         } else {
1230             ShowReminder((*it), false, false, isSysTimeChanged, false);
1231         }
1232     }
1233 }
1234 
HandleRefreshReminder(const uint8_t & type,sptr<ReminderRequest> & reminder)1235 sptr<ReminderRequest> ReminderDataManager::HandleRefreshReminder(const uint8_t &type, sptr<ReminderRequest> &reminder)
1236 {
1237     reminder->SetReminderTimeInMilli(ReminderRequest::INVALID_LONG_LONG_VALUE);
1238     uint64_t triggerTimeBefore = reminder->GetTriggerTimeInMilli();
1239     bool needShowImmediately = false;
1240     if (type == TIME_ZONE_CHANGE) {
1241         needShowImmediately = reminder->OnTimeZoneChange();
1242     }
1243     if (type == DATE_TIME_CHANGE) {
1244         needShowImmediately = reminder->OnDateTimeChange();
1245     }
1246     if (!needShowImmediately) {
1247         uint64_t triggerTimeAfter = reminder->GetTriggerTimeInMilli();
1248         if (triggerTimeBefore != triggerTimeAfter || reminder->GetReminderId() == alertingReminderId_) {
1249             CloseReminder(reminder, true);
1250         }
1251         store_->UpdateOrInsert(reminder, FindNotificationBundleOption(reminder->GetReminderId()));
1252         return nullptr;
1253     }
1254     store_->UpdateOrInsert(reminder, FindNotificationBundleOption(reminder->GetReminderId()));
1255     return reminder;
1256 }
1257 
HandleSameNotificationIdShowing(const sptr<ReminderRequest> reminder)1258 void ReminderDataManager::HandleSameNotificationIdShowing(const sptr<ReminderRequest> reminder)
1259 {
1260     // not add ReminderDataManager::MUTEX, as ShowActiveReminderExtendLocked has locked
1261     int32_t notificationId = reminder->GetNotificationId();
1262     ANSR_LOGD("HandleSameNotificationIdShowing notificationId=%{public}d", notificationId);
1263     int32_t curReminderId = reminder->GetReminderId();
1264     auto mit = notificationBundleOptionMap_.find(curReminderId);
1265     if (mit == notificationBundleOptionMap_.end()) {
1266         ANSR_LOGE("Error occur when get bundle option, reminderId=%{public}d", curReminderId);
1267         return;
1268     }
1269 
1270     for (auto it = reminderVector_.begin(); it != reminderVector_.end(); ++it) {
1271         int32_t tmpId = (*it)->GetReminderId();
1272         if (tmpId == curReminderId) {
1273             continue;
1274         }
1275         if (!(*it)->IsShowing()) {
1276             continue;
1277         }
1278         sptr<NotificationBundleOption>  bundleOption = FindNotificationBundleOption(tmpId);
1279         if (bundleOption == nullptr) {
1280             ANSR_LOGW("Get notificationBundleOption(reminderId=%{public}d) fail", tmpId);
1281             continue;
1282         }
1283         if (notificationId == (*it)->GetNotificationId() && IsBelongToSameApp(bundleOption, mit->second)) {
1284             if ((*it)->IsAlerting()) {
1285                 StopAlertingReminder(*it);
1286             }
1287             (*it)->OnSameNotificationIdCovered();
1288             RemoveFromShowedReminders(*it);
1289             store_->UpdateOrInsert((*it), FindNotificationBundleOption((*it)->GetReminderId()));
1290         }
1291     }
1292 }
1293 
Init(bool isFromBootComplete)1294 void ReminderDataManager::Init(bool isFromBootComplete)
1295 {
1296     ANSR_LOGD("ReminderDataManager Init, isFromBootComplete:%{public}d", isFromBootComplete);
1297     if (IsReminderAgentReady()) {
1298         return;
1299     }
1300     // Register config observer for language change
1301     if (!RegisterConfigurationObserver()) {
1302         ANSR_LOGW("Register configuration observer failed.");
1303         return;
1304     }
1305     if (queue_ == nullptr) {
1306         queue_ = std::make_shared<ffrt::queue>("ReminderDataManager");
1307         if (queue_ == nullptr) {
1308             ANSR_LOGE("create ffrt queue failed!");
1309             return;
1310         }
1311     }
1312     if (store_ == nullptr) {
1313         store_ = std::make_shared<ReminderStore>();
1314     }
1315     if (store_->Init() != ReminderStore::STATE_OK) {
1316         ANSR_LOGW("Db init fail.");
1317         return;
1318     }
1319     LoadReminderFromDb();
1320     InitUserId();
1321     isReminderAgentReady_ = true;
1322     ANSR_LOGD("ReminderAgent is ready.");
1323 }
1324 
InitUserId()1325 void ReminderDataManager::InitUserId()
1326 {
1327     std::vector<int32_t> activeUserId;
1328     AccountSA::OsAccountManager::QueryActiveOsAccountIds(activeUserId);
1329     if (activeUserId.size() > 0) {
1330         currentUserId_ = activeUserId[0];
1331         ANSR_LOGD("Init user id=%{public}d", currentUserId_);
1332     } else {
1333         currentUserId_ = MAIN_USER_ID;
1334         ANSR_LOGE("Failed to get active user id.");
1335     }
1336 }
1337 
RegisterConfigurationObserver()1338 bool ReminderDataManager::RegisterConfigurationObserver()
1339 {
1340     if (configChangeObserver_ != nullptr) {
1341         return true;
1342     }
1343 
1344     auto appMgrClient = std::make_shared<AppExecFwk::AppMgrClient>();
1345     if (appMgrClient->ConnectAppMgrService() != ERR_OK) {
1346         ANSR_LOGW("Connect to app mgr service failed.");
1347         return false;
1348     }
1349 
1350     configChangeObserver_ = sptr<AppExecFwk::IConfigurationObserver>(
1351         new (std::nothrow) ReminderConfigChangeObserver());
1352     if (appMgrClient->RegisterConfigurationObserver(configChangeObserver_) != ERR_OK) {
1353         ANSR_LOGE("Register configuration observer failed.");
1354         return false;
1355     }
1356     return true;
1357 }
1358 
GetImmediatelyShowRemindersLocked(std::vector<sptr<ReminderRequest>> & reminders) const1359 void ReminderDataManager::GetImmediatelyShowRemindersLocked(std::vector<sptr<ReminderRequest>> &reminders) const
1360 {
1361     std::lock_guard<std::mutex> lock(ReminderDataManager::MUTEX);
1362     for (auto reminderSptr : reminderVector_) {
1363         if (!(reminderSptr->ShouldShowImmediately())) {
1364             break;
1365         }
1366         if (reminderSptr->GetReminderType() != ReminderRequest::ReminderType::TIMER) {
1367             reminderSptr->SetSnoozeTimesDynamic(0);
1368         }
1369         reminders.push_back(reminderSptr);
1370     }
1371 }
1372 
IsAllowedNotify(const sptr<ReminderRequest> & reminder) const1373 bool ReminderDataManager::IsAllowedNotify(const sptr<ReminderRequest> &reminder) const
1374 {
1375     if (reminder == nullptr) {
1376         return false;
1377     }
1378     int32_t reminderId = reminder->GetReminderId();
1379     auto mit = notificationBundleOptionMap_.find(reminderId);
1380     if (mit == notificationBundleOptionMap_.end()) {
1381         ANSR_LOGE("Get bundle option occur error, reminderId=%{public}d", reminderId);
1382         return false;
1383     }
1384     bool isAllowed = false;
1385     ErrCode errCode = advancedNotificationService_->IsSpecialBundleAllowedNotify(mit->second, isAllowed);
1386     if (errCode != ERR_OK) {
1387         ANSR_LOGE("Failed to call IsSpecialBundleAllowedNotify, errCode=%{public}d", errCode);
1388         return false;
1389     }
1390     return isAllowed;
1391 }
1392 
IsReminderAgentReady() const1393 bool ReminderDataManager::IsReminderAgentReady() const
1394 {
1395     return isReminderAgentReady_;
1396 }
1397 
IsBelongToSameApp(const sptr<NotificationBundleOption> & bundleOption,const sptr<NotificationBundleOption> & other) const1398 bool ReminderDataManager::IsBelongToSameApp(const sptr<NotificationBundleOption> &bundleOption,
1399     const sptr<NotificationBundleOption> &other) const
1400 {
1401     int32_t userIdSrc = ReminderRequest::GetUserId(bundleOption->GetUid());
1402     int32_t userIdTar = ReminderRequest::GetUserId(other->GetUid());
1403     return ((bundleOption->GetBundleName() == other->GetBundleName()) && (userIdSrc == userIdTar)) ? true : false;
1404 }
1405 
LoadReminderFromDb()1406 void ReminderDataManager::LoadReminderFromDb()
1407 {
1408     std::lock_guard<std::mutex> lock(ReminderDataManager::MUTEX);
1409     std::vector<sptr<ReminderRequest>> existReminders = store_->GetAllValidReminders();
1410     reminderVector_ = existReminders;
1411     ANSR_LOGD("LoadReminderFromDb, reminder size=%{public}zu", reminderVector_.size());
1412     for (auto it = reminderVector_.begin(); it != reminderVector_.end(); ++it) {
1413         sptr<NotificationBundleOption> bundleOption = new (std::nothrow) NotificationBundleOption();
1414         if (bundleOption == nullptr) {
1415             ANS_LOGE("Failed to create bundle option due to low memory.");
1416             return;
1417         }
1418         int32_t reminderId = (*it)->GetReminderId();
1419         if (!(store_->GetBundleOption(reminderId, bundleOption))) {
1420             ANSR_LOGE("Get bundle option fail, reminderId=%{public}d", reminderId);
1421             continue;
1422         }
1423         auto ret = notificationBundleOptionMap_.insert(
1424             std::pair<int32_t, sptr<NotificationBundleOption>>(reminderId, bundleOption));
1425         if (!ret.second) {
1426             ANSR_LOGE("Containers add to map error");
1427             continue;
1428         }
1429     }
1430     totalCount_ = static_cast<int16_t>(reminderVector_.size());
1431     ReminderRequest::GLOBAL_ID = store_->GetMaxId() + 1;
1432 }
1433 
PlaySoundAndVibrationLocked(const sptr<ReminderRequest> & reminder)1434 void ReminderDataManager::PlaySoundAndVibrationLocked(const sptr<ReminderRequest> &reminder)
1435 {
1436     std::lock_guard<std::mutex> lock(ReminderDataManager::ALERT_MUTEX);
1437     PlaySoundAndVibration(reminder);
1438 }
1439 
GetCustomRingUri(const sptr<ReminderRequest> & reminder)1440 std::string ReminderDataManager::GetCustomRingUri(const sptr<ReminderRequest> &reminder) {
1441     if (reminder == nullptr) {
1442         return "";
1443     }
1444     return reminder->GetCustomRingUri();
1445 }
1446 
PlaySoundAndVibration(const sptr<ReminderRequest> & reminder)1447 void ReminderDataManager::PlaySoundAndVibration(const sptr<ReminderRequest> &reminder)
1448 {
1449     if (reminder == nullptr) {
1450         ANSR_LOGE("Play sound and vibration failed as reminder is null.");
1451         return;
1452     }
1453     if (alertingReminderId_ != -1) {
1454         TerminateAlerting(alertingReminder_, "PlaySoundAndVibration");
1455     }
1456     ANSR_LOGD("Play sound and vibration, reminderId=%{public}d", reminder->GetReminderId());
1457 #ifdef PLAYER_FRAMEWORK_ENABLE
1458     if (soundPlayer_ == nullptr) {
1459         soundPlayer_ = Media::PlayerFactory::CreatePlayer();
1460         if (soundPlayer_ == nullptr) {
1461             ANSR_LOGE("Fail to creat player.");
1462             return;
1463         }
1464     }
1465     std::string ringUri = GetCustomRingUri(reminder);
1466     Uri reminderSound(ringUri);
1467     Uri soundUri = ringUri.empty() ? DEFAULT_REMINDER_SOUND : reminderSound;
1468     std::string uri = soundUri.GetSchemeSpecificPart();
1469     ANSR_LOGD("uri:%{public}s", uri.c_str());
1470     soundPlayer_->SetSource(uri);
1471     soundPlayer_->SetLooping(true);
1472     soundPlayer_->PrepareAsync();
1473     soundPlayer_->Play();
1474 #endif
1475     SetAlertingReminder(reminder);
1476 }
1477 
GetSoundUri(const sptr<ReminderRequest> & reminder)1478 std::string ReminderDataManager::GetSoundUri(const sptr<ReminderRequest> &reminder)
1479 {
1480     Uri uri = DEFAULT_NOTIFICATION_SOUND;
1481     if (advancedNotificationService_ == nullptr) {
1482         ANSR_LOGE("Ans instance is null.");
1483         return uri.GetSchemeSpecificPart();
1484     }
1485     sptr<NotificationBundleOption> bundle = FindNotificationBundleOption(reminder->GetReminderId());
1486     std::vector<sptr<NotificationSlot>> slots;
1487     ErrCode errCode = advancedNotificationService_->GetSlotsByBundle(bundle, slots);
1488     if (errCode != ERR_OK) {
1489         ANSR_LOGW("Get sound uri fail, use default sound instead.");
1490         return uri.GetSchemeSpecificPart();
1491     }
1492     for (auto it = slots.begin(); it != slots.end(); ++it) {
1493         if ((*it)->GetType() == reminder->GetSlotType()) {
1494             uri = (*it)->GetSound();
1495             break;
1496         }
1497     }
1498     return uri.GetSchemeSpecificPart();
1499 }
1500 
StopSoundAndVibrationLocked(const sptr<ReminderRequest> & reminder)1501 void ReminderDataManager::StopSoundAndVibrationLocked(const sptr<ReminderRequest> &reminder)
1502 {
1503     std::lock_guard<std::mutex> lock(ReminderDataManager::ALERT_MUTEX);
1504     StopSoundAndVibration(reminder);
1505 }
1506 
StopSoundAndVibration(const sptr<ReminderRequest> & reminder)1507 void ReminderDataManager::StopSoundAndVibration(const sptr<ReminderRequest> &reminder)
1508 {
1509     if (reminder == nullptr) {
1510         ANSR_LOGE("Stop sound and vibration failed as reminder is null.");
1511         return;
1512     }
1513     if ((alertingReminderId_ == -1) || (reminder->GetReminderId() != alertingReminderId_)) {
1514         ANSR_LOGE("Stop sound and vibration failed as alertingReminder is illegal, alertingReminderId_=" \
1515             "%{public}d, tarReminderId=%{public}d", alertingReminderId_, reminder->GetReminderId());
1516         return;
1517     }
1518     ANSR_LOGD("Stop sound and vibration, reminderId=%{public}d", reminder->GetReminderId());
1519 #ifdef PLAYER_FRAMEWORK_ENABLE
1520     if (soundPlayer_ == nullptr) {
1521         ANSR_LOGW("Sound player is null");
1522     } else {
1523         soundPlayer_->Stop();
1524         soundPlayer_->Release();
1525         soundPlayer_ = nullptr;
1526     }
1527 #endif
1528     sptr<ReminderRequest> nullReminder = nullptr;
1529     SetAlertingReminder(nullReminder);
1530 }
1531 
RemoveFromShowedReminders(const sptr<ReminderRequest> & reminder)1532 void ReminderDataManager::RemoveFromShowedReminders(const sptr<ReminderRequest> &reminder)
1533 {
1534     std::lock_guard<std::mutex> lock(ReminderDataManager::SHOW_MUTEX);
1535     for (auto it = showedReminderVector_.begin(); it != showedReminderVector_.end(); ++it) {
1536         if ((*it)->GetReminderId() == reminder->GetReminderId()) {
1537             ANSR_LOGD("Containers(shownVector) remove. reminderId=%{public}d", reminder->GetReminderId());
1538             showedReminderVector_.erase(it);
1539             break;
1540         }
1541     }
1542 }
1543 
RefreshRemindersLocked(uint8_t type)1544 std::vector<sptr<ReminderRequest>> ReminderDataManager::RefreshRemindersLocked(uint8_t type)
1545 {
1546     std::lock_guard<std::mutex> lock(ReminderDataManager::MUTEX);
1547     std::vector<sptr<ReminderRequest>> showImmediately;
1548     for (auto it = reminderVector_.begin(); it != reminderVector_.end(); ++it) {
1549         sptr<ReminderRequest> reminder = HandleRefreshReminder(type, (*it));
1550         if (reminder != nullptr) {
1551             showImmediately.push_back(reminder);
1552         }
1553     }
1554     return showImmediately;
1555 }
1556 
RemoveReminderLocked(const int32_t & reminderId)1557 void ReminderDataManager::RemoveReminderLocked(const int32_t &reminderId)
1558 {
1559     std::lock_guard<std::mutex> lock(ReminderDataManager::MUTEX);
1560     for (auto it = reminderVector_.begin(); it != reminderVector_.end();) {
1561         if (reminderId == (*it)->GetReminderId()) {
1562             ANSR_LOGD("Containers(vector) remove. reminderId=%{public}d", reminderId);
1563             it = reminderVector_.erase(it);
1564             totalCount_--;
1565             store_->Delete(reminderId);
1566             break;
1567         } else {
1568             ++it;
1569         }
1570     }
1571     auto it = notificationBundleOptionMap_.find(reminderId);
1572     if (it == notificationBundleOptionMap_.end()) {
1573         ANSR_LOGE("Remove notificationBundleOption(reminderId=%{public}d) fail", reminderId);
1574     } else {
1575         ANSR_LOGD("Containers(map) remove. reminderId=%{public}d", reminderId);
1576         notificationBundleOptionMap_.erase(it);
1577     }
1578 }
1579 
StartTimerLocked(const sptr<ReminderRequest> & reminderRequest,TimerType type)1580 void ReminderDataManager::StartTimerLocked(const sptr<ReminderRequest> &reminderRequest, TimerType type)
1581 {
1582     std::lock_guard<std::mutex> lock(ReminderDataManager::TIMER_MUTEX);
1583     StartTimer(reminderRequest, type);
1584 }
1585 
StartTimer(const sptr<ReminderRequest> & reminderRequest,TimerType type)1586 void ReminderDataManager::StartTimer(const sptr<ReminderRequest> &reminderRequest, TimerType type)
1587 {
1588     sptr<MiscServices::TimeServiceClient> timer = MiscServices::TimeServiceClient::GetInstance();
1589     if (timer == nullptr) {
1590         ANS_LOGE("Failed to start timer due to get TimeServiceClient is null.");
1591         return;
1592     }
1593     time_t now;
1594     (void)time(&now);  // unit is seconds.
1595     if (now < 0) {
1596         ANSR_LOGE("Get now time error");
1597         return;
1598     }
1599     uint64_t triggerTime = 0;
1600     switch (type) {
1601         case TimerType::TRIGGER_TIMER: {
1602             if (timerId_ != 0) {
1603                 ANSR_LOGE("Trigger timer has already started.");
1604                 break;
1605             }
1606             triggerTime = HandleTriggerTimeInner(reminderRequest, type, timer);
1607             break;
1608         }
1609         case TimerType::ALERTING_TIMER: {
1610             if (timerIdAlerting_ != 0) {
1611                 ANSR_LOGE("Alerting time out timer has already started.");
1612                 break;
1613             }
1614             triggerTime = HandleAlertingTimeInner(reminderRequest, type, timer, now);
1615             break;
1616         }
1617         default: {
1618             ANSR_LOGE("TimerType not support");
1619             break;
1620         }
1621     }
1622     if (triggerTime == 0) {
1623         ANSR_LOGW("Start timer fail");
1624     } else {
1625         ANSR_LOGD("Timing info: now:(%{public}" PRIu64 "), tar:(%{public}" PRIu64 ")",
1626             ReminderRequest::GetDurationSinceEpochInMilli(now), triggerTime);
1627     }
1628 }
1629 
HandleTriggerTimeInner(const sptr<ReminderRequest> & reminderRequest,TimerType type,const sptr<MiscServices::TimeServiceClient> & timer)1630 uint64_t ReminderDataManager::HandleTriggerTimeInner(const sptr<ReminderRequest> &reminderRequest, TimerType type,
1631     const sptr<MiscServices::TimeServiceClient> &timer)
1632 {
1633     uint64_t triggerTime = 0;
1634     SetActiveReminder(reminderRequest);
1635     timerId_ = timer->CreateTimer(REMINDER_DATA_MANAGER->CreateTimerInfo(type, reminderRequest));
1636     triggerTime = reminderRequest->GetTriggerTimeInMilli();
1637     timer->StartTimer(timerId_, triggerTime);
1638     ANSR_LOGD("Start timing (next triggerTime), timerId=%{public}" PRIu64 "", timerId_);
1639     return triggerTime;
1640 }
1641 
HandleAlertingTimeInner(const sptr<ReminderRequest> & reminderRequest,TimerType type,const sptr<MiscServices::TimeServiceClient> & timer,time_t now)1642 uint64_t ReminderDataManager::HandleAlertingTimeInner(const sptr<ReminderRequest> &reminderRequest, TimerType type,
1643     const sptr<MiscServices::TimeServiceClient> &timer, time_t now)
1644 {
1645     uint64_t triggerTime = 0;
1646     triggerTime = ReminderRequest::GetDurationSinceEpochInMilli(now)
1647         + static_cast<uint64_t>(reminderRequest->GetRingDuration() * ReminderRequest::MILLI_SECONDS);
1648     timerIdAlerting_ = timer->CreateTimer(REMINDER_DATA_MANAGER->CreateTimerInfo(type, reminderRequest));
1649     timer->StartTimer(timerIdAlerting_, triggerTime);
1650     ANSR_LOGD("Start timing (alerting time out), timerId=%{public}" PRIu64 "", timerIdAlerting_);
1651     return triggerTime;
1652 }
1653 
StopTimerLocked(TimerType type)1654 void ReminderDataManager::StopTimerLocked(TimerType type)
1655 {
1656     std::lock_guard<std::mutex> lock(ReminderDataManager::TIMER_MUTEX);
1657     StopTimer(type);
1658 }
1659 
StopTimer(TimerType type)1660 void ReminderDataManager::StopTimer(TimerType type)
1661 {
1662     sptr<MiscServices::TimeServiceClient> timer = MiscServices::TimeServiceClient::GetInstance();
1663     if (timer == nullptr) {
1664         ANSR_LOGE("Failed to stop timer due to get TimeServiceClient is null.");
1665         return;
1666     }
1667     uint64_t timerId = 0;
1668     switch (type) {
1669         case TimerType::TRIGGER_TIMER: {
1670             timerId = timerId_;
1671             ANSR_LOGD("Stop timing (next triggerTime)");
1672             break;
1673         }
1674         case TimerType::ALERTING_TIMER: {
1675             timerId = timerIdAlerting_;
1676             ANSR_LOGD("Stop timing (alerting time out)");
1677             break;
1678         }
1679         default: {
1680             ANSR_LOGE("TimerType not support");
1681             break;
1682         }
1683     }
1684     if (timerId == 0) {
1685         ANSR_LOGD("Timer is not running");
1686         return;
1687     }
1688     ANSR_LOGD("Stop timer id=%{public}" PRIu64 "", timerId);
1689     timer->StopTimer(timerId);
1690     ResetStates(type);
1691 }
1692 
ResetStates(TimerType type)1693 void ReminderDataManager::ResetStates(TimerType type)
1694 {
1695     switch (type) {
1696         case TimerType::TRIGGER_TIMER: {
1697             ANSR_LOGD("ResetStates(activeReminderId, timerId(next triggerTime))");
1698             timerId_ = 0;
1699             activeReminderId_ = -1;
1700             break;
1701         }
1702         case TimerType::ALERTING_TIMER: {
1703             ANSR_LOGD("ResetStates(alertingReminderId, timeId(alerting time out))");
1704             timerIdAlerting_ = 0;
1705             alertingReminderId_ = -1;
1706             break;
1707         }
1708         default: {
1709             ANSR_LOGE("TimerType not support");
1710             break;
1711         }
1712     }
1713 }
1714 
HandleCustomButtonClick(const OHOS::EventFwk::Want & want)1715 void ReminderDataManager::HandleCustomButtonClick(const OHOS::EventFwk::Want &want)
1716 {
1717     int32_t reminderId = static_cast<int32_t>(want.GetIntParam(ReminderRequest::PARAM_REMINDER_ID, -1));
1718     sptr<ReminderRequest> reminder = FindReminderRequestLocked(reminderId);
1719     if (reminder == nullptr) {
1720         ANSR_LOGE("Invalid reminder id: %{public}d", reminderId);
1721         return;
1722     }
1723     CloseReminder(reminder, false);
1724     UpdateAppDatabase(reminder, ReminderRequest::ActionButtonType::CUSTOM);
1725     std::string buttonPkgName = want.GetStringParam("PkgName");
1726     std::string buttonAbilityName = want.GetStringParam("AbilityName");
1727 
1728     AAFwk::Want abilityWant;
1729     abilityWant.SetElementName(buttonPkgName, buttonAbilityName);
1730     abilityWant.SetUri(reminder->GetCustomButtonUri());
1731     auto client = AppExecFwk::AbilityManagerClient::GetInstance();
1732     if (client == nullptr) {
1733         return;
1734     }
1735     int32_t result = client->StartAbility(abilityWant);
1736     if (result != 0) {
1737         ANSR_LOGE("Start ability failed, result = %{public}d", result);
1738         return;
1739     }
1740 }
1741 
GetBundleResMgr(const AppExecFwk::BundleInfo & bundleInfo)1742 std::shared_ptr<Global::Resource::ResourceManager> ReminderDataManager::GetBundleResMgr(
1743     const AppExecFwk::BundleInfo &bundleInfo)
1744 {
1745     std::shared_ptr<Global::Resource::ResourceManager> resourceManager(Global::Resource::CreateResourceManager());
1746     if (!resourceManager) {
1747         ANSR_LOGE("create resourceManager failed.");
1748         return nullptr;
1749     }
1750     // obtains the resource path.
1751     for (const auto &hapModuleInfo : bundleInfo.hapModuleInfos) {
1752         std::string moduleResPath = hapModuleInfo.hapPath.empty() ? hapModuleInfo.resourcePath : hapModuleInfo.hapPath;
1753         if (moduleResPath.empty()) {
1754             continue;
1755         }
1756         ANSR_LOGD("GetBundleResMgr, moduleResPath: %{private}s", moduleResPath.c_str());
1757         if (!resourceManager->AddResource(moduleResPath.c_str())) {
1758             ANSR_LOGW("GetBundleResMgr AddResource failed");
1759         }
1760     }
1761     // obtains the current system language.
1762     std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
1763     UErrorCode status = U_ZERO_ERROR;
1764     icu::Locale locale = icu::Locale::forLanguageTag(Global::I18n::LocaleConfig::GetSystemLanguage(), status);
1765     resConfig->SetLocaleInfo(locale);
1766     resourceManager->UpdateResConfig(*resConfig);
1767     return resourceManager;
1768 }
1769 
UpdateReminderLanguage(const sptr<ReminderRequest> & reminder)1770 void ReminderDataManager::UpdateReminderLanguage(const sptr<ReminderRequest> &reminder)
1771 {
1772     // obtains the bundle info by bundle name
1773     const std::string bundleName = reminder->GetBundleName();
1774     AppExecFwk::BundleInfo bundleInfo;
1775     if (!BundleManagerHelper::GetInstance()->GetBundleInfo(bundleName,
1776         AppExecFwk::BundleFlag::GET_BUNDLE_WITH_ABILITIES, reminder->GetUid(), bundleInfo)) {
1777         ANSR_LOGE("Get reminder request[%{public}d][%{public}s] bundle info failed.",
1778             reminder->GetReminderId(), bundleName.c_str());
1779         return;
1780     }
1781     // obtains the resource manager
1782     auto resourceMgr = GetBundleResMgr(bundleInfo);
1783     if (resourceMgr == nullptr) {
1784         ANSR_LOGE("Get reminder request[%{public}d][%{public}s] resource manager failed.",
1785             reminder->GetReminderId(), bundleName.c_str());
1786         return;
1787     }
1788     // update action button title
1789     reminder->OnLanguageChange(resourceMgr);
1790 }
1791 
UpdateReminderLanguageLocked(const sptr<ReminderRequest> & reminder)1792 void ReminderDataManager::UpdateReminderLanguageLocked(const sptr<ReminderRequest> &reminder)
1793 {
1794     std::lock_guard<std::mutex> lock(ReminderDataManager::MUTEX);
1795     UpdateReminderLanguage(reminder);
1796 }
1797 
OnConfigurationChanged(const AppExecFwk::Configuration & configuration)1798 void ReminderDataManager::OnConfigurationChanged(const AppExecFwk::Configuration &configuration)
1799 {
1800     ANSR_LOGI("System language config changed.");
1801     std::lock_guard<std::mutex> lock(ReminderDataManager::MUTEX);
1802     for (auto it = reminderVector_.begin(); it != reminderVector_.end(); ++it) {
1803         UpdateReminderLanguage(*it);
1804     }
1805 }
1806 
OnRemoveAppMgr()1807 void ReminderDataManager::OnRemoveAppMgr()
1808 {
1809     std::lock_guard<std::mutex> lock(appMgrMutex_);
1810     appMgrProxy_ = nullptr;
1811 }
1812 
ConnectAppMgr()1813 bool ReminderDataManager::ConnectAppMgr()
1814 {
1815     if (appMgrProxy_ != nullptr) {
1816         return true;
1817     }
1818 
1819     sptr<ISystemAbilityManager> systemAbilityManager =
1820         SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
1821     if (systemAbilityManager == nullptr) {
1822         ANSR_LOGE("get SystemAbilityManager failed");
1823         return false;
1824     }
1825 
1826     sptr<IRemoteObject> remoteObject = systemAbilityManager->GetSystemAbility(APP_MGR_SERVICE_ID);
1827     if (remoteObject == nullptr) {
1828         ANSR_LOGE("get app manager service failed");
1829         return false;
1830     }
1831 
1832     appMgrProxy_ = iface_cast<AppExecFwk::IAppMgr>(remoteObject);
1833     if (!appMgrProxy_ || !appMgrProxy_->AsObject()) {
1834         ANSR_LOGE("get app mgr proxy failed!");
1835         return false;
1836     }
1837     return true;
1838 }
1839 
CheckNeedNotifyStatus(const sptr<ReminderRequest> & reminder,const ReminderRequest::ActionButtonType buttonType)1840 void ReminderDataManager::CheckNeedNotifyStatus(const sptr<ReminderRequest> &reminder,
1841     const ReminderRequest::ActionButtonType buttonType)
1842 {
1843     const std::string bundleName = reminder->GetBundleName();
1844     if (bundleName.empty()) {
1845         return;
1846     }
1847     ANS_LOGI("notify bundleName is: %{public}s", bundleName.c_str());
1848     // get foreground application
1849     std::vector<AppExecFwk::AppStateData> apps;
1850     {
1851         std::lock_guard<std::mutex> lock(appMgrMutex_);
1852         if (!ConnectAppMgr()) {
1853             return;
1854         }
1855         if (appMgrProxy_->GetForegroundApplications(apps) != ERR_OK) {
1856             ANS_LOGW("get foreground application failed");
1857             return;
1858         }
1859     }
1860     // notify application
1861     for (auto &eachApp : apps) {
1862         if (eachApp.bundleName != bundleName) {
1863             continue;
1864         }
1865 
1866         EventFwk::Want want;
1867         // common event not add COMMON_EVENT_REMINDER_STATUS_CHANGE, Temporary use of string
1868         want.SetAction("usual.event.REMINDER_STATUS_CHANGE");
1869         EventFwk::CommonEventData eventData(want);
1870 
1871         std::string data;
1872         data.append(std::to_string(static_cast<int>(buttonType))).append(",");
1873         data.append(std::to_string(reminder->GetReminderId()));
1874         eventData.SetData(data);
1875 
1876         EventFwk::CommonEventPublishInfo info;
1877         info.SetBundleName(bundleName);
1878         if (EventFwk::CommonEventManager::PublishCommonEvent(eventData, info)) {
1879             ANSR_LOGI("notify reminder status change %{public}s", bundleName.c_str());
1880         }
1881         break;
1882     }
1883 }
1884 }
1885 }
1886