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