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 }