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