• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 #ifdef DEVICE_STANDBY_ENABLE
24 #include "standby_service_client.h"
25 #include "allow_type.h"
26 #endif
27 #include "ipc_skeleton.h"
28 #include "notification_slot.h"
29 #include "os_account_manager.h"
30 #include "reminder_event_manager.h"
31 #include "time_service_client.h"
32 #include "singleton.h"
33 
34 namespace OHOS {
35 namespace Notification {
36 namespace {
37 const std::string ALL_PACKAGES = "allPackages";
38 const int32_t MAIN_USER_ID = 100;
39 #ifdef DEVICE_STANDBY_ENABLE
40 const int REASON_APP_API = 1;
41 #endif
42 }
43 
44 /**
45  * Default reminder sound.
46  */
47 const static Uri DEFAULT_REMINDER_SOUND("file://system/etc/capture.ogg");
48 
49 const int16_t ReminderDataManager::MAX_NUM_REMINDER_LIMIT_SYSTEM = 12000;
50 const int16_t ReminderDataManager::MAX_NUM_REMINDER_LIMIT_SYS_APP = 10000;
51 const int16_t ReminderDataManager::MAX_NUM_REMINDER_LIMIT_APP = 30;
52 const uint8_t ReminderDataManager::TIME_ZONE_CHANGE = 0;
53 const uint8_t ReminderDataManager::DATE_TIME_CHANGE = 1;
54 std::shared_ptr<ReminderDataManager> ReminderDataManager::REMINDER_DATA_MANAGER = nullptr;
55 std::mutex ReminderDataManager::MUTEX;
56 std::mutex ReminderDataManager::SHOW_MUTEX;
57 std::mutex ReminderDataManager::ALERT_MUTEX;
58 std::mutex ReminderDataManager::TIMER_MUTEX;
59 
PublishReminder(const sptr<ReminderRequest> & reminder,const sptr<NotificationBundleOption> & bundleOption)60 ErrCode ReminderDataManager::PublishReminder(const sptr<ReminderRequest> &reminder,
61     const sptr<NotificationBundleOption> &bundleOption)
62 {
63     if (CheckReminderLimitExceededLocked(bundleOption, reminder)) {
64         return ERR_REMINDER_NUMBER_OVERLOAD;
65     }
66     UpdateAndSaveReminderLocked(reminder, bundleOption);
67     StartRecentReminder();
68     return ERR_OK;
69 }
70 
CancelReminder(const int32_t & reminderId,const sptr<NotificationBundleOption> & bundleOption)71 ErrCode ReminderDataManager::CancelReminder(
72     const int32_t &reminderId, const sptr<NotificationBundleOption> &bundleOption)
73 {
74     sptr<ReminderRequest> reminder = FindReminderRequestLocked(reminderId, bundleOption->GetBundleName());
75     if (reminder == nullptr) {
76         ANSR_LOGW("Cancel reminder, not find the reminder");
77         return ERR_REMINDER_NOT_EXIST;
78     }
79     if (activeReminderId_ == reminderId) {
80         ANSR_LOGD("Cancel active reminder, id=%{public}d", reminderId);
81         activeReminder_->OnStop();
82         StopTimerLocked(TimerType::TRIGGER_TIMER);
83     }
84     if (alertingReminderId_ == reminderId) {
85         StopSoundAndVibrationLocked(reminder);
86         StopTimerLocked(TimerType::ALERTING_TIMER);
87     }
88     int32_t id = reminderId;
89     CancelNotification(reminder);
90     RemoveReminderLocked(id);
91     StartRecentReminder();
92     return ERR_OK;
93 }
94 
CancelAllReminders(const std::string & packageName,const int32_t & userId)95 ErrCode ReminderDataManager::CancelAllReminders(const std::string &packageName, const int32_t &userId)
96 {
97     ANSR_LOGD("CancelAllReminders, userId=%{public}d, pkgName=%{public}s",
98         userId, packageName.c_str());
99     CancelRemindersImplLocked(packageName, userId);
100     return ERR_OK;
101 }
102 
GetValidReminders(const sptr<NotificationBundleOption> & bundleOption,std::vector<sptr<ReminderRequest>> & reminders)103 void ReminderDataManager::GetValidReminders(
104     const sptr<NotificationBundleOption> &bundleOption, std::vector<sptr<ReminderRequest>> &reminders)
105 {
106     std::lock_guard<std::mutex> lock(ReminderDataManager::MUTEX);
107     for (auto it = reminderVector_.begin(); it != reminderVector_.end(); ++it) {
108         if ((*it)->IsExpired()) {
109             continue;
110         }
111         int32_t reminderId = (*it)->GetReminderId();
112         auto mit = notificationBundleOptionMap_.find(reminderId);
113         if (mit == notificationBundleOptionMap_.end()) {
114             ANSR_LOGE("Get bundle option occur error, reminderId=%{public}d", reminderId);
115         } else {
116             if (IsBelongToSameApp(mit->second, bundleOption)) {
117                 reminders.push_back(*it);
118             }
119         }
120     }
121 }
122 
CancelAllReminders(const int32_t & userId)123 void ReminderDataManager::CancelAllReminders(const int32_t &userId)
124 {
125     ANSR_LOGD("CancelAllReminders, userId=%{public}d", userId);
126     CancelRemindersImplLocked(ALL_PACKAGES, userId);
127 }
128 
CancelRemindersImplLocked(const std::string & packageName,const int32_t & userId)129 void ReminderDataManager::CancelRemindersImplLocked(const std::string &packageName, const int32_t &userId)
130 {
131     MUTEX.lock();
132     if (activeReminderId_ != -1 && IsMatched(activeReminder_, packageName, userId)) {
133         activeReminder_->OnStop();
134         StopTimer(TimerType::TRIGGER_TIMER);
135         ANSR_LOGD("Stop active reminder, reminderId=%{public}d", activeReminderId_);
136     }
137     for (auto vit = reminderVector_.begin(); vit != reminderVector_.end();) {
138         int32_t reminderId = (*vit)->GetReminderId();
139         auto mit = notificationBundleOptionMap_.find(reminderId);
140         if (mit == notificationBundleOptionMap_.end()) {
141             ANSR_LOGE("Get bundle option occur error, reminderId=%{public}d", reminderId);
142             ++vit;
143             continue;
144         }
145         if (IsMatched(*vit, packageName, userId)) {
146             if ((*vit)->IsAlerting()) {
147                 StopAlertingReminder(*vit);
148             }
149             CancelNotification(*vit);
150             RemoveFromShowedReminders(*vit);
151             ANSR_LOGD("Containers(vector/map) remove. reminderId=%{public}d", reminderId);
152             vit = reminderVector_.erase(vit);
153             notificationBundleOptionMap_.erase(mit);
154             totalCount_--;
155             continue;
156         }
157         ++vit;
158     }
159     if (packageName == ALL_PACKAGES) {
160         store_->DeleteUser(userId);
161     } else {
162         store_->Delete(packageName, userId);
163     }
164     MUTEX.unlock();
165     StartRecentReminder();
166 }
167 
IsMatched(const sptr<ReminderRequest> & reminder,const std::string & packageName,const int32_t & userId) const168 bool ReminderDataManager::IsMatched(const sptr<ReminderRequest> &reminder,
169     const std::string &packageName, const int32_t &userId) const
170 {
171     auto mit = notificationBundleOptionMap_.find(reminder->GetReminderId());
172     if (mit == notificationBundleOptionMap_.end()) {
173         ANS_LOGE("Failed to get bundle information. reminderId=%{public}d", reminder->GetReminderId());
174         return true;
175     }
176     if (ReminderRequest::GetUserId(mit->second->GetUid()) != userId) {
177         return false;
178     }
179     if (packageName == ALL_PACKAGES) {
180         return true;
181     }
182     if (mit->second->GetBundleName() == packageName) {
183         return true;
184     }
185     return false;
186 }
187 
CancelNotification(const sptr<ReminderRequest> & reminder) const188 void ReminderDataManager::CancelNotification(const sptr<ReminderRequest> &reminder) const
189 {
190     if (!(reminder->IsShowing())) {
191         ANSR_LOGD("No need to cancel notification");
192         return;
193     }
194     sptr<NotificationRequest> notification = reminder->GetNotificationRequest();
195     if (notification == nullptr) {
196         ANSR_LOGW("Cancel notification fail");
197         return;
198     }
199     ANSR_LOGD("Cancel notification");
200     if (advancedNotificationService_ == nullptr) {
201         ANSR_LOGE("Cancel notification fail");
202         return;
203     }
204     sptr<NotificationBundleOption> bundleOption = FindNotificationBundleOption(reminder->GetReminderId());
205     advancedNotificationService_->CancelPreparedNotification(
206         notification->GetNotificationId(), ReminderRequest::NOTIFICATION_LABEL, bundleOption);
207 }
208 
CheckReminderLimitExceededLocked(const sptr<NotificationBundleOption> & bundleOption,const sptr<ReminderRequest> & reminder) const209 bool ReminderDataManager::CheckReminderLimitExceededLocked(const sptr<NotificationBundleOption> &bundleOption,
210     const sptr<ReminderRequest> &reminder) const
211 {
212     std::lock_guard<std::mutex> lock(ReminderDataManager::MUTEX);
213     if (totalCount_ >= ReminderDataManager::MAX_NUM_REMINDER_LIMIT_SYSTEM) {
214         ANSR_LOGW("The number of validate reminders exceeds the system upper limit:%{public}d, \
215             and new reminder can not be published", MAX_NUM_REMINDER_LIMIT_SYSTEM);
216         return true;
217     }
218     int32_t count = 0;
219     for (auto it = reminderVector_.begin(); it != reminderVector_.end(); ++it) {
220         if ((*it)->IsExpired()) {
221             continue;
222         }
223         auto mit = notificationBundleOptionMap_.find((*it)->GetReminderId());
224         if (mit == notificationBundleOptionMap_.end()) {
225             ANSR_LOGE("Error occur when get bundle option, reminderId=%{public}d", (*it)->GetReminderId());
226         } else {
227             if (IsBelongToSameApp(mit->second, bundleOption)) {
228                 count++;
229             }
230         }
231     }
232     auto maxReminderNum = reminder->IsSystemApp() ? MAX_NUM_REMINDER_LIMIT_SYS_APP : MAX_NUM_REMINDER_LIMIT_APP;
233     if (count >= maxReminderNum) {
234         ANSR_LOGW("The number of validate reminders exceeds the application upper limit:%{public}d, and new \
235             reminder can not be published", maxReminderNum);
236         return true;
237     }
238     return false;
239 }
240 
AddToShowedReminders(const sptr<ReminderRequest> & reminder)241 void ReminderDataManager::AddToShowedReminders(const sptr<ReminderRequest> &reminder)
242 {
243     std::lock_guard<std::mutex> lock(ReminderDataManager::SHOW_MUTEX);
244     for (auto it = showedReminderVector_.begin(); it != showedReminderVector_.end(); ++it) {
245         if (reminder->GetReminderId() == (*it)->GetReminderId()) {
246             ANSR_LOGD("Showed reminder is already exist");
247             return;
248         }
249     }
250     ANSR_LOGD("Containers(shownVector) add. reminderId=%{public}d", reminder->GetReminderId());
251     showedReminderVector_.push_back(reminder);
252 }
253 
OnUserRemove(const int32_t & userId)254 void ReminderDataManager::OnUserRemove(const int32_t& userId)
255 {
256     ANSR_LOGD("Remove user id: %{public}d", userId);
257     if (!IsReminderAgentReady()) {
258         ANSR_LOGW("Give up to remove user id: %{public}d for reminderAgent is not ready", userId);
259         return;
260     }
261     CancelAllReminders(userId);
262 }
263 
OnServiceStart()264 void ReminderDataManager::OnServiceStart()
265 {
266     std::vector<sptr<ReminderRequest>> immediatelyShowReminders;
267     GetImmediatelyShowRemindersLocked(immediatelyShowReminders);
268     ANSR_LOGD("immediatelyShowReminders size=%{public}zu", immediatelyShowReminders.size());
269     HandleImmediatelyShow(immediatelyShowReminders, false);
270     StartRecentReminder();
271 }
272 
OnUserSwitch(const int32_t & userId)273 void ReminderDataManager::OnUserSwitch(const int32_t& userId)
274 {
275     ANSR_LOGD("Switch user id from %{public}d to %{public}d", currentUserId_, userId);
276     currentUserId_ = userId;
277     std::lock_guard<std::mutex> lock(ReminderDataManager::MUTEX);
278     if ((alertingReminderId_ != -1) && IsReminderAgentReady()) {
279         TerminateAlerting(alertingReminder_, "OnUserSwitch");
280     }
281 }
282 
OnProcessDiedLocked(const sptr<NotificationBundleOption> & bundleOption)283 void ReminderDataManager::OnProcessDiedLocked(const sptr<NotificationBundleOption> &bundleOption)
284 {
285     std::string bundleName = bundleOption->GetBundleName();
286     int32_t uid = bundleOption->GetUid();
287     ANSR_LOGI("OnProcessDiedLocked, bundleName=%{public}s, uid=%{public}d", bundleName.c_str(), uid);
288     std::lock_guard<std::mutex> lock(ReminderDataManager::SHOW_MUTEX);
289     for (auto it = showedReminderVector_.begin(); it != showedReminderVector_.end(); ++it) {
290         int32_t reminderId = (*it)->GetReminderId();
291         auto mit = notificationBundleOptionMap_.find(reminderId);
292         if (mit == notificationBundleOptionMap_.end()) {
293             ANSR_LOGD(
294                 "Not get bundle option, the reminder may has been cancelled, reminderId=%{public}d", reminderId);
295             CancelNotification(*it);
296             showedReminderVector_.erase(it);
297             --it;
298             continue;
299         }
300         if (mit->second->GetBundleName() != bundleName || mit->second->GetUid() != uid) {
301             continue;
302         }
303         if ((*it)->IsAlerting()) {
304             TerminateAlerting((*it), "onProcessDied");
305         } else {
306             CancelNotification(*it);
307             (*it)->OnClose(false);
308             ANSR_LOGD("Containers(shownVector) remove. reminderId=%{public}d", reminderId);
309             showedReminderVector_.erase(it);
310             --it;
311         }
312         store_->UpdateOrInsert((*it), bundleOption);
313     }
314 }
315 
InitTimerInfo(std::shared_ptr<ReminderTimerInfo> & sharedTimerInfo,const sptr<ReminderRequest> & reminderRequest,TimerType reminderType) const316 void ReminderDataManager::InitTimerInfo(std::shared_ptr<ReminderTimerInfo> &sharedTimerInfo,
317     const sptr<ReminderRequest> &reminderRequest, TimerType reminderType) const
318 {
319     uint8_t timerTypeWakeup = static_cast<uint8_t>(sharedTimerInfo->TIMER_TYPE_WAKEUP);
320     uint8_t timerTypeExact = static_cast<uint8_t>(sharedTimerInfo->TIMER_TYPE_EXACT);
321     sharedTimerInfo->SetRepeat(false);
322     sharedTimerInfo->SetInterval(0);
323 
324     auto mit = notificationBundleOptionMap_.find(reminderRequest->GetReminderId());
325     if (mit == notificationBundleOptionMap_.end()) {
326         ANS_LOGE("Failed to get bundle information. reminderId=%{public}d",
327             reminderRequest->GetReminderId());
328         return;
329     }
330     sharedTimerInfo->SetBundleName(mit->second->GetBundleName());
331     sharedTimerInfo->SetUid(mit->second->GetUid());
332 
333     // The systemtimer type will be set TIMER_TYPE_INEXACT_REMINDER&&EXACT if reminder type is CALENDAR or TIMER,
334     // and set WAKEUP&&EXACT if ALARM.
335     int32_t timerType;
336     if (reminderType == TimerType::TRIGGER_TIMER &&
337         (reminderRequest->GetReminderType() == ReminderRequest::ReminderType::CALENDAR ||
338         reminderRequest->GetReminderType() == ReminderRequest::ReminderType::TIMER)) {
339 #ifdef DEVICE_STANDBY_ENABLE
340         // Get allow list.
341         std::string name = mit->second->GetBundleName();
342         std::vector<DevStandbyMgr::AllowInfo> allowInfoList;
343         DevStandbyMgr::StandbyServiceClient::GetInstance().GetAllowList(DevStandbyMgr::AllowType::TIMER,
344             allowInfoList, REASON_APP_API);
345         auto it = std::find_if(allowInfoList.begin(),
346             allowInfoList.end(),
347             [&name](const DevStandbyMgr::AllowInfo &allowInfo) {
348                 return allowInfo.GetName() == name;
349             });
350         if (reminderRequest->IsSystemApp() || it != allowInfoList.end()) {
351             timerType = static_cast<int32_t>(timerTypeWakeup | timerTypeExact);
352         } else {
353             uint8_t timerTypeAns = static_cast<uint8_t>(sharedTimerInfo->TIMER_TYPE_INEXACT_REMINDER);
354             timerType = static_cast<int32_t>(timerTypeAns | timerTypeExact);
355         }
356 #else
357         timerType = static_cast<int32_t>(timerTypeWakeup | timerTypeExact);
358 #endif
359     } else {
360         timerType = static_cast<int32_t>(timerTypeWakeup | timerTypeExact);
361     }
362     sharedTimerInfo->SetType(timerType);
363 }
364 
CreateTimerInfo(TimerType type,const sptr<ReminderRequest> & reminderRequest) const365 std::shared_ptr<ReminderTimerInfo> ReminderDataManager::CreateTimerInfo(TimerType type,
366     const sptr<ReminderRequest> &reminderRequest) const
367 {
368     auto sharedTimerInfo = std::make_shared<ReminderTimerInfo>();
369     if ((sharedTimerInfo->TIMER_TYPE_WAKEUP > UINT8_MAX) || (sharedTimerInfo->TIMER_TYPE_EXACT > UINT8_MAX)) {
370         ANSR_LOGE("Failed to set timer type.");
371         return nullptr;
372     }
373     InitTimerInfo(sharedTimerInfo, reminderRequest, type);
374 
375     int32_t requestCode = 10;
376     std::vector<AbilityRuntime::WantAgent::WantAgentConstant::Flags> flags;
377     flags.push_back(AbilityRuntime::WantAgent::WantAgentConstant::Flags::UPDATE_PRESENT_FLAG);
378 
379     auto want = std::make_shared<OHOS::AAFwk::Want>();
380     switch (type) {
381         case (TimerType::TRIGGER_TIMER): {
382             want->SetAction(ReminderRequest::REMINDER_EVENT_ALARM_ALERT);
383             sharedTimerInfo->SetAction(ReminderRequest::REMINDER_EVENT_ALARM_ALERT);
384             want->SetParam(ReminderRequest::PARAM_REMINDER_ID, activeReminderId_);
385             break;
386         }
387         case (TimerType::ALERTING_TIMER): {
388             if (alertingReminderId_ == -1) {
389                 ANSR_LOGE("Create alerting time out timer Illegal.");
390                 return sharedTimerInfo;
391             }
392             want->SetAction(ReminderRequest::REMINDER_EVENT_ALERT_TIMEOUT);
393             sharedTimerInfo->SetAction(ReminderRequest::REMINDER_EVENT_ALERT_TIMEOUT);
394             want->SetParam(ReminderRequest::PARAM_REMINDER_ID, alertingReminderId_);
395             break;
396         }
397         default:
398             ANSR_LOGE("TimerType not support");
399             break;
400     }
401     std::vector<std::shared_ptr<AAFwk::Want>> wants;
402     wants.push_back(want);
403     AbilityRuntime::WantAgent::WantAgentInfo wantAgentInfo(
404         requestCode,
405         AbilityRuntime::WantAgent::WantAgentConstant::OperationType::SEND_COMMON_EVENT,
406         flags,
407         wants,
408         nullptr
409     );
410 
411     std::string identity = IPCSkeleton::ResetCallingIdentity();
412     std::shared_ptr<AbilityRuntime::WantAgent::WantAgent> wantAgent =
413         AbilityRuntime::WantAgent::WantAgentHelper::GetWantAgent(wantAgentInfo, 0);
414     IPCSkeleton::SetCallingIdentity(identity);
415 
416     sharedTimerInfo->SetWantAgent(wantAgent);
417     return sharedTimerInfo;
418 }
419 
FindReminderRequestLocked(const int32_t & reminderId)420 sptr<ReminderRequest> ReminderDataManager::FindReminderRequestLocked(const int32_t &reminderId)
421 {
422     std::lock_guard<std::mutex> lock(ReminderDataManager::MUTEX);
423     for (auto it = reminderVector_.begin(); it != reminderVector_.end(); ++it) {
424         if (reminderId == (*it)->GetReminderId()) {
425             return *it;
426         }
427     }
428     ANSR_LOGD("Not find the reminder");
429     return nullptr;
430 }
431 
FindReminderRequestLocked(const int32_t & reminderId,const std::string & pkgName)432 sptr<ReminderRequest> ReminderDataManager::FindReminderRequestLocked(
433     const int32_t &reminderId, const std::string &pkgName)
434 {
435     sptr<ReminderRequest> reminder = FindReminderRequestLocked(reminderId);
436     std::lock_guard<std::mutex> lock(ReminderDataManager::MUTEX);
437     if (reminder == nullptr) {
438         return nullptr;
439     }
440     sptr<NotificationRequest> notificationRequest = reminder->GetNotificationRequest();
441     if (notificationRequest == nullptr) {
442         ANSR_LOGW("Not find the reminder due to notification request is null");
443         return nullptr;
444     }
445     if (notificationRequest->GetCreatorBundleName() != pkgName) {
446         ANSR_LOGW("Not find the reminder due to package name not match");
447         return nullptr;
448     }
449     return reminder;
450 }
451 
FindNotificationBundleOption(const int32_t & reminderId) const452 sptr<NotificationBundleOption> ReminderDataManager::FindNotificationBundleOption(const int32_t &reminderId) const
453 {
454     auto it = notificationBundleOptionMap_.find(reminderId);
455     if (it == notificationBundleOptionMap_.end()) {
456         ANSR_LOGW("Failed to get bundle option.");
457         return nullptr;
458     } else {
459         return it->second;
460     }
461 }
462 
cmp(sptr<ReminderRequest> & reminderRequest,sptr<ReminderRequest> & other)463 bool ReminderDataManager::cmp(sptr<ReminderRequest> &reminderRequest, sptr<ReminderRequest> &other)
464 {
465     return reminderRequest->GetTriggerTimeInMilli() < other->GetTriggerTimeInMilli();
466 }
467 
CloseReminder(const OHOS::EventFwk::Want & want,bool cancelNotification)468 void ReminderDataManager::CloseReminder(const OHOS::EventFwk::Want &want, bool cancelNotification)
469 {
470     int32_t reminderId = static_cast<int32_t>(want.GetIntParam(ReminderRequest::PARAM_REMINDER_ID, -1));
471     sptr<ReminderRequest> reminder = FindReminderRequestLocked(reminderId);
472     if (reminder == nullptr) {
473         ANSR_LOGW("Invalid reminder id: %{public}d", reminderId);
474         return;
475     }
476     CloseReminder(reminder, cancelNotification);
477     StartRecentReminder();
478 }
479 
CloseReminder(const sptr<ReminderRequest> & reminder,bool cancelNotification)480 void ReminderDataManager::CloseReminder(const sptr<ReminderRequest> &reminder, bool cancelNotification)
481 {
482     int32_t reminderId = reminder->GetReminderId();
483     if (activeReminderId_ == reminderId) {
484         ANSR_LOGD("Stop active reminder due to CloseReminder");
485         activeReminder_->OnStop();
486         StopTimerLocked(TimerType::TRIGGER_TIMER);
487     }
488     if (alertingReminderId_ == reminderId) {
489         StopSoundAndVibrationLocked(reminder);
490         StopTimerLocked(TimerType::ALERTING_TIMER);
491     }
492     reminder->OnClose(true);
493     RemoveFromShowedReminders(reminder);
494     store_->UpdateOrInsert(reminder, FindNotificationBundleOption(reminder->GetReminderId()));
495     if (cancelNotification) {
496         CancelNotification(reminder);
497     }
498 }
499 
GetInstance()500 std::shared_ptr<ReminderDataManager> ReminderDataManager::GetInstance()
501 {
502     return REMINDER_DATA_MANAGER;
503 }
504 
InitInstance(const sptr<AdvancedNotificationService> & advancedNotificationService)505 std::shared_ptr<ReminderDataManager> ReminderDataManager::InitInstance(
506     const sptr<AdvancedNotificationService> &advancedNotificationService)
507 {
508     if (REMINDER_DATA_MANAGER == nullptr) {
509         REMINDER_DATA_MANAGER = std::make_shared<ReminderDataManager>();
510         REMINDER_DATA_MANAGER->advancedNotificationService_ = advancedNotificationService;
511         ReminderEventManager reminderEventManager(REMINDER_DATA_MANAGER);
512     }
513     return REMINDER_DATA_MANAGER;
514 }
515 
RefreshRemindersDueToSysTimeChange(uint8_t type)516 void ReminderDataManager::RefreshRemindersDueToSysTimeChange(uint8_t type)
517 {
518     std::string typeInfo = type == TIME_ZONE_CHANGE ? "timeZone" : "dateTime";
519     ANSR_LOGI("Refresh all reminders due to %{public}s changed by user", typeInfo.c_str());
520     if (activeReminderId_ != -1) {
521         ANSR_LOGD("Stop active reminder due to date/time or timeZone change");
522         activeReminder_->OnStop();
523         StopTimerLocked(TimerType::TRIGGER_TIMER);
524     }
525     std::vector<sptr<ReminderRequest>> showImmediately = RefreshRemindersLocked(type);
526     if (!showImmediately.empty()) {
527         ANSR_LOGD("Refresh all reminders, show expired reminders immediately");
528         HandleImmediatelyShow(showImmediately, true);
529     }
530     StartRecentReminder();
531 }
532 
TerminateAlerting(const OHOS::EventFwk::Want & want)533 void ReminderDataManager::TerminateAlerting(const OHOS::EventFwk::Want &want)
534 {
535     int32_t reminderId = static_cast<int32_t>(want.GetIntParam(ReminderRequest::PARAM_REMINDER_ID, -1));
536     sptr<ReminderRequest> reminder = FindReminderRequestLocked(reminderId);
537     if (reminder == nullptr) {
538         ANSR_LOGE("Invalid reminder id: %{public}d", reminderId);
539         return;
540     }
541     TerminateAlerting(reminder, "timeOut");
542 }
543 
TerminateAlerting(const uint16_t waitInSecond,const sptr<ReminderRequest> & reminder)544 void ReminderDataManager::TerminateAlerting(const uint16_t waitInSecond, const sptr<ReminderRequest> &reminder)
545 {
546     sleep(waitInSecond);
547     TerminateAlerting(reminder, "waitInMillis");
548 }
549 
TerminateAlerting(const sptr<ReminderRequest> & reminder,const std::string & reason)550 void ReminderDataManager::TerminateAlerting(const sptr<ReminderRequest> &reminder, const std::string &reason)
551 {
552     if (reminder == nullptr) {
553         ANSR_LOGE("TerminateAlerting illegal.");
554         return;
555     }
556     ANSR_LOGI("Terminate the alerting reminder, %{public}s, called by %{public}s",
557         reminder->Dump().c_str(), reason.c_str());
558     StopAlertingReminder(reminder);
559 
560     if (!reminder->OnTerminate()) {
561         return;
562     }
563     int32_t reminderId = reminder->GetReminderId();
564     sptr<NotificationBundleOption> bundleOption = FindNotificationBundleOption(reminderId);
565     sptr<NotificationRequest> notificationRequest = reminder->GetNotificationRequest();
566     if (bundleOption == nullptr) {
567         ANSR_LOGE("Get bundle option fail, reminderId=%{public}d", reminderId);
568         return;
569     }
570     ANSR_LOGD("publish(update) notification.(reminderId=%{public}d)", reminder->GetReminderId());
571     UpdateNotification(reminder);
572     if (advancedNotificationService_ == nullptr) {
573         ANSR_LOGE("Ans instance is null.");
574         return;
575     }
576     advancedNotificationService_->PublishPreparedNotification(notificationRequest, bundleOption);
577     store_->UpdateOrInsert(reminder, FindNotificationBundleOption(reminder->GetReminderId()));
578 }
579 
UpdateAndSaveReminderLocked(const sptr<ReminderRequest> & reminder,const sptr<NotificationBundleOption> & bundleOption)580 void ReminderDataManager::UpdateAndSaveReminderLocked(
581     const sptr<ReminderRequest> &reminder, const sptr<NotificationBundleOption> &bundleOption)
582 {
583     std::lock_guard<std::mutex> lock(ReminderDataManager::MUTEX);
584     reminder->InitReminderId();
585     reminder->InitUserId(ReminderRequest::GetUserId(bundleOption->GetUid()));
586     reminder->InitUid(bundleOption->GetUid());
587     int32_t reminderId = reminder->GetReminderId();
588     ANSR_LOGD("Containers(map) add. reminderId=%{public}d", reminderId);
589     auto ret = notificationBundleOptionMap_.insert(
590         std::pair<int32_t, sptr<NotificationBundleOption>>(reminderId, bundleOption));
591     if (!ret.second) {
592         ANSR_LOGE("Containers add to map error");
593         return;
594     }
595     ANSR_LOGD("Containers(vector) add. reminderId=%{public}d", reminderId);
596     reminderVector_.push_back(reminder);
597     totalCount_++;
598     store_->UpdateOrInsert(reminder, bundleOption);
599 }
600 
SetService(AdvancedNotificationService * advancedNotificationService)601 void ReminderDataManager::SetService(AdvancedNotificationService *advancedNotificationService)
602 {
603     advancedNotificationService_ = advancedNotificationService;
604 }
605 
ShouldAlert(const sptr<ReminderRequest> & reminder) const606 bool ReminderDataManager::ShouldAlert(const sptr<ReminderRequest> &reminder) const
607 {
608     if (reminder == nullptr) {
609         return false;
610     }
611     int32_t reminderId = reminder->GetReminderId();
612     sptr<NotificationBundleOption> bundleOption = FindNotificationBundleOption(reminderId);
613     if (bundleOption == nullptr) {
614         ANSR_LOGD("The reminder (reminderId=%{public}d) is silent", reminderId);
615         return false;
616     }
617     int32_t userId = ReminderRequest::GetUserId(bundleOption->GetUid());
618     if (currentUserId_ != userId) {
619         ANSR_LOGD("The reminder (reminderId=%{public}d) is silent for not in active user, " \
620             "current user id: %{public}d, reminder user id: %{public}d", reminderId, currentUserId_, userId);
621         return false;
622     }
623 
624     sptr<NotificationDoNotDisturbDate> date;
625     ErrCode errCode = advancedNotificationService_->GetDoNotDisturbDate(date);
626     if (errCode != ERR_OK) {
627         ANSR_LOGE("The reminder (reminderId=%{public}d) is silent for get disturbDate error", reminderId);
628         return false;
629     }
630     if (date->GetDoNotDisturbType() == NotificationConstant::DoNotDisturbType::NONE) {
631         return true;
632     }
633     std::vector<sptr<NotificationSlot>> slots;
634     errCode = advancedNotificationService_->GetSlotsByBundle(bundleOption, slots);
635     if (errCode != ERR_OK) {
636         ANSR_LOGE("The reminder (reminderId=%{public}d) is silent for get slots error", reminderId);
637         return false;
638     }
639     for (auto slot : slots) {
640         if (slot->GetType() != reminder->GetSlotType()) {
641             continue;
642         }
643         if (slot->IsEnableBypassDnd()) {
644             ANSR_LOGD("Not silent for enable by pass Dnd, reminderId=%{public}d", reminderId);
645             return true;
646         }
647     }
648     ANSR_LOGD("The reminder (reminderId=%{public}d) is silent for Dnd", reminderId);
649     return false;
650 }
651 
ShowActiveReminder(const EventFwk::Want & want)652 void ReminderDataManager::ShowActiveReminder(const EventFwk::Want &want)
653 {
654     int32_t reminderId = static_cast<int32_t>(want.GetIntParam(ReminderRequest::PARAM_REMINDER_ID, -1));
655     ANSR_LOGI("Begin to show reminder(reminderId=%{public}d)", reminderId);
656     if (reminderId == activeReminderId_) {
657         ResetStates(TimerType::TRIGGER_TIMER);
658     }
659     sptr<ReminderRequest> reminder = FindReminderRequestLocked(reminderId);
660     if (reminder == nullptr) {
661         ANSR_LOGW("Invalid reminder id: %{public}d", reminderId);
662         return;
663     }
664     if (HandleSysTimeChange(reminder)) {
665         return;
666     }
667     ShowActiveReminderExtendLocked(reminder);
668     StartRecentReminder();
669 }
670 
HandleSysTimeChange(const sptr<ReminderRequest> reminder) const671 bool ReminderDataManager::HandleSysTimeChange(const sptr<ReminderRequest> reminder) const
672 {
673     if (reminder->CanShow()) {
674         return false;
675     } else {
676         ANSR_LOGI("handleSystimeChange, no need to show reminder again.");
677         return true;
678     }
679 }
680 
SetActiveReminder(const sptr<ReminderRequest> & reminder)681 void ReminderDataManager::SetActiveReminder(const sptr<ReminderRequest> &reminder)
682 {
683     if (reminder == nullptr) {
684         // activeReminder_ should not be set with null as it point to actual object.
685         activeReminderId_ = -1;
686     } else {
687         activeReminderId_ = reminder->GetReminderId();
688         activeReminder_ = reminder;
689         ANSR_LOGD("Set activeReminder with id=%{public}d", activeReminderId_);
690     }
691     ANSR_LOGD("Set activeReminderId=%{public}d", activeReminderId_);
692 }
693 
SetAlertingReminder(const sptr<ReminderRequest> & reminder)694 void ReminderDataManager::SetAlertingReminder(const sptr<ReminderRequest> &reminder)
695 {
696     if (reminder == nullptr) {
697         // alertingReminder_ should not be set with null as it point to actual object.
698         alertingReminderId_ = -1;
699     } else {
700         alertingReminderId_ = reminder->GetReminderId();
701         alertingReminder_ = reminder;
702         ANSR_LOGD("Set alertingReminder with id=%{public}d", alertingReminderId_);
703     }
704     ANSR_LOGD("Set alertingReminderId=%{public}d", alertingReminderId_);
705 }
706 
ShowActiveReminderExtendLocked(sptr<ReminderRequest> & reminder)707 void ReminderDataManager::ShowActiveReminderExtendLocked(sptr<ReminderRequest> &reminder)
708 {
709     std::lock_guard<std::mutex> lock(ReminderDataManager::MUTEX);
710     uint64_t triggerTime = reminder->GetTriggerTimeInMilli();
711     bool isAlerting = false;
712     sptr<ReminderRequest> playSoundReminder = nullptr;
713     for (auto it = reminderVector_.begin(); it != reminderVector_.end(); ++it) {
714         if ((*it)->IsExpired()) {
715             continue;
716         }
717         if ((*it)->GetTriggerTimeInMilli() - triggerTime > ReminderRequest::SAME_TIME_DISTINGUISH_MILLISECONDS) {
718             continue;
719         }
720         if (!isAlerting) {
721             playSoundReminder = (*it);
722             isAlerting = true;
723         } else {
724             ShowReminder((*it), false, false, false, false);
725         }
726     }
727     if (playSoundReminder != nullptr) {
728         ShowReminder(playSoundReminder, true, false, false, true);
729     }
730 }
731 
ShowReminder(const sptr<ReminderRequest> & reminder,const bool & isNeedToPlaySound,const bool & isNeedToStartNext,const bool & isSysTimeChanged,const bool & needScheduleTimeout)732 void ReminderDataManager::ShowReminder(const sptr<ReminderRequest> &reminder, const bool &isNeedToPlaySound,
733     const bool &isNeedToStartNext, const bool &isSysTimeChanged, const bool &needScheduleTimeout)
734 {
735     ANSR_LOGD("Show the reminder(Play sound: %{public}d), %{public}s",
736         static_cast<int32_t>(isNeedToPlaySound), reminder->Dump().c_str());
737     int32_t reminderId = reminder->GetReminderId();
738     sptr<NotificationBundleOption> bundleOption = FindNotificationBundleOption(reminderId);
739     sptr<NotificationRequest> notificationRequest = reminder->GetNotificationRequest();
740     if (bundleOption == nullptr) {
741         ANSR_LOGE("Get bundle option fail, reminderId=%{public}d", reminderId);
742         return;
743     }
744     if (advancedNotificationService_ == nullptr) {
745         ANSR_LOGE("ShowReminder fail");
746         reminder->OnShow(false, isSysTimeChanged, false);
747         store_->UpdateOrInsert(reminder, FindNotificationBundleOption(reminder->GetReminderId()));
748         return;
749     }
750     if (!IsAllowedNotify(reminder)) {
751         ANSR_LOGD("Not allow to notify.");
752         reminder->OnShow(false, isSysTimeChanged, false);
753         store_->UpdateOrInsert(reminder, FindNotificationBundleOption(reminder->GetReminderId()));
754         return;
755     }
756     bool toPlaySound = isNeedToPlaySound && ShouldAlert(reminder) ? true : false;
757     reminder->OnShow(toPlaySound, isSysTimeChanged, true);
758     AddToShowedReminders(reminder);
759     UpdateNotification(reminder);  // this should be called after OnShow
760 
761     if (alertingReminderId_ != -1) {
762         TerminateAlerting(alertingReminder_, "PlaySoundAndVibration");
763     }
764     ANSR_LOGD("publish notification.(reminderId=%{public}d)", reminder->GetReminderId());
765     ErrCode errCode = advancedNotificationService_->PublishPreparedNotification(notificationRequest, bundleOption);
766     if (errCode != ERR_OK) {
767         reminder->OnShowFail();
768         RemoveFromShowedReminders(reminder);
769     } else {
770         if (toPlaySound) {
771             PlaySoundAndVibration(reminder);  // play sound and vibration
772             if (needScheduleTimeout) {
773                 StartTimer(reminder, TimerType::ALERTING_TIMER);
774             } else {
775                 TerminateAlerting(1, reminder);
776             }
777         }
778         HandleSameNotificationIdShowing(reminder);
779     }
780     store_->UpdateOrInsert(reminder, FindNotificationBundleOption(reminder->GetReminderId()));
781 
782     if (isNeedToStartNext) {
783         StartRecentReminder();
784     }
785 }
786 
UpdateNotification(const sptr<ReminderRequest> & reminder)787 void ReminderDataManager::UpdateNotification(const sptr<ReminderRequest> &reminder)
788 {
789     int32_t reminderId = reminder->GetReminderId();
790     sptr<NotificationBundleOption> bundleOption = FindNotificationBundleOption(reminderId);
791     if (bundleOption == nullptr) {
792         ANSR_LOGE("Get bundle option fail, reminderId=%{public}d", reminderId);
793         return;
794     }
795     reminder->UpdateNotificationRequest(ReminderRequest::UpdateNotificationType::COMMON, "");
796     reminder->UpdateNotificationRequest(ReminderRequest::UpdateNotificationType::REMOVAL_WANT_AGENT, "");
797     reminder->UpdateNotificationRequest(ReminderRequest::UpdateNotificationType::WANT_AGENT, "");
798     reminder->UpdateNotificationRequest(ReminderRequest::UpdateNotificationType::MAX_SCREEN_WANT_AGENT, "");
799     reminder->UpdateNotificationRequest(ReminderRequest::UpdateNotificationType::BUNDLE_INFO, "");
800 }
801 
SnoozeReminder(const OHOS::EventFwk::Want & want)802 void ReminderDataManager::SnoozeReminder(const OHOS::EventFwk::Want &want)
803 {
804     int32_t reminderId = static_cast<int32_t>(want.GetIntParam(ReminderRequest::PARAM_REMINDER_ID, -1));
805     sptr<ReminderRequest> reminder = FindReminderRequestLocked(reminderId);
806     if (reminder == nullptr) {
807         ANSR_LOGW("Invalid reminder id: %{public}d", reminderId);
808         return;
809     }
810     SnoozeReminderImpl(reminder);
811 }
812 
SnoozeReminderImpl(sptr<ReminderRequest> & reminder)813 void ReminderDataManager::SnoozeReminderImpl(sptr<ReminderRequest> &reminder)
814 {
815     ANSR_LOGI("Snooze the reminder request, %{public}s", reminder->Dump().c_str());
816     int32_t reminderId = reminder->GetReminderId();
817     if (activeReminderId_ == reminderId) {
818         ANSR_LOGD("Cancel active reminder, id=%{public}d", activeReminderId_);
819         activeReminder_->OnStop();
820         StopTimerLocked(TimerType::TRIGGER_TIMER);
821     }
822 
823     // 1) Snooze the reminder by manual
824     if (alertingReminderId_ == reminder->GetReminderId()) {
825         StopSoundAndVibrationLocked(reminder);
826         StopTimerLocked(TimerType::ALERTING_TIMER);
827     }
828     reminder->OnSnooze();
829     store_->UpdateOrInsert(reminder, FindNotificationBundleOption(reminder->GetReminderId()));
830 
831     // 2) Show the notification dialog in the systemUI
832     sptr<NotificationBundleOption> bundleOption = FindNotificationBundleOption(reminderId);
833     sptr<NotificationRequest> notificationRequest = reminder->GetNotificationRequest();
834     if (bundleOption == nullptr) {
835         ANSR_LOGW("snoozeReminder, invalid bundle option");
836         return;
837     }
838     ANSR_LOGD("publish(update) notification.(reminderId=%{public}d)", reminder->GetReminderId());
839     UpdateNotification(reminder);
840     if (advancedNotificationService_ == nullptr) {
841         ANSR_LOGE("Ans instance is null");
842         return;
843     }
844     advancedNotificationService_->PublishPreparedNotification(notificationRequest, bundleOption);
845     StartRecentReminder();
846 }
847 
StartRecentReminder()848 void ReminderDataManager::StartRecentReminder()
849 {
850     sptr<ReminderRequest> reminder = GetRecentReminderLocked();
851     if (reminder == nullptr) {
852         ANSR_LOGI("No reminder need to start");
853         SetActiveReminder(reminder);
854         return;
855     }
856     if (activeReminderId_ == reminder->GetReminderId()) {
857         ANSR_LOGI("Recent reminder has already run, no need to start again.");
858         return;
859     }
860     if (activeReminderId_ != -1) {
861         activeReminder_->OnStop();
862         store_->UpdateOrInsert(activeReminder_, FindNotificationBundleOption(activeReminderId_));
863         StopTimerLocked(TimerType::TRIGGER_TIMER);
864     }
865     ANSR_LOGI("Start recent reminder");
866     StartTimerLocked(reminder, TimerType::TRIGGER_TIMER);
867     reminder->OnStart();
868     store_->UpdateOrInsert(reminder, FindNotificationBundleOption(reminder->GetReminderId()));
869 }
870 
StopAlertingReminder(const sptr<ReminderRequest> & reminder)871 void ReminderDataManager::StopAlertingReminder(const sptr<ReminderRequest> &reminder)
872 {
873     if (reminder == nullptr) {
874         ANSR_LOGE("StopAlertingReminder illegal.");
875         return;
876     }
877     if ((alertingReminderId_ == -1) || (reminder->GetReminderId() != alertingReminderId_)) {
878         ANSR_LOGE("StopAlertingReminder is illegal.");
879         return;
880     }
881     StopSoundAndVibration(alertingReminder_);
882     StopTimer(TimerType::ALERTING_TIMER);
883 }
884 
Dump() const885 std::string ReminderDataManager::Dump() const
886 {
887     std::lock_guard<std::mutex> lock(ReminderDataManager::MUTEX);
888     std::map<std::string, std::vector<sptr<ReminderRequest>>> bundleNameMap;
889     for (auto it = reminderVector_.begin(); it != reminderVector_.end(); ++it) {
890         if ((*it)->IsExpired()) {
891             continue;
892         }
893         int32_t reminderId = (*it)->GetReminderId();
894         auto mit = notificationBundleOptionMap_.find(reminderId);
895         if (mit == notificationBundleOptionMap_.end()) {
896             ANSR_LOGE("Dump get notificationBundleOption(reminderId=%{public}d) fail", reminderId);
897             continue;
898         }
899         std::string bundleName = mit->second->GetBundleName();
900         auto val = bundleNameMap.find(bundleName);
901         if (val == bundleNameMap.end()) {
902             std::vector<sptr<ReminderRequest>> reminders;
903             reminders.push_back(*it);
904             bundleNameMap.insert(std::pair<std::string, std::vector<sptr<ReminderRequest>>>(bundleName, reminders));
905         } else {
906             val->second.push_back(*it);
907         }
908     }
909 
910     std::string allReminders = "";
911     for (auto it = bundleNameMap.begin(); it != bundleNameMap.end(); ++it) {
912         std::string bundleName = it->first;
913         std::vector<sptr<ReminderRequest>> reminders = it->second;
914         sort(reminders.begin(), reminders.end(), cmp);
915         std::string oneBundleReminders = bundleName + ":{\n";
916         oneBundleReminders += "    totalCount:" + std::to_string(reminders.size()) + ",\n";
917         oneBundleReminders += "    reminders:{\n";
918         for (auto vit = reminders.begin(); vit != reminders.end(); ++vit) {
919             oneBundleReminders += "        [\n";
920             std::string reminderInfo = (*vit)->Dump();
921             oneBundleReminders += "            " + reminderInfo + "\n";
922             oneBundleReminders += "        ],\n";
923         }
924         oneBundleReminders += "    },\n";
925         oneBundleReminders += "},\n";
926         allReminders += oneBundleReminders;
927     }
928 
929     return "ReminderDataManager{ totalCount:" + std::to_string(totalCount_) + ",\n" +
930            "timerId:" + std::to_string(timerId_) + ",\n" +
931            "activeReminderId:" + std::to_string(activeReminderId_) + ",\n" +
932            allReminders + "}";
933 }
934 
GetRecentReminderLocked()935 sptr<ReminderRequest> ReminderDataManager::GetRecentReminderLocked()
936 {
937     std::lock_guard<std::mutex> lock(ReminderDataManager::MUTEX);
938     sort(reminderVector_.begin(), reminderVector_.end(), cmp);
939     for (auto it = reminderVector_.begin(); it != reminderVector_.end();) {
940         if (!(*it)->IsExpired()) {
941             ANSR_LOGI("GetRecentReminderLocked: %{public}s", (*it)->Dump().c_str());
942             time_t now;
943             (void)time(&now);  // unit is seconds.
944             if (now < 0
945                 || ReminderRequest::GetDurationSinceEpochInMilli(now) > (*it)->GetTriggerTimeInMilli()) {
946                 ANSR_LOGE("Get recent reminder while the trigger time is overdue.");
947                 it++;
948                 continue;
949             }
950             return *it;
951         }
952         if (!(*it)->CanRemove()) {
953             ANSR_LOGD("Reminder has been expired: %{public}s", (*it)->Dump().c_str());
954             it++;
955             continue;
956         }
957         int32_t reminderId = (*it)->GetReminderId();
958         ANSR_LOGD("Containers(vector) remove. reminderId=%{public}d", reminderId);
959         auto mit = notificationBundleOptionMap_.find(reminderId);
960         if (mit == notificationBundleOptionMap_.end()) {
961             ANSR_LOGE("Remove notificationBundleOption(reminderId=%{public}d) fail", reminderId);
962         } else {
963             ANSR_LOGD("Containers(map) remove. reminderId=%{public}d", reminderId);
964             notificationBundleOptionMap_.erase(mit);
965         }
966         it = reminderVector_.erase(it);
967         totalCount_--;
968         store_->Delete(reminderId);
969     }
970     return nullptr;
971 }
972 
HandleImmediatelyShow(std::vector<sptr<ReminderRequest>> & showImmediately,bool isSysTimeChanged)973 void ReminderDataManager::HandleImmediatelyShow(
974     std::vector<sptr<ReminderRequest>> &showImmediately, bool isSysTimeChanged)
975 {
976     bool isAlerting = false;
977     for (auto it = showImmediately.begin(); it != showImmediately.end(); ++it) {
978         if (!isAlerting) {
979             ShowReminder((*it), true, false, isSysTimeChanged, false);
980             isAlerting = true;
981         } else {
982             ShowReminder((*it), false, false, isSysTimeChanged, false);
983         }
984     }
985 }
986 
HandleRefreshReminder(const uint8_t & type,sptr<ReminderRequest> & reminder)987 sptr<ReminderRequest> ReminderDataManager::HandleRefreshReminder(const uint8_t &type, sptr<ReminderRequest> &reminder)
988 {
989     reminder->SetReminderTimeInMilli(ReminderRequest::INVALID_LONG_LONG_VALUE);
990     uint64_t triggerTimeBefore = reminder->GetTriggerTimeInMilli();
991     bool needShowImmediately = false;
992     if (type == TIME_ZONE_CHANGE) {
993         needShowImmediately = reminder->OnTimeZoneChange();
994     }
995     if (type == DATE_TIME_CHANGE) {
996         needShowImmediately = reminder->OnDateTimeChange();
997     }
998     if (!needShowImmediately) {
999         uint64_t triggerTimeAfter = reminder->GetTriggerTimeInMilli();
1000         if (triggerTimeBefore != triggerTimeAfter || reminder->GetReminderId() == alertingReminderId_) {
1001             CloseReminder(reminder, true);
1002         }
1003         store_->UpdateOrInsert(reminder, FindNotificationBundleOption(reminder->GetReminderId()));
1004         return nullptr;
1005     }
1006     store_->UpdateOrInsert(reminder, FindNotificationBundleOption(reminder->GetReminderId()));
1007     return reminder;
1008 }
1009 
HandleSameNotificationIdShowing(const sptr<ReminderRequest> reminder)1010 void ReminderDataManager::HandleSameNotificationIdShowing(const sptr<ReminderRequest> reminder)
1011 {
1012     // not add ReminderDataManager::MUTEX, as ShowActiveReminderExtendLocked has locked
1013     int32_t notificationId = reminder->GetNotificationId();
1014     ANSR_LOGD("HandleSameNotificationIdShowing notificationId=%{public}d", notificationId);
1015     int32_t curReminderId = reminder->GetReminderId();
1016     auto mit = notificationBundleOptionMap_.find(curReminderId);
1017     if (mit == notificationBundleOptionMap_.end()) {
1018         ANSR_LOGE("Error occur when get bundle option, reminderId=%{public}d", curReminderId);
1019         return;
1020     }
1021 
1022     for (auto it = reminderVector_.begin(); it != reminderVector_.end(); ++it) {
1023         int32_t tmpId = (*it)->GetReminderId();
1024         if (tmpId == curReminderId) {
1025             continue;
1026         }
1027         if (!(*it)->IsShowing()) {
1028             continue;
1029         }
1030         sptr<NotificationBundleOption>  bundleOption = FindNotificationBundleOption(tmpId);
1031         if (bundleOption == nullptr) {
1032             ANSR_LOGW("Get notificationBundleOption(reminderId=%{public}d) fail", tmpId);
1033             continue;
1034         }
1035         if (notificationId == (*it)->GetNotificationId() && IsBelongToSameApp(bundleOption, mit->second)) {
1036             if ((*it)->IsAlerting()) {
1037                 StopAlertingReminder(*it);
1038             }
1039             (*it)->OnSameNotificationIdCovered();
1040             RemoveFromShowedReminders(*it);
1041             store_->UpdateOrInsert((*it), FindNotificationBundleOption((*it)->GetReminderId()));
1042         }
1043     }
1044 }
1045 
Init(bool isFromBootComplete)1046 void ReminderDataManager::Init(bool isFromBootComplete)
1047 {
1048     ANSR_LOGD("ReminderDataManager Init, isFromBootComplete:%{public}d", isFromBootComplete);
1049     if (IsReminderAgentReady()) {
1050         return;
1051     }
1052     if (store_ == nullptr) {
1053         store_ = std::make_shared<ReminderStore>();
1054     }
1055     if (store_->Init() != ReminderStore::STATE_OK) {
1056         ANSR_LOGW("Db init fail.");
1057         return;
1058     }
1059     LoadReminderFromDb();
1060     InitUserId();
1061     isReminderAgentReady_ = true;
1062     ANSR_LOGD("ReminderAgent is ready.");
1063 }
1064 
InitUserId()1065 void ReminderDataManager::InitUserId()
1066 {
1067     std::vector<int32_t> activeUserId;
1068     AccountSA::OsAccountManager::QueryActiveOsAccountIds(activeUserId);
1069     if (activeUserId.size() > 0) {
1070         currentUserId_ = activeUserId[0];
1071         ANSR_LOGD("Init user id=%{public}d", currentUserId_);
1072     } else {
1073         currentUserId_ = MAIN_USER_ID;
1074         ANSR_LOGE("Failed to get active user id.");
1075     }
1076 }
1077 
GetImmediatelyShowRemindersLocked(std::vector<sptr<ReminderRequest>> & reminders) const1078 void ReminderDataManager::GetImmediatelyShowRemindersLocked(std::vector<sptr<ReminderRequest>> &reminders) const
1079 {
1080     std::lock_guard<std::mutex> lock(ReminderDataManager::MUTEX);
1081     for (auto reminderSptr : reminderVector_) {
1082         if (!(reminderSptr->ShouldShowImmediately())) {
1083             break;
1084         }
1085         if (reminderSptr->GetReminderType() != ReminderRequest::ReminderType::TIMER) {
1086             reminderSptr->SetSnoozeTimesDynamic(0);
1087         }
1088         reminders.push_back(reminderSptr);
1089     }
1090 }
1091 
IsAllowedNotify(const sptr<ReminderRequest> & reminder) const1092 bool ReminderDataManager::IsAllowedNotify(const sptr<ReminderRequest> &reminder) const
1093 {
1094     if (reminder == nullptr) {
1095         return false;
1096     }
1097     int32_t reminderId = reminder->GetReminderId();
1098     auto mit = notificationBundleOptionMap_.find(reminderId);
1099     if (mit == notificationBundleOptionMap_.end()) {
1100         ANSR_LOGE("Get bundle option occur error, reminderId=%{public}d", reminderId);
1101         return false;
1102     }
1103     bool isAllowed = false;
1104     ErrCode errCode = advancedNotificationService_->IsSpecialBundleAllowedNotify(mit->second, isAllowed);
1105     if (errCode != ERR_OK) {
1106         ANSR_LOGE("Failed to call IsSpecialBundleAllowedNotify, errCode=%{public}d", errCode);
1107         return false;
1108     }
1109     return isAllowed;
1110 }
1111 
IsReminderAgentReady() const1112 bool ReminderDataManager::IsReminderAgentReady() const
1113 {
1114     return isReminderAgentReady_;
1115 }
1116 
IsBelongToSameApp(const sptr<NotificationBundleOption> & bundleOption,const sptr<NotificationBundleOption> & other) const1117 bool ReminderDataManager::IsBelongToSameApp(const sptr<NotificationBundleOption> &bundleOption,
1118     const sptr<NotificationBundleOption> &other) const
1119 {
1120     int32_t userIdSrc = ReminderRequest::GetUserId(bundleOption->GetUid());
1121     int32_t userIdTar = ReminderRequest::GetUserId(other->GetUid());
1122     return ((bundleOption->GetBundleName() == other->GetBundleName()) && (userIdSrc == userIdTar)) ? true : false;
1123 }
1124 
LoadReminderFromDb()1125 void ReminderDataManager::LoadReminderFromDb()
1126 {
1127     std::lock_guard<std::mutex> lock(ReminderDataManager::MUTEX);
1128     std::vector<sptr<ReminderRequest>> existReminders = store_->GetAllValidReminders();
1129     reminderVector_ = existReminders;
1130     ANSR_LOGD("LoadReminderFromDb, reminder size=%{public}zu", reminderVector_.size());
1131     for (auto it = reminderVector_.begin(); it != reminderVector_.end(); ++it) {
1132         sptr<NotificationBundleOption> bundleOption = new (std::nothrow) NotificationBundleOption();
1133         if (bundleOption == nullptr) {
1134             ANS_LOGE("Failed to create bundle option due to low memory.");
1135             return;
1136         }
1137         int32_t reminderId = (*it)->GetReminderId();
1138         if (!(store_->GetBundleOption(reminderId, bundleOption))) {
1139             ANSR_LOGE("Get bundle option fail, reminderId=%{public}d", reminderId);
1140             continue;
1141         }
1142         auto ret = notificationBundleOptionMap_.insert(
1143             std::pair<int32_t, sptr<NotificationBundleOption>>(reminderId, bundleOption));
1144         if (!ret.second) {
1145             ANSR_LOGE("Containers add to map error");
1146             continue;
1147         }
1148     }
1149     totalCount_ = static_cast<int16_t>(reminderVector_.size());
1150     ReminderRequest::GLOBAL_ID = store_->GetMaxId() + 1;
1151 }
1152 
PlaySoundAndVibrationLocked(const sptr<ReminderRequest> & reminder)1153 void ReminderDataManager::PlaySoundAndVibrationLocked(const sptr<ReminderRequest> &reminder)
1154 {
1155     std::lock_guard<std::mutex> lock(ReminderDataManager::ALERT_MUTEX);
1156     PlaySoundAndVibration(reminder);
1157 }
1158 
PlaySoundAndVibration(const sptr<ReminderRequest> & reminder)1159 void ReminderDataManager::PlaySoundAndVibration(const sptr<ReminderRequest> &reminder)
1160 {
1161     if (reminder == nullptr) {
1162         ANSR_LOGE("Play sound and vibration failed as reminder is null.");
1163         return;
1164     }
1165     if (alertingReminderId_ != -1) {
1166         TerminateAlerting(alertingReminder_, "PlaySoundAndVibration");
1167     }
1168     ANSR_LOGD("Play sound and vibration, reminderId=%{public}d", reminder->GetReminderId());
1169     if (soundPlayer_ == nullptr) {
1170         soundPlayer_ = Media::PlayerFactory::CreatePlayer();
1171         if (soundPlayer_ == nullptr) {
1172             ANSR_LOGE("Fail to creat player.");
1173             return;
1174         }
1175     }
1176     Uri soundUri = DEFAULT_REMINDER_SOUND;
1177     std::string uri = soundUri.GetSchemeSpecificPart();
1178     ANSR_LOGD("uri:%{public}s", uri.c_str());
1179     soundPlayer_->SetSource(uri);
1180     soundPlayer_->SetLooping(true);
1181     soundPlayer_->PrepareAsync();
1182     soundPlayer_->Play();
1183     SetAlertingReminder(reminder);
1184 }
1185 
GetSoundUri(const sptr<ReminderRequest> & reminder)1186 std::string ReminderDataManager::GetSoundUri(const sptr<ReminderRequest> &reminder)
1187 {
1188     Uri uri = DEFAULT_NOTIFICATION_SOUND;
1189     if (advancedNotificationService_ == nullptr) {
1190         ANSR_LOGE("Ans instance is null.");
1191         return uri.GetSchemeSpecificPart();
1192     }
1193     sptr<NotificationBundleOption> bundle = FindNotificationBundleOption(reminder->GetReminderId());
1194     std::vector<sptr<NotificationSlot>> slots;
1195     ErrCode errCode = advancedNotificationService_->GetSlotsByBundle(bundle, slots);
1196     if (errCode != ERR_OK) {
1197         ANSR_LOGW("Get sound uri fail, use default sound instead.");
1198         return uri.GetSchemeSpecificPart();
1199     }
1200     for (auto it = slots.begin(); it != slots.end(); ++it) {
1201         if ((*it)->GetType() == reminder->GetSlotType()) {
1202             uri = (*it)->GetSound();
1203             break;
1204         }
1205     }
1206     return uri.GetSchemeSpecificPart();
1207 }
1208 
StopSoundAndVibrationLocked(const sptr<ReminderRequest> & reminder)1209 void ReminderDataManager::StopSoundAndVibrationLocked(const sptr<ReminderRequest> &reminder)
1210 {
1211     std::lock_guard<std::mutex> lock(ReminderDataManager::ALERT_MUTEX);
1212     StopSoundAndVibration(reminder);
1213 }
1214 
StopSoundAndVibration(const sptr<ReminderRequest> & reminder)1215 void ReminderDataManager::StopSoundAndVibration(const sptr<ReminderRequest> &reminder)
1216 {
1217     if (reminder == nullptr) {
1218         ANSR_LOGE("Stop sound and vibration failed as reminder is null.");
1219         return;
1220     }
1221     if ((alertingReminderId_ == -1) || (reminder->GetReminderId() != alertingReminderId_)) {
1222         ANSR_LOGE("Stop sound and vibration failed as alertingReminder is illegal, alertingReminderId_=" \
1223             "%{public}d, tarReminderId=%{public}d", alertingReminderId_, reminder->GetReminderId());
1224         return;
1225     }
1226     ANSR_LOGD("Stop sound and vibration, reminderId=%{public}d", reminder->GetReminderId());
1227     if (soundPlayer_ == nullptr) {
1228         ANSR_LOGW("Sound player is null");
1229     } else {
1230         soundPlayer_->Stop();
1231         soundPlayer_->Release();
1232         soundPlayer_ = nullptr;
1233     }
1234     sptr<ReminderRequest> nullReminder = nullptr;
1235     SetAlertingReminder(nullReminder);
1236 }
1237 
RemoveFromShowedReminders(const sptr<ReminderRequest> & reminder)1238 void ReminderDataManager::RemoveFromShowedReminders(const sptr<ReminderRequest> &reminder)
1239 {
1240     std::lock_guard<std::mutex> lock(ReminderDataManager::SHOW_MUTEX);
1241     for (auto it = showedReminderVector_.begin(); it != showedReminderVector_.end(); ++it) {
1242         if ((*it)->GetReminderId() == reminder->GetReminderId()) {
1243             ANSR_LOGD("Containers(shownVector) remove. reminderId=%{public}d", reminder->GetReminderId());
1244             showedReminderVector_.erase(it);
1245             break;
1246         }
1247     }
1248 }
1249 
RefreshRemindersLocked(uint8_t type)1250 std::vector<sptr<ReminderRequest>> ReminderDataManager::RefreshRemindersLocked(uint8_t type)
1251 {
1252     std::lock_guard<std::mutex> lock(ReminderDataManager::MUTEX);
1253     std::vector<sptr<ReminderRequest>> showImmediately;
1254     for (auto it = reminderVector_.begin(); it != reminderVector_.end(); ++it) {
1255         sptr<ReminderRequest> reminder = HandleRefreshReminder(type, (*it));
1256         if (reminder != nullptr) {
1257             showImmediately.push_back(reminder);
1258         }
1259     }
1260     return showImmediately;
1261 }
1262 
RemoveReminderLocked(const int32_t & reminderId)1263 void ReminderDataManager::RemoveReminderLocked(const int32_t &reminderId)
1264 {
1265     std::lock_guard<std::mutex> lock(ReminderDataManager::MUTEX);
1266     for (auto it = reminderVector_.begin(); it != reminderVector_.end();) {
1267         if (reminderId == (*it)->GetReminderId()) {
1268             ANSR_LOGD("Containers(vector) remove. reminderId=%{public}d", reminderId);
1269             it = reminderVector_.erase(it);
1270             totalCount_--;
1271             store_->Delete(reminderId);
1272             break;
1273         } else {
1274             ++it;
1275         }
1276     }
1277     auto it = notificationBundleOptionMap_.find(reminderId);
1278     if (it == notificationBundleOptionMap_.end()) {
1279         ANSR_LOGE("Remove notificationBundleOption(reminderId=%{public}d) fail", reminderId);
1280     } else {
1281         ANSR_LOGD("Containers(map) remove. reminderId=%{public}d", reminderId);
1282         notificationBundleOptionMap_.erase(it);
1283     }
1284 }
1285 
StartTimerLocked(const sptr<ReminderRequest> & reminderRequest,TimerType type)1286 void ReminderDataManager::StartTimerLocked(const sptr<ReminderRequest> &reminderRequest, TimerType type)
1287 {
1288     std::lock_guard<std::mutex> lock(ReminderDataManager::TIMER_MUTEX);
1289     StartTimer(reminderRequest, type);
1290 }
1291 
StartTimer(const sptr<ReminderRequest> & reminderRequest,TimerType type)1292 void ReminderDataManager::StartTimer(const sptr<ReminderRequest> &reminderRequest, TimerType type)
1293 {
1294     sptr<MiscServices::TimeServiceClient> timer = MiscServices::TimeServiceClient::GetInstance();
1295     if (timer == nullptr) {
1296         ANS_LOGE("Failed to start timer due to get TimeServiceClient is null.");
1297         return;
1298     }
1299     time_t now;
1300     (void)time(&now);  // unit is seconds.
1301     if (now < 0) {
1302         ANSR_LOGE("Get now time error");
1303         return;
1304     }
1305     uint64_t triggerTime = 0;
1306     switch (type) {
1307         case TimerType::TRIGGER_TIMER: {
1308             if (timerId_ != 0) {
1309                 ANSR_LOGE("Trigger timer has already started.");
1310                 break;
1311             }
1312             SetActiveReminder(reminderRequest);
1313             timerId_ = timer->CreateTimer(REMINDER_DATA_MANAGER->CreateTimerInfo(type, reminderRequest));
1314             triggerTime = reminderRequest->GetTriggerTimeInMilli();
1315             timer->StartTimer(timerId_, triggerTime);
1316             ANSR_LOGD("Start timing (next triggerTime), timerId=%{public}" PRIu64 "", timerId_);
1317             break;
1318         }
1319         case TimerType::ALERTING_TIMER: {
1320             if (timerIdAlerting_ != 0) {
1321                 ANSR_LOGE("Alerting time out timer has already started.");
1322                 break;
1323             }
1324             triggerTime = ReminderRequest::GetDurationSinceEpochInMilli(now)
1325                 + static_cast<uint64_t>(reminderRequest->GetRingDuration() * ReminderRequest::MILLI_SECONDS);
1326             timerIdAlerting_ = timer->CreateTimer(REMINDER_DATA_MANAGER->CreateTimerInfo(type, reminderRequest));
1327             timer->StartTimer(timerIdAlerting_, triggerTime);
1328             ANSR_LOGD(
1329                 "Start timing (alerting time out), timerId=%{public}" PRIu64 "", timerIdAlerting_);
1330             break;
1331         }
1332         default: {
1333             ANSR_LOGE("TimerType not support");
1334             break;
1335         }
1336     }
1337     if (triggerTime == 0) {
1338         ANSR_LOGW("Start timer fail");
1339     } else {
1340         ANSR_LOGD("Timing info: now:(%{public}" PRIu64 "), tar:(%{public}" PRIu64 ")",
1341             ReminderRequest::GetDurationSinceEpochInMilli(now), triggerTime);
1342     }
1343 }
1344 
StopTimerLocked(TimerType type)1345 void ReminderDataManager::StopTimerLocked(TimerType type)
1346 {
1347     std::lock_guard<std::mutex> lock(ReminderDataManager::TIMER_MUTEX);
1348     StopTimer(type);
1349 }
1350 
StopTimer(TimerType type)1351 void ReminderDataManager::StopTimer(TimerType type)
1352 {
1353     sptr<MiscServices::TimeServiceClient> timer = MiscServices::TimeServiceClient::GetInstance();
1354     if (timer == nullptr) {
1355         ANSR_LOGE("Failed to stop timer due to get TimeServiceClient is null.");
1356         return;
1357     }
1358     uint64_t timerId = 0;
1359     switch (type) {
1360         case TimerType::TRIGGER_TIMER: {
1361             timerId = timerId_;
1362             ANSR_LOGD("Stop timing (next triggerTime)");
1363             break;
1364         }
1365         case TimerType::ALERTING_TIMER: {
1366             timerId = timerIdAlerting_;
1367             ANSR_LOGD("Stop timing (alerting time out)");
1368             break;
1369         }
1370         default: {
1371             ANSR_LOGE("TimerType not support");
1372             break;
1373         }
1374     }
1375     if (timerId == 0) {
1376         ANSR_LOGD("Timer is not running");
1377         return;
1378     }
1379     ANSR_LOGD("Stop timer id=%{public}" PRIu64 "", timerId);
1380     timer->StopTimer(timerId);
1381     ResetStates(type);
1382 }
1383 
ResetStates(TimerType type)1384 void ReminderDataManager::ResetStates(TimerType type)
1385 {
1386     switch (type) {
1387         case TimerType::TRIGGER_TIMER: {
1388             ANSR_LOGD("ResetStates(activeReminderId, timerId(next triggerTime))");
1389             timerId_ = 0;
1390             activeReminderId_ = -1;
1391             break;
1392         }
1393         case TimerType::ALERTING_TIMER: {
1394             ANSR_LOGD("ResetStates(alertingReminderId, timeId(alerting time out))");
1395             timerIdAlerting_ = 0;
1396             alertingReminderId_ = -1;
1397             break;
1398         }
1399         default: {
1400             ANSR_LOGE("TimerType not support");
1401             break;
1402         }
1403     }
1404 }
1405 
HandleCustomButtonClick(const OHOS::EventFwk::Want & want)1406 void ReminderDataManager::HandleCustomButtonClick(const OHOS::EventFwk::Want &want)
1407 {
1408     int32_t reminderId = static_cast<int32_t>(want.GetIntParam(ReminderRequest::PARAM_REMINDER_ID, -1));
1409     sptr<ReminderRequest> reminder = FindReminderRequestLocked(reminderId);
1410     if (reminder == nullptr) {
1411         ANSR_LOGE("Invalid reminder id: %{public}d", reminderId);
1412         return;
1413     }
1414     CloseReminder(reminder, false);
1415     std::string buttonPkgName = want.GetStringParam("PkgName");
1416     std::string buttonAbilityName = want.GetStringParam("AbilityName");
1417 
1418     AAFwk::Want abilityWant;
1419     abilityWant.SetElementName(buttonPkgName, buttonAbilityName);
1420     abilityWant.SetUri(reminder->GetCustomButtonUri());
1421     auto client = AppExecFwk::AbilityManagerClient::GetInstance();
1422     if (client == nullptr) {
1423         return;
1424     }
1425     int32_t result = client->StartAbility(abilityWant);
1426     if (result != 0) {
1427         ANSR_LOGE("Start ability failed, result = %{public}d", result);
1428         return;
1429     }
1430 }
1431 }
1432 }