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