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