From 632b15257409dff71dc695d2be66a4244da33a14 Mon Sep 17 00:00:00 2001 From: derek Date: Mon, 24 Jan 2022 22:02:22 +0800 Subject: [PATCH 01/10] add calendar/snooze/ringDuration and so on Signed-off-by: derek Change-Id: I7d98f7a33928909e9106c1c0cfe85e4db874b7f3 --- frameworks/ans/core/BUILD.gn | 1 + frameworks/ans/core/src/ans_manager_proxy.cpp | 4 + frameworks/ans/core/src/ans_manager_stub.cpp | 4 + frameworks/ans/core/src/ans_notification.cpp | 36 +- frameworks/ans/native/src/reminder_helper.cpp | 1 + .../ans/native/src/reminder_request.cpp | 633 +++++++++++++++-- .../ans/native/src/reminder_request_alarm.cpp | 79 ++- .../native/src/reminder_request_calendar.cpp | 481 +++++++++++++ .../ans/native/src/reminder_request_timer.cpp | 4 +- frameworks/ans/native/test/unittest/BUILD.gn | 1 + .../reminder_request_calendar_test.cpp | 286 ++++++++ .../test/unittest/reminder_request_test.cpp | 14 +- .../unittest/reminder_request_timer_test.cpp | 12 +- frameworks/ans/test/moduletest/BUILD.gn | 1 + .../ans/native/include/reminder_request.h | 157 ++++- .../native/include/reminder_request_alarm.h | 4 +- .../include/reminder_request_calendar.h | 184 +++++ .../native/include/reminder_request_timer.h | 2 +- .../ans/include/reminder/reminder_common.h | 65 +- .../napi/ans/src/reminder/native_module.cpp | 6 + .../kits/napi/ans/src/reminder/publish.cpp | 152 +++- .../napi/ans/src/reminder/reminder_common.cpp | 230 ++++-- services/ans/BUILD.gn | 2 + .../include/advanced_notification_service.h | 2 + services/ans/include/reminder_data_manager.h | 166 ++++- services/ans/include/reminder_event_manager.h | 4 + services/ans/include/reminder_timer_info.h | 10 +- .../ans/src/advanced_notification_service.cpp | 53 +- services/ans/src/reminder_data_manager.cpp | 653 +++++++++++++++--- services/ans/src/reminder_event_manager.cpp | 70 +- services/ans/src/reminder_timer_info.cpp | 14 +- services/ans/test/unittest/BUILD.gn | 1 + services/test/moduletest/BUILD.gn | 1 + 33 files changed, 2945 insertions(+), 388 deletions(-) create mode 100644 frameworks/ans/native/src/reminder_request_calendar.cpp create mode 100644 frameworks/ans/native/test/unittest/reminder_request_calendar_test.cpp create mode 100644 interfaces/innerkits/ans/native/include/reminder_request_calendar.h diff --git a/frameworks/ans/core/BUILD.gn b/frameworks/ans/core/BUILD.gn index 8bd4d57f7..cc8e50066 100644 --- a/frameworks/ans/core/BUILD.gn +++ b/frameworks/ans/core/BUILD.gn @@ -74,6 +74,7 @@ ohos_shared_library("ans_core") { "${frameworks_path}/ans/native/src/reminder_helper.cpp", "${frameworks_path}/ans/native/src/reminder_request.cpp", "${frameworks_path}/ans/native/src/reminder_request_alarm.cpp", + "${frameworks_path}/ans/native/src/reminder_request_calendar.cpp", "${frameworks_path}/ans/native/src/reminder_request_timer.cpp", ] diff --git a/frameworks/ans/core/src/ans_manager_proxy.cpp b/frameworks/ans/core/src/ans_manager_proxy.cpp index b0ab15db8..ce1d52ceb 100644 --- a/frameworks/ans/core/src/ans_manager_proxy.cpp +++ b/frameworks/ans/core/src/ans_manager_proxy.cpp @@ -21,6 +21,7 @@ #include "message_parcel.h" #include "parcel.h" #include "reminder_request_alarm.h" +#include "reminder_request_calendar.h" #include "reminder_request_timer.h" namespace OHOS { @@ -2271,6 +2272,9 @@ ErrCode AnsManagerProxy::ReadReminders( } else if (ReminderRequest::ReminderType::TIMER == reminderType) { ANSR_LOGD("[GetValidReminders] timer"); reminder = reply.ReadParcelable(); + } else if (ReminderRequest::ReminderType::CALENDAR == reminderType) { + ANSR_LOGD("[GetValidReminders] calendar"); + reminder = reply.ReadParcelable(); } else { ANSR_LOGW("[GetValidReminders] type=%{public}d", typeInfo); return ERR_ANS_INVALID_PARAM; diff --git a/frameworks/ans/core/src/ans_manager_stub.cpp b/frameworks/ans/core/src/ans_manager_stub.cpp index 9dee804e9..979f0b2ed 100644 --- a/frameworks/ans/core/src/ans_manager_stub.cpp +++ b/frameworks/ans/core/src/ans_manager_stub.cpp @@ -21,6 +21,7 @@ #include "message_parcel.h" #include "parcel.h" #include "reminder_request_alarm.h" +#include "reminder_request_calendar.h" #include "reminder_request_timer.h" namespace OHOS { @@ -1417,6 +1418,9 @@ ErrCode AnsManagerStub::HandlePublishReminder(MessageParcel &data, MessageParcel } else if (ReminderRequest::ReminderType::TIMER == reminderType) { ANSR_LOGD("Publish timer"); reminder = data.ReadParcelable(); + } else if (ReminderRequest::ReminderType::CALENDAR == reminderType) { + ANSR_LOGD("Publish calendar"); + reminder = data.ReadParcelable(); } else { ANSR_LOGE("Reminder type invalid"); return ERR_ANS_INVALID_PARAM; diff --git a/frameworks/ans/core/src/ans_notification.cpp b/frameworks/ans/core/src/ans_notification.cpp index a9249491d..6c4873d6c 100644 --- a/frameworks/ans/core/src/ans_notification.cpp +++ b/frameworks/ans/core/src/ans_notification.cpp @@ -19,6 +19,7 @@ #include "ans_log_wrapper.h" #include "iservice_registry.h" #include "reminder_request_alarm.h" +#include "reminder_request_calendar.h" #include "reminder_request_timer.h" #include "system_ability_definition.h" @@ -964,19 +965,30 @@ ErrCode AnsNotification::PublishReminder(ReminderRequest &reminder) ANS_LOGE("GetAnsManagerProxy fail."); return ERR_ANS_SERVICE_NOT_CONNECTED; } - sptr tarReminder; - if (reminder.GetReminderType() == ReminderRequest::ReminderType::ALARM) { - ANSR_LOGI("Publish alarm"); - ReminderRequestAlarm &alarm = (ReminderRequestAlarm &)reminder; - tarReminder = new (std::nothrow) ReminderRequestAlarm(alarm); - } else if (reminder.GetReminderType() == ReminderRequest::ReminderType::TIMER) { - ANSR_LOGI("Publish timer"); - ReminderRequestTimer &timer = (ReminderRequestTimer &)reminder; - tarReminder = new (std::nothrow) ReminderRequestTimer(timer); - } else { - ANSR_LOGW("PublishReminder fail."); - return ERR_ANS_INVALID_PARAM; + switch (reminder.GetReminderType()) { + case (ReminderRequest::ReminderType::TIMER): { + ANSR_LOGI("Publish timer"); + ReminderRequestTimer &timer = (ReminderRequestTimer &)reminder; + tarReminder = new (std::nothrow) ReminderRequestTimer(timer); + break; + } + case (ReminderRequest::ReminderType::ALARM): { + ANSR_LOGI("Publish alarm"); + ReminderRequestAlarm &alarm = (ReminderRequestAlarm &)reminder; + tarReminder = new (std::nothrow) ReminderRequestAlarm(alarm); + break; + } + case (ReminderRequest::ReminderType::CALENDAR): { + ANSR_LOGI("Publish calendar"); + ReminderRequestCalendar &calendar = (ReminderRequestCalendar &)reminder; + tarReminder = new (std::nothrow) ReminderRequestCalendar(calendar); + break; + } + default: { + ANSR_LOGW("PublishReminder fail."); + return ERR_ANS_INVALID_PARAM; + } } ErrCode code = ansManagerProxy_->PublishReminder(tarReminder); reminder.SetReminderId(tarReminder->GetReminderId()); diff --git a/frameworks/ans/native/src/reminder_helper.cpp b/frameworks/ans/native/src/reminder_helper.cpp index 39fe3105d..3197916ae 100644 --- a/frameworks/ans/native/src/reminder_helper.cpp +++ b/frameworks/ans/native/src/reminder_helper.cpp @@ -29,6 +29,7 @@ namespace Notification { ErrCode ReminderHelper::PublishReminder(ReminderRequest &reminder) { ANSR_LOGI("PublishReminder start"); + NotificationSlot slot(reminder.GetSlotType()); NotificationHelper::AddNotificationSlot(slot); return DelayedSingleton::GetInstance()->PublishReminder(reminder); diff --git a/frameworks/ans/native/src/reminder_request.cpp b/frameworks/ans/native/src/reminder_request.cpp index 1f7f16d4e..bb8245dfb 100644 --- a/frameworks/ans/native/src/reminder_request.cpp +++ b/frameworks/ans/native/src/reminder_request.cpp @@ -21,11 +21,17 @@ namespace OHOS { namespace Notification { int32_t ReminderRequest::GLOBAL_ID = 0; -const uint64_t ReminderRequest::INVALID_LONG_VALUE = 0; +const uint64_t ReminderRequest::INVALID_LONG_LONG_VALUE = 0; +const uint16_t ReminderRequest::INVALID_U16_VALUE = 0; const uint16_t ReminderRequest::MILLI_SECONDS = 1000; const uint16_t ReminderRequest::SAME_TIME_DISTINGUISH_MILLISECONDS = 1000; +const uint32_t ReminderRequest::MIN_TIME_INTERVAL_IN_MILLI = 5 * 60 * 1000; +const uint8_t ReminderRequest::INVALID_U8_VALUE = 0; const uint8_t ReminderRequest::REMINDER_STATUS_INACTIVE = 0; +const uint8_t ReminderRequest::REMINDER_STATUS_ACTIVE = 1; +const uint8_t ReminderRequest::REMINDER_STATUS_ALERTING = 2; const uint8_t ReminderRequest::REMINDER_STATUS_SHOWING = 4; +const uint8_t ReminderRequest::REMINDER_STATUS_SNOOZE = 8; const std::string ReminderRequest::NOTIFICATION_LABEL = "REMINDER_AGENT"; const std::string ReminderRequest::REMINDER_EVENT_ALARM_ALERT = "ohos.event.notification.reminder.ALARM_ALERT"; const std::string ReminderRequest::REMINDER_EVENT_CLOSE_ALERT = "ohos.event.notification.reminder.CLOSE_ALERT"; @@ -34,40 +40,71 @@ const std::string ReminderRequest::REMINDER_EVENT_ALERT_TIMEOUT = "ohos.event.no const std::string ReminderRequest::REMINDER_EVENT_REMOVE_NOTIFICATION = "ohos.event.notification.reminder.REMOVE_NOTIFICATION"; const std::string ReminderRequest::PARAM_REMINDER_ID = "REMINDER_ID"; +const int ReminderRequest::BASE_YEAR = 1900; ReminderRequest::ReminderRequest() { wantAgentInfo_ = wantAgentInfo_ == nullptr ? std::make_shared() : wantAgentInfo_; + maxScreenWantAgentInfo_ = + maxScreenWantAgentInfo_ == nullptr ? std::make_shared() : maxScreenWantAgentInfo_; } ReminderRequest::ReminderRequest(const ReminderRequest &other) { - this->actionButtonMap_ = other.actionButtonMap_; this->content_ = other.content_; this->expiredContent_ = other.expiredContent_; + this->snoozeContent_ = other.snoozeContent_; + this->displayContent_ = other.displayContent_; + this->title_ = other.title_; + this->isExpired_ = other.isExpired_; + this->snoozeTimes_ = other.snoozeTimes_; + this->snoozeTimesDynamic_ = other.snoozeTimesDynamic_; + this->state_ = other.state_; this->notificationId_ = other.notificationId_; this->reminderId_ = other.reminderId_; + this->reminderTimeInMilli_ = other.reminderTimeInMilli_; + this->ringDurationInMilli_ = other.ringDurationInMilli_; + this->triggerTimeInMilli_ = other.triggerTimeInMilli_; + this->timeIntervalInMilli_ = other.timeIntervalInMilli_; this->reminderType_ = other.reminderType_; this->slotType_ = other.slotType_; - this->title_ = other.title_; - this->triggerTimeInMilli_ = other.triggerTimeInMilli_; + this->notificationRequest_ = other.notificationRequest_; this->wantAgentInfo_ = other.wantAgentInfo_; + this->maxScreenWantAgentInfo_ = other.maxScreenWantAgentInfo_; + this->actionButtonMap_ = other.actionButtonMap_; } ReminderRequest::ReminderRequest(ReminderType reminderType) { reminderType_ = reminderType; wantAgentInfo_ = wantAgentInfo_ == nullptr ? std::make_shared() : wantAgentInfo_; + maxScreenWantAgentInfo_ = + maxScreenWantAgentInfo_ == nullptr ? std::make_shared() : maxScreenWantAgentInfo_; } bool ReminderRequest::CanRemove() { - if ((state_ & REMINDER_STATUS_SHOWING) == 0) { + if ((state_ & (REMINDER_STATUS_SHOWING | REMINDER_STATUS_ALERTING | REMINDER_STATUS_ACTIVE)) == 0) { return true; } return false; } +bool ReminderRequest::CanShow() const +{ + // when system time change by user manually, and the reminde is to show immediately, + // the show reminder just need to be triggered by ReminderDataManager#RefreshRemindersLocked(uint8_t). + // we need to make the REMINDER_EVENT_ALARM_ALERT do nothing. + uint64_t nowInstantMilli = GetNowInstantMilli(); + if (nowInstantMilli == 0) { + return false; + } + if ((nowInstantMilli - GetReminderTimeInMilli()) < MIN_TIME_INTERVAL_IN_MILLI) { + return false; + } + return true; +} + std::string ReminderRequest::Dump() const { struct tm *timeInfo; @@ -77,7 +114,7 @@ std::string ReminderRequest::Dump() const char dateTimeBuffer[dateTimeLen]; (void)strftime(dateTimeBuffer, dateTimeLen, "%Y-%m-%d %H:%M:%S", timeInfo); return "Reminder[" - "id=" + std::to_string(reminderId_) + + "reminderId=" + std::to_string(reminderId_) + ", type=" + std::to_string(static_cast(reminderType_)) + ", state=" + GetState(state_) + ", nextTriggerTime=" + dateTimeBuffer + @@ -86,8 +123,9 @@ std::string ReminderRequest::Dump() const ReminderRequest& ReminderRequest::SetActionButton(const std::string &title, const ActionButtonType &type) { - if (type != ActionButtonType::CLOSE) { - ANSR_LOGI("Button type only support: %{public}d", static_cast(ActionButtonType::CLOSE)); + if (type != ActionButtonType::CLOSE && type != ActionButtonType::SNOOZE) { + ANSR_LOGI("Button type only support: %{public}d or %{public}d", + static_cast(ActionButtonType::CLOSE), static_cast(ActionButtonType::SNOOZE)); return *this; } ActionButtonInfo actionButtonInfo; @@ -144,20 +182,24 @@ void ReminderRequest::OnClose(bool updateNext) ANSR_LOGE("onClose, the state of reminder is incorrect, state:%{public}s", GetState(state_).c_str()); return; } - SetState(false, REMINDER_STATUS_SHOWING, "onClose()"); + SetState(false, REMINDER_STATUS_SHOWING | REMINDER_STATUS_SNOOZE, "onClose()"); + if ((state_ & REMINDER_STATUS_ALERTING) != 0) { + SetState(false, REMINDER_STATUS_ALERTING, "onClose"); + } if (updateNext) { - uint64_t nextTriggerTime = PreGetNextTriggerTimeIgnoreSnooze(false); - if (nextTriggerTime == INVALID_LONG_VALUE) { + uint64_t nextTriggerTime = PreGetNextTriggerTimeIgnoreSnooze(true, false); + if (nextTriggerTime == INVALID_LONG_LONG_VALUE) { isExpired_ = true; } else { SetTriggerTimeInMilli(nextTriggerTime); + snoozeTimesDynamic_ = snoozeTimes_; } } } bool ReminderRequest::OnDateTimeChange() { - uint64_t nextTriggerTime = PreGetNextTriggerTimeIgnoreSnooze(false); + uint64_t nextTriggerTime = PreGetNextTriggerTimeIgnoreSnooze(true, false); return HandleSysTimeChange(triggerTimeInMilli_, nextTriggerTime); } @@ -167,19 +209,19 @@ bool ReminderRequest::HandleSysTimeChange(uint64_t oriTriggerTime, uint64_t optT return false; } bool showImmediately = false; - if (optTriggerTime != INVALID_LONG_VALUE && optTriggerTime <= oriTriggerTime) { + if (optTriggerTime != INVALID_LONG_LONG_VALUE && optTriggerTime <= oriTriggerTime) { // case1. switch to a previous time SetTriggerTimeInMilli(optTriggerTime); + snoozeTimesDynamic_ = snoozeTimes_; } else { - time_t now; - time(&now); // unit is seconds. - if (static_cast(now) < 0) { - ANSR_LOGE("Get now time error"); + uint64_t now = GetNowInstantMilli(); + if (now == 0) { return false; } - if (oriTriggerTime <= (static_cast(now) * MILLI_SECONDS)) { + if (oriTriggerTime <= now) { // case2. switch to a future time, trigger time is less than now time. // when the reminder show immediately, trigger time will update in onShow function. + snoozeTimesDynamic_ = 0; showImmediately = true; } else { // case3. switch to a future time, trigger time is larger than now time. @@ -189,19 +231,23 @@ bool ReminderRequest::HandleSysTimeChange(uint64_t oriTriggerTime, uint64_t optT return showImmediately; } -bool ReminderRequest::HandleTimeZoneChange( - uint64_t oldZoneTriggerTime, uint64_t newZoneTriggerTime, uint64_t optTriggerTime) +bool ReminderRequest::HandleTimeZoneChange(uint64_t oldZoneTriggerTime, uint64_t newZoneTriggerTime, uint64_t optTriggerTime) { if (isExpired_) { return false; } ANSR_LOGD("Handle timezone change, oldZoneTriggerTime:%{public}llu, newZoneTriggerTime:%{public}llu", (unsigned long long)oldZoneTriggerTime, (unsigned long long)newZoneTriggerTime); + if (oldZoneTriggerTime == newZoneTriggerTime) { + return false; + } bool showImmediately = false; - if (optTriggerTime != INVALID_LONG_VALUE && oldZoneTriggerTime < newZoneTriggerTime) { + if (optTriggerTime != INVALID_LONG_LONG_VALUE && oldZoneTriggerTime < newZoneTriggerTime) { // case1. timezone change to smaller SetTriggerTimeInMilli(optTriggerTime); + snoozeTimesDynamic_ = snoozeTimes_; } else { + // case2. timezone change to larger time_t now; time(&now); // unit is seconds. if (static_cast(now) < 0) { @@ -209,10 +255,10 @@ bool ReminderRequest::HandleTimeZoneChange( return false; } if (newZoneTriggerTime <= (static_cast(now))) { - // case2. timezone change to larger + snoozeTimesDynamic_ = 0; showImmediately = true; } else { - SetTriggerTimeInMilli(newZoneTriggerTime); + SetTriggerTimeInMilli(newZoneTriggerTime * MILLI_SECONDS); showImmediately = false; } } @@ -221,15 +267,91 @@ bool ReminderRequest::HandleTimeZoneChange( void ReminderRequest::OnSameNotificationIdCovered() { - SetState(false, REMINDER_STATUS_SHOWING, "OnSameNotificationIdCovered"); + SetState(false, REMINDER_STATUS_ALERTING | REMINDER_STATUS_SHOWING | REMINDER_STATUS_SNOOZE, + "OnSameNotificationIdCovered"); } -void ReminderRequest::OnShow(bool isSysTimeChanged, bool allowToNotify) +void ReminderRequest::OnShow(bool isPlaySoundOrVibration, bool isSysTimeChanged, bool allowToNotify) { + if ((state_ & (REMINDER_STATUS_ACTIVE | REMINDER_STATUS_SNOOZE)) != 0) { + SetState(false, REMINDER_STATUS_ACTIVE | REMINDER_STATUS_SNOOZE, "onShow()"); + } + if (isSysTimeChanged) { + uint64_t nowInstantMilli = GetNowInstantMilli(); + if (nowInstantMilli == 0) { + ANSR_LOGW("Onshow, get now time error"); + } + reminderTimeInMilli_ = nowInstantMilli; + } else { + reminderTimeInMilli_ = triggerTimeInMilli_; + } + UpdateNextReminder(false); if (allowToNotify) { SetState(true, REMINDER_STATUS_SHOWING, "OnShow"); + if (isPlaySoundOrVibration) { + SetState(true, REMINDER_STATUS_ALERTING, "OnShow"); + } + UpdateNotificationStateForAlert(); } - UpdateNextReminder(); +} + +void ReminderRequest::OnShowFail() +{ + SetState(false, REMINDER_STATUS_SHOWING, "OnShowFailed()"); +} + +bool ReminderRequest::OnSnooze() +{ + if ((state_ & REMINDER_STATUS_SNOOZE) != 0) { + ANSR_LOGW("onSnooze, the state of reminder is incorrect, state: %{public}s", (GetState(state_)).c_str()); + return false; + } + if ((state_ & REMINDER_STATUS_ALERTING) != 0) { + SetState(false, REMINDER_STATUS_ALERTING, "onSnooze()"); + } + if (!UpdateNextReminder(true)) { + return false; + } + UpdateNotificationStateForSnooze(); + if (timeIntervalInMilli_ > 0) { + SetState(true, REMINDER_STATUS_SNOOZE, "onSnooze()"); + } + return true; +} + +void ReminderRequest::OnStart() +{ + if ((state_ & REMINDER_STATUS_ACTIVE) != 0) { + ANSR_LOGE( + "start failed, the state of reminder is incorrect, state: %{public}s", (GetState(state_)).c_str()); + return; + } + if (isExpired_) { + ANSR_LOGE("start failed, the reminder is expired"); + return; + } + SetState(true, REMINDER_STATUS_ACTIVE, "OnStart()"); +} + +void ReminderRequest::OnStop() +{ + ANSR_LOGI("Stop the previous active reminder, %{public}s", this->Dump().c_str()); + if ((state_ & REMINDER_STATUS_ACTIVE) == 0) { + ANSR_LOGW("onStop, the state of reminder is incorrect, state: %{public}s", (GetState(state_)).c_str()); + return; + } + SetState(false, REMINDER_STATUS_ACTIVE, "OnStop"); +} + +bool ReminderRequest::OnTerminate() +{ + if ((state_ & REMINDER_STATUS_ALERTING) == 0) { + ANSR_LOGW("onTerminate, the state of reminder is %{public}s", (GetState(state_)).c_str()); + return false; + } + SetState(false, REMINDER_STATUS_ALERTING, "onTerminate"); + UpdateNotificationStateForAlert(); + return true; } bool ReminderRequest::OnTimeZoneChange() @@ -237,10 +359,17 @@ bool ReminderRequest::OnTimeZoneChange() time_t oldZoneTriggerTime = static_cast(triggerTimeInMilli_ / MILLI_SECONDS); struct tm *oriTime = gmtime(&oldZoneTriggerTime); time_t newZoneTriggerTime = mktime(oriTime); - uint64_t nextTriggerTime = PreGetNextTriggerTimeIgnoreSnooze(false); + uint64_t nextTriggerTime = PreGetNextTriggerTimeIgnoreSnooze(true, false); return HandleTimeZoneChange(oldZoneTriggerTime, newZoneTriggerTime, nextTriggerTime); } +ReminderRequest& ReminderRequest::SetMaxScreenWantAgentInfo( + const std::shared_ptr &maxScreenWantAgentInfo) +{ + maxScreenWantAgentInfo_ = maxScreenWantAgentInfo; + return *this; +} + ReminderRequest& ReminderRequest::SetNotificationId(int32_t notificationId) { notificationId_ = notificationId; @@ -253,6 +382,44 @@ ReminderRequest& ReminderRequest::SetSlotType(const NotificationConstant::SlotTy return *this; } +ReminderRequest& ReminderRequest::SetSnoozeContent(const std::string &snoozeContent) +{ + snoozeContent_ = snoozeContent; + return *this; +} + +ReminderRequest& ReminderRequest::SetSnoozeTimes(const uint8_t snoozeTimes) +{ + snoozeTimes_ = snoozeTimes; + SetSnoozeTimesDynamic(snoozeTimes); + return *this; +} + +ReminderRequest& ReminderRequest::SetSnoozeTimesDynamic(const uint8_t snooziTimes) +{ + snoozeTimesDynamic_ = snooziTimes; + return *this; +} + +ReminderRequest& ReminderRequest::SetTimeInterval(const uint64_t timeIntervalInSeconds) +{ + if (timeIntervalInSeconds < 0 || timeIntervalInSeconds > (UINT64_MAX / MILLI_SECONDS)) { + ANSR_LOGW("SetTimeInterval, replace to set (0s), for the given is out of legal range"); + timeIntervalInMilli_ = 0; + } else { + uint64_t timeIntervalInMilli = timeIntervalInSeconds * MILLI_SECONDS; + if (timeIntervalInMilli > 0 && timeIntervalInMilli < MIN_TIME_INTERVAL_IN_MILLI) { + ANSR_LOGW("SetTimeInterval, replace to set %{public}u, for the given is 0<%{public}llu<%{public}u", + MIN_TIME_INTERVAL_IN_MILLI / MILLI_SECONDS, (unsigned long long)timeIntervalInSeconds, + MIN_TIME_INTERVAL_IN_MILLI / MILLI_SECONDS); + timeIntervalInMilli_ = MIN_TIME_INTERVAL_IN_MILLI; + } else { + timeIntervalInMilli_ = timeIntervalInMilli; + } + } + return *this; +} + ReminderRequest& ReminderRequest::SetTitle(const std::string &title) { title_ = title; @@ -270,8 +437,20 @@ ReminderRequest& ReminderRequest::SetWantAgentInfo(const std::shared_ptr ReminderRequest::GetActionButtons() - const +bool ReminderRequest::ShouldShowImmediately() const +{ + uint64_t nowInstantMilli = GetNowInstantMilli(); + if (nowInstantMilli == 0) { + return false; + } + if (triggerTimeInMilli_ > nowInstantMilli) { + return false; + } + return true; +} + +std::map ReminderRequest::GetActionButtons() const { return actionButtonMap_; } @@ -286,6 +465,11 @@ std::string ReminderRequest::GetExpiredContent() const return expiredContent_; } +std::shared_ptr ReminderRequest::GetMaxScreenWantAgentInfo() const +{ + return maxScreenWantAgentInfo_; +} + int32_t ReminderRequest::GetNotificationId() const { return notificationId_; @@ -301,21 +485,62 @@ int32_t ReminderRequest::GetReminderId() const return reminderId_; } +uint64_t ReminderRequest::GetReminderTimeInMilli() const +{ + return reminderTimeInMilli_; +} + void ReminderRequest::SetReminderId(int32_t reminderId) { reminderId_ = reminderId; } +void ReminderRequest::SetReminderTimeInMilli(const uint64_t reminderTimeInMilli) +{ + reminderTimeInMilli_ = reminderTimeInMilli; +} + +ReminderRequest& ReminderRequest::SetRingDuration(const uint64_t ringDurationInSeconds) +{ + if (ringDurationInSeconds <= 0 || ringDurationInSeconds > (UINT64_MAX / MILLI_SECONDS)) { + ANSR_LOGW("setRingDuration, replace to set (1s), for the given is out of legal range"); + ringDurationInMilli_ = MILLI_SECONDS; + } else { + ringDurationInMilli_ = ringDurationInSeconds * MILLI_SECONDS; + } + return *this; +} + NotificationConstant::SlotType ReminderRequest::GetSlotType() const { return slotType_; } +std::string ReminderRequest::GetSnoozeContent() const +{ + return snoozeContent_; +} + +uint8_t ReminderRequest::GetSnoozeTimes() const +{ + return snoozeTimes_; +} + +uint8_t ReminderRequest::GetSnoozeTimesDynamic() const +{ + return snoozeTimesDynamic_; +} + uint8_t ReminderRequest::GetState() const { return state_; } +uint64_t ReminderRequest::GetTimeInterval() const +{ + return timeIntervalInMilli_ / MILLI_SECONDS; +} + std::string ReminderRequest::GetTitle() const { return title_; @@ -336,6 +561,11 @@ ReminderRequest::ReminderType ReminderRequest::GetReminderType() const return reminderType_; } +uint16_t ReminderRequest::GetRingDuration() const +{ + return ringDurationInMilli_ / MILLI_SECONDS; +} + bool ReminderRequest::UpdateNextReminder() { return false; @@ -343,20 +573,30 @@ bool ReminderRequest::UpdateNextReminder() void ReminderRequest::UpdateNotificationRequest(UpdateNotificationType type, std::string extra) { - ANSR_LOGI("UpdateNotification type=%{public}d", static_cast(type)); - switch (type) { + switch(type) { case UpdateNotificationType::COMMON: { + ANSR_LOGI("UpdateNotification common information"); UpdateNotificationCommon(); break; } - case UpdateNotificationType::ACTION_BUTTON: { - AddActionButtons(); - break; - } case UpdateNotificationType::REMOVAL_WANT_AGENT: { + ANSR_LOGI("UpdateNotification removal_want_agent"); AddRemovalWantAgent(); break; } + case UpdateNotificationType::WANT_AGENT: { + ANSR_LOGI("UpdateNotification want_agent"); + AppExecFwk::ElementName wantAgent("", wantAgentInfo_->pkgName, wantAgentInfo_->abilityName); + SetWantAgent(wantAgent); + break; + } + case UpdateNotificationType::MAX_SCREEN_WANT_AGENT: { + ANSR_LOGI("UpdateNotification max_screen_want_agent"); + AppExecFwk::ElementName maxScreenWantAgent( + "", maxScreenWantAgentInfo_->pkgName, maxScreenWantAgentInfo_->abilityName); + SetMaxScreenWantAgent(maxScreenWantAgent); + break; + } case UpdateNotificationType::CONTENT: { break; } @@ -376,6 +616,10 @@ bool ReminderRequest::Marshalling(Parcel &parcel) const ANSR_LOGE("Failed to write expiredContent"); return false; } + if (!parcel.WriteString(snoozeContent_)) { + ANSR_LOGE("Failed to write snoozeContent"); + return false; + } if (!parcel.WriteString(title_)) { ANSR_LOGE("Failed to write title"); return false; @@ -388,6 +632,20 @@ bool ReminderRequest::Marshalling(Parcel &parcel) const ANSR_LOGE("Failed to write wantAgentInfo`s pkgName"); return false; } + if (!parcel.WriteString(maxScreenWantAgentInfo_->abilityName)) { + ANSR_LOGE("Failed to write maxScreenWantAgentInfo`s abilityName"); + return false; + } + if (!parcel.WriteString(maxScreenWantAgentInfo_->pkgName)) { + ANSR_LOGE("Failed to write maxScreenWantAgentInfo`s pkgName"); + return false; + } + + // write bool + if (!parcel.WriteBool(isExpired_)) { + ANSR_LOGE("Failed to write isExpired"); + return false; + } // write int if (!parcel.WriteInt32(reminderId_)) { @@ -402,6 +660,30 @@ bool ReminderRequest::Marshalling(Parcel &parcel) const ANSR_LOGE("Failed to write triggerTimeInMilli"); return false; } + if (!parcel.WriteUint64(timeIntervalInMilli_)) { + ANSR_LOGE("Failed to write timeIntervalInMilli"); + return false; + } + if (!parcel.WriteUint64(ringDurationInMilli_)) { + ANSR_LOGE("Failed to write ringDurationInMilli"); + return false; + } + if (!parcel.WriteUint64(reminderTimeInMilli_)) { + ANSR_LOGE("Failed to write reminderTimeInMilli"); + return false; + } + if (!parcel.WriteUint8(snoozeTimes_)) { + ANSR_LOGE("Failed to write snoozeTimes"); + return false; + } + if (!parcel.WriteUint8(snoozeTimesDynamic_)) { + ANSR_LOGE("Failed to write snoozeTimesDynamic"); + return false; + } + if (!parcel.WriteUint8(state_)) { + ANSR_LOGE("Failed to write state"); + return false; + } // write enum if (!parcel.WriteUint8(static_cast(reminderType_))) { @@ -454,6 +736,10 @@ bool ReminderRequest::ReadFromParcel(Parcel &parcel) ANSR_LOGE("to read expiredContent"); return false; } + if (!parcel.ReadString(snoozeContent_)) { + ANSR_LOGE("to read snoozeContent"); + return false; + } if (!parcel.ReadString(title_)) { ANSR_LOGE("Failed to read title"); return false; @@ -466,6 +752,20 @@ bool ReminderRequest::ReadFromParcel(Parcel &parcel) ANSR_LOGE("Failed to read wantAgentInfo`s pkgName"); return false; } + if (!parcel.ReadString(maxScreenWantAgentInfo_->abilityName)) { + ANSR_LOGE("Failed to read maxScreenWantAgentInfo`s abilityName"); + return false; + } + if (!parcel.ReadString(maxScreenWantAgentInfo_->pkgName)) { + ANSR_LOGE("Failed to read maxScreenWantAgentInfo`s pkgName"); + return false; + } + + // read bool + if (!parcel.ReadBool(isExpired_)) { + ANSR_LOGE("Failed to read isExpired"); + return false; + } // read int int32_t tempReminderId = -1; @@ -483,6 +783,30 @@ bool ReminderRequest::ReadFromParcel(Parcel &parcel) ANSR_LOGE("Failed to read triggerTimeInMilli"); return false; } + if (!parcel.ReadUint64(timeIntervalInMilli_)) { + ANSR_LOGE("Failed to read timeIntervalInMilli"); + return false; + } + if (!parcel.ReadUint64(ringDurationInMilli_)) { + ANSR_LOGE("Failed to read ringDurationInMilli"); + return false; + } + if (!parcel.ReadUint64(reminderTimeInMilli_)) { + ANSR_LOGE("Failed to read reminderTimeInMilli"); + return false; + } + if (!parcel.ReadUint8(snoozeTimes_)) { + ANSR_LOGE("Failed to read snoozeTimes"); + return false; + } + if (!parcel.ReadUint8(snoozeTimesDynamic_)) { + ANSR_LOGE("Failed to read snoozeTimesDynamic"); + return false; + } + if (!parcel.ReadUint8(state_)) { + ANSR_LOGE("Failed to read state"); + return false; + } // read enum uint8_t reminderType = static_cast(ReminderType::INVALID); @@ -525,32 +849,91 @@ bool ReminderRequest::ReadFromParcel(Parcel &parcel) void ReminderRequest::InitNotificationRequest() { ANSR_LOGI("Init notification"); - auto notificationNormalContent = std::make_shared(); - notificationNormalContent->SetText(content_); - notificationNormalContent->SetTitle(title_); - auto notificationContent = std::make_shared(notificationNormalContent); notificationRequest_ = new NotificationRequest(notificationId_); - notificationRequest_->SetLabel(NOTIFICATION_LABEL); - notificationRequest_->SetShowDeliveryTime(true); - notificationRequest_->SetSlotType(slotType_); - notificationRequest_->SetContent(notificationContent); - SetWantAgent(); // todo move to updateNotification + displayContent_ = content_; + AddActionButtons(true); +} + +bool ReminderRequest::IsAlerting() const +{ + return (state_ & REMINDER_STATUS_ALERTING) != 0; +} + +std::string ReminderRequest::GetDateTimeInfo(const time_t &timeInSecond) const +{ + struct tm *timeInfo; + timeInfo = localtime(&timeInSecond); + uint8_t dateTimeLen = 80; + char dateTimeBuffer[dateTimeLen]; + strftime(dateTimeBuffer, dateTimeLen, "%Y-%m-%d %H:%M:%S", timeInfo); + std::string dateTimeInfo(dateTimeBuffer); + return dateTimeInfo; +} + +uint64_t ReminderRequest::GetNowInstantMilli() const +{ + time_t now; + time(&now); // unit is seconds. + if (static_cast(now) < 0) { + ANSR_LOGE("Get now time error"); + return 0; + } + return static_cast(now * MILLI_SECONDS); +} + +std::string ReminderRequest::GetShowTime(const uint64_t showTime) const +{ + if (reminderType_ == ReminderType::TIMER) { + return ""; + } else { + struct tm *timeInfo; + const time_t showTimeInSecond = static_cast(showTime / 1000); + timeInfo = localtime(&showTimeInSecond); + uint8_t dateTimeLen = 80; + char dateTimeBuffer[dateTimeLen]; + strftime(dateTimeBuffer, dateTimeLen, "%H:%M", timeInfo); + std::string time = dateTimeBuffer; + return time; + } } std::string ReminderRequest::GetState(const uint8_t state) const { - std::string stateInfo = "Inactive"; + std::string stateInfo = "'"; if (state == REMINDER_STATUS_INACTIVE) { - return stateInfo; + stateInfo += "Inactive"; } else { + bool hasSeparator = false; + if ((state & REMINDER_STATUS_ACTIVE) != 0) { + stateInfo += "Active"; + hasSeparator = true; + } + if ((state & REMINDER_STATUS_ALERTING) != 0) { + if (hasSeparator) { + stateInfo += ","; + } + stateInfo += "Alerting"; + hasSeparator = true; + } if ((state & REMINDER_STATUS_SHOWING) != 0) { - stateInfo = "Showing"; + if (hasSeparator) { + stateInfo += ","; + } + stateInfo += "Showing"; + hasSeparator = true; + } + if ((state & REMINDER_STATUS_SNOOZE) != 0) { + if (hasSeparator) { + stateInfo += ","; + } + stateInfo += "Snooze"; } + stateInfo += "'"; } return stateInfo; } -void ReminderRequest::AddActionButtons() +void ReminderRequest::AddActionButtons(const bool includeSnooze) { int requestCode = 10; std::vector flags; @@ -562,6 +945,15 @@ void ReminderRequest::AddActionButtons() want->SetAction(REMINDER_EVENT_CLOSE_ALERT); ANSR_LOGD("Add action button, type is close"); } + if (type == ActionButtonType::SNOOZE) { + if (includeSnooze) { + want->SetAction(REMINDER_EVENT_SNOOZE_ALERT); + ANSR_LOGD("Add action button, type is snooze"); + } else { + ANSR_LOGD("Not add action button, type is snooze, as includeSnooze is false"); + continue; + } + } want->SetParam("REMINDER_ID", reminderId_); std::vector> wants; wants.push_back(want); @@ -602,13 +994,12 @@ void ReminderRequest::AddRemovalWantAgent() notificationRequest_->SetRemovalWantAgent(wantAgent); } -void ReminderRequest::SetWantAgent() +std::shared_ptr ReminderRequest::CreateWantAgent(AppExecFwk::ElementName &element) const { int requestCode = 10; std::vector flags; flags.push_back(WantAgent::WantAgentConstant::Flags::UPDATE_PRESENT_FLAG); auto want = std::make_shared(); - AppExecFwk::ElementName element("", wantAgentInfo_->pkgName, wantAgentInfo_->abilityName); want->SetElement(element); std::vector> wants; wants.push_back(want); @@ -619,7 +1010,18 @@ void ReminderRequest::SetWantAgent() wants, nullptr ); - std::shared_ptr wantAgent = WantAgent::WantAgentHelper::GetWantAgent(wantAgentInfo); + return WantAgent::WantAgentHelper::GetWantAgent(wantAgentInfo); +} + +void ReminderRequest::SetMaxScreenWantAgent(AppExecFwk::ElementName &element) +{ + std::shared_ptr wantAgent = CreateWantAgent(element); + notificationRequest_->SetMaxScreenWantAgent(wantAgent); +} + +void ReminderRequest::SetWantAgent(AppExecFwk::ElementName &element) +{ + std::shared_ptr wantAgent = CreateWantAgent(element); notificationRequest_->SetWantAgent(wantAgent); } @@ -631,15 +1033,140 @@ void ReminderRequest::SetState(bool deSet, const uint8_t newState, std::string f } else { state_ &= ~newState; } - ANSR_LOGI("Switch the reminder(id=%{public}d) state, from %{public}s to %{public}s, called by %{public}s", + ANSR_LOGI("Switch the reminder(reminderId=%{public}d) state, from %{public}s to %{public}s, called by %{public}s", reminderId_, GetState(oldState).c_str(), GetState(state_).c_str(), function.c_str()); } +void ReminderRequest::UpdateActionButtons(const bool &setSnooze) +{ + if (notificationRequest_ == nullptr) { + ANSR_LOGE("updateActionButtons failed, the notificationRequest is null"); + return; + } + notificationRequest_->ClearActionButtons(); + if (setSnooze || snoozeTimesDynamic_ == snoozeTimes_) { + AddActionButtons(false); + } else { + AddActionButtons(true); + } +} + +bool ReminderRequest::UpdateNextReminder(const bool &force) +{ + bool result = true; + if (force) { + uint64_t nowInstantMilli = GetNowInstantMilli(); + if (nowInstantMilli == 0) { + result = false; + } else { + triggerTimeInMilli_ = nowInstantMilli + timeIntervalInMilli_; + snoozeTimesDynamic_ = snoozeTimes_; + if (timeIntervalInMilli_ != 0) { + isExpired_ = false; + } + } + } else { + result = UpdateNextReminder(); + } + std::string info = result == true ? "success" : "no next"; + ANSR_LOGI("updateNextReminder(id=%{public}d, %{public}s): force=%{public}d, trigger time is: %{public}s", + reminderId_, info.c_str(), force, + GetDateTimeInfo(static_cast(triggerTimeInMilli_ / MILLI_SECONDS)).c_str()); + return result; +} + void ReminderRequest::UpdateNotificationCommon() { + notificationRequest_->SetLabel(NOTIFICATION_LABEL); + notificationRequest_->SetShowDeliveryTime(true); + notificationRequest_->SetTapDismissed(true); + notificationRequest_->SetSlotType(slotType_); + auto notificationNormalContent = std::make_shared(); + notificationNormalContent->SetText(displayContent_); + notificationNormalContent->SetTitle(title_); + auto notificationContent = std::make_shared(notificationNormalContent); + notificationRequest_->SetContent(notificationContent); + if (reminderType_ == ReminderRequest::ReminderType::TIMER + || reminderType_ == ReminderRequest::ReminderType::ALARM) { + notificationRequest_->SetUnremovable(true); + } time_t now; (void)time(&now); // unit is seconds. notificationRequest_->SetDeliveryTime(static_cast(now * MILLI_SECONDS)); } + +void ReminderRequest::UpdateNotificationContent(const bool &setSnooze) +{ + if (notificationRequest_ == nullptr) { + ANSR_LOGE("updateNotificationContent failed, the notificationRequest is null"); + return; + } + std::string extendContent = ""; + if (setSnooze) { + if (timeIntervalInMilli_ != 0) { + // snooze the reminder by manual + extendContent = GetShowTime(triggerTimeInMilli_) + + snoozeContent_ == "" ? "" : (" (" + snoozeContent_ + ")"); + } else { + // the reminder is expired now, when timeInterval is 0 + extendContent = GetShowTime(reminderTimeInMilli_) + + expiredContent_ == "" ? "" : (" (" + expiredContent_ + ")"); + } + } else if (IsAlerting()) { + // the reminder is alerting, or ring duration is 0 + extendContent = GetShowTime(reminderTimeInMilli_); + } else if (snoozeTimesDynamic_ != snoozeTimes_) { + // the reminder is snoozing by period artithmetic, when the ring duration is over. + extendContent = GetShowTime(triggerTimeInMilli_) + + snoozeContent_ == "" ? "" : (" (" + snoozeContent_ + ")"); + notificationRequest_->SetTapDismissed(false); + } else { + // the reminder has already snoozed by period arithmetic, when the ring duration is over. + extendContent = GetShowTime(reminderTimeInMilli_) + + expiredContent_ == "" ? "" : (" (" + expiredContent_ + ")"); + } + displayContent_ = content_ + " " + extendContent; + ANSR_LOGD("Display content=%{public}s", displayContent_.c_str()); +} + +void ReminderRequest::UpdateNotificationStateForAlert() +{ + UpdateNotificationContent(false); + UpdateActionButtons(false); +} + +void ReminderRequest::UpdateNotificationStateForSnooze() +{ + UpdateNotificationContent(true); + UpdateActionButtons(true); +} + +int ReminderRequest::GetActualTime(const TimeTransferType &type, int cTime) +{ + switch (type) { + case (TimeTransferType::YEAR): // year + return BASE_YEAR + cTime; + case (TimeTransferType::MONTH): // month + return 1 + cTime; + case (TimeTransferType::WEEK): // week + return 1 + cTime; + default: + return -1; + } +} + +int ReminderRequest::GetCTime(const TimeTransferType &type, int actualTime) +{ + switch (type) { + case (TimeTransferType::YEAR): // year + return actualTime - BASE_YEAR; + case (TimeTransferType::MONTH): // month + return actualTime - 1; + case (TimeTransferType::WEEK): // week + return actualTime - 1; + default: + return -1; + } +} +} } -} \ No newline at end of file diff --git a/frameworks/ans/native/src/reminder_request_alarm.cpp b/frameworks/ans/native/src/reminder_request_alarm.cpp index 7cbc22645..918736dcd 100644 --- a/frameworks/ans/native/src/reminder_request_alarm.cpp +++ b/frameworks/ans/native/src/reminder_request_alarm.cpp @@ -13,9 +13,10 @@ * limitations under the License. */ -#include "reminder_request_alarm.h" #include "ans_log_wrapper.h" +#include "reminder_request_alarm.h" + namespace OHOS { namespace Notification { const uint8_t ReminderRequestAlarm::DAYS_PER_WEEK = 7; @@ -25,10 +26,12 @@ const uint8_t ReminderRequestAlarm::HOURS_PER_DAY = 24; const uint16_t ReminderRequestAlarm::SECONDS_PER_HOUR = 3600; const uint8_t ReminderRequestAlarm::MINUTES_PER_HOUR = 60; const int8_t ReminderRequestAlarm::INVALID_INT_VALUE = -1; +const int8_t ReminderRequestAlarm::DEFAULT_SNOOZE_TIMES = 3; ReminderRequestAlarm::ReminderRequestAlarm(uint8_t hour, uint8_t minute, const std::vector daysOfWeek) : ReminderRequest(ReminderRequest::ReminderType::ALARM) { + SetSnoozeTimes(DEFAULT_SNOOZE_TIMES); hour_ = hour; minute_ = minute; CheckParamValid(); @@ -56,6 +59,15 @@ void ReminderRequestAlarm::CheckParamValid() const } } +bool ReminderRequestAlarm::IsRepeatReminder() const +{ + if ((repeatDays_ != 0) || ((GetTimeInterval() > 0) && (GetSnoozeTimes() > 0))) { + return true; + } else { + return false; + } +} + void ReminderRequestAlarm::SetDaysOfWeek(bool set, std::vector daysOfWeek) { if (daysOfWeek.size() == 0) { @@ -77,9 +89,13 @@ void ReminderRequestAlarm::SetDaysOfWeek(bool set, std::vector daysOfWe } } -uint64_t ReminderRequestAlarm::PreGetNextTriggerTimeIgnoreSnooze(bool forceToGetNext) const +uint64_t ReminderRequestAlarm::PreGetNextTriggerTimeIgnoreSnooze(bool ignoreRepeat, bool forceToGetNext) const { - return GetNextTriggerTime(false); + if (ignoreRepeat || (repeatDays_)) { + return GetNextTriggerTime(forceToGetNext); + } else { + return INVALID_LONG_LONG_VALUE; + } } uint64_t ReminderRequestAlarm::GetNextTriggerTime(bool forceToGetNext) const @@ -95,13 +111,13 @@ uint64_t ReminderRequestAlarm::GetNextTriggerTime(bool forceToGetNext) const tar.tm_hour = hour_; tar.tm_min = minute_; tar.tm_sec = 0; + ANSR_LOGD("Now: year=%{public}d, mon=%{public}d, day=%{public}d, hour=%{public}d, " - "min=%{public}d, sec=%{public}d, week=%{public}d, tar_hour=%{public}d, tar_min=%{public}d", - nowTime->tm_year, nowTime->tm_mon, nowTime->tm_mday, nowTime->tm_hour, - nowTime->tm_min, nowTime->tm_sec, nowTime->tm_wday, hour_, minute_); - ANSR_LOGD("Tar: year=%{public}d, mon=%{public}d, day=%{public}d, hour=%{public}d, " - "min=%{public}d, sec=%{public}d, week=%{public}d", - tar.tm_year, tar.tm_mon, tar.tm_mday, tar.tm_hour, tar.tm_min, tar.tm_sec, tar.tm_wday); + "min=%{public}d, sec=%{public}d, week=%{public}d, \n Target: tar_hour=%{public}d, tar_min=%{public}d", + GetActualTime(TimeTransferType::YEAR, nowTime->tm_year), + GetActualTime(TimeTransferType::MONTH, nowTime->tm_mon), + nowTime->tm_mday, nowTime->tm_hour, nowTime->tm_min, nowTime->tm_sec, + GetActualTime(TimeTransferType::WEEK, nowTime->tm_wday), hour_, minute_); const time_t target = mktime(&tar); int8_t nextDayInterval = GetNextAlarm(now, target); @@ -120,8 +136,10 @@ uint64_t ReminderRequestAlarm::GetNextTriggerTime(bool forceToGetNext) const struct tm *test = localtime(&nextTriggerTime); ANSR_LOGI("NextTriggerTime: year=%{public}d, mon=%{public}d, day=%{public}d, hour=%{public}d, " "min=%{public}d, sec=%{public}d, week=%{public}d, nextTriggerTime=%{public}lld", - test->tm_year, test->tm_mon, test->tm_mday, test->tm_hour, test->tm_min, test->tm_sec, - test->tm_wday, (long long)nextTriggerTime); + GetActualTime(TimeTransferType::YEAR, test->tm_year), + GetActualTime(TimeTransferType::MONTH, test->tm_mon), + test->tm_mday, test->tm_hour, test->tm_min, test->tm_sec, + GetActualTime(TimeTransferType::WEEK, test->tm_wday), (long long)nextTriggerTime); if (static_cast(nextTriggerTime) <= 0) { return 0; @@ -192,18 +210,35 @@ bool ReminderRequestAlarm::OnTimeZoneChange() bool ReminderRequestAlarm::UpdateNextReminder() { - if (repeatDays_ == 0) { - ANSR_LOGD("Set reminder to expired"); - SetExpired(true); - return false; - } - uint64_t nextTriggerTime = GetNextTriggerTime(true); - if (nextTriggerTime != 0) { - ANSR_LOGI("Set next trigger time=%{public}llu", (unsigned long long)nextTriggerTime); - SetTriggerTimeInMilli(nextTriggerTime); + ANSR_LOGD("UpdateNextReminder alarm time"); + if (IsRepeatReminder()) { + uint8_t letfSnoozeTimes = GetSnoozeTimesDynamic(); + if ((letfSnoozeTimes > 0) && (GetTimeInterval() > 0)) { + ANSR_LOGI("Left times: %{public}d, update next triggerTime", GetSnoozeTimesDynamic()); + SetTriggerTimeInMilli(GetTriggerTimeInMilli() + GetTimeInterval() * MILLI_SECONDS); + SetSnoozeTimesDynamic(--letfSnoozeTimes); + } else { + SetSnoozeTimesDynamic(GetSnoozeTimes()); + if (repeatDays_ == 0) { + ANSR_LOGI("No need to update next triggerTime"); + SetExpired(true); + return false; + } else { + uint64_t nextTriggerTime = GetNextTriggerTime(true); + if (nextTriggerTime != INVALID_LONG_LONG_VALUE) { + ANSR_LOGI("Set next trigger time successful, reset dynamic snoozeTimes"); + SetTriggerTimeInMilli(nextTriggerTime); + } else { + ANSR_LOGW("Set reminder to expired"); + SetExpired(true); + return false; + } + } + } return true; } else { - ANSR_LOGD("Set reminder to expired"); + ANSR_LOGD("Single time reminder, not need to update next trigger time"); + SetSnoozeTimesDynamic(GetSnoozeTimes()); SetExpired(true); return false; } @@ -226,13 +261,11 @@ bool ReminderRequestAlarm::Marshalling(Parcel &parcel) const ANSR_LOGE("Failed to write daysOfWeek"); return false; } - return true; } ReminderRequestAlarm *ReminderRequestAlarm::Unmarshalling(Parcel &parcel) { - std::vector daysOfWeek; ANSR_LOGD("New alarm"); auto objptr = new ReminderRequestAlarm(); if ((objptr != nullptr) && !objptr->ReadFromParcel(parcel)) { diff --git a/frameworks/ans/native/src/reminder_request_calendar.cpp b/frameworks/ans/native/src/reminder_request_calendar.cpp new file mode 100644 index 000000000..42dbc3018 --- /dev/null +++ b/frameworks/ans/native/src/reminder_request_calendar.cpp @@ -0,0 +1,481 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ans_log_wrapper.h" + +#include "reminder_request_calendar.h" + +namespace OHOS { +namespace Notification { +const uint8_t ReminderRequestCalendar::MAX_MONTHS_OF_YEAR = 12; +const uint8_t ReminderRequestCalendar::MAX_DAYS_OF_MONTH = 31; +const uint8_t ReminderRequestCalendar::JANUARY = 1; +const uint8_t ReminderRequestCalendar::DECEMBER = 12; +const uint8_t ReminderRequestCalendar::DEFAULT_SNOOZE_TIMES = 3; + +ReminderRequestCalendar::ReminderRequestCalendar(const tm &dateTime, + const std::vector &repeatMonths, const std::vector &repeatDays) : + ReminderRequest(ReminderRequest::ReminderType::CALENDAR) +{ + // 1. record the infomation which designated by user at first time. + firstDesignateYear_ = GetActualTime(TimeTransferType::YEAR, dateTime.tm_year); + firstDesignateMonth_ = GetActualTime(TimeTransferType::MONTH, dateTime.tm_mon); + firstDesignateDay_ = dateTime.tm_mday; + SetRepeatMonths(repeatMonths); + SetRepeatDaysOfMonth(repeatDays); + SetSnoozeTimes(DEFAULT_SNOOZE_TIMES); + + // 2. get the latest valid trigger time. + InitDateTime(dateTime); + hour_ = dateTime_.tm_hour; + minute_ = dateTime_.tm_min; + uint64_t nextTriggerTime = INVALID_LONG_LONG_VALUE; + if ((nextTriggerTime = GetNextTriggerTime()) != INVALID_LONG_LONG_VALUE) { + time_t target = static_cast(nextTriggerTime / MILLI_SECONDS); + dateTime_ = *(localtime(&target)); + } else { + ANSR_LOGW("Not exist next trigger time, please check the param of ReminderRequestCalendar constructor."); + throw std::invalid_argument( + "Not exist next trigger time, please check the param of ReminderRequestCalendar constructor."); + } + + // 2. set the time infomation (used to transfer to proxy service) which is decided to trigger firstly. + year_ = GetActualTime(TimeTransferType::YEAR, dateTime_.tm_year); + month_ = GetActualTime(TimeTransferType::MONTH, dateTime_.tm_mon); + day_ = dateTime_.tm_mday; + second_ = 0; + SetTriggerTimeInMilli(nextTriggerTime); +} + +ReminderRequestCalendar::ReminderRequestCalendar(const ReminderRequestCalendar &other) : ReminderRequest(other) +{ + dateTime_ = other.dateTime_; + firstDesignateYear_ = other.firstDesignateYear_; + firstDesignateMonth_ = other.firstDesignateMonth_; + firstDesignateDay_ = other.firstDesignateDay_; + year_ = other.year_; + month_ = other.month_; + day_ = other.day_; + hour_ = other.hour_; + minute_ = other.minute_; + second_ = other.second_; + repeatMonth_ = other.repeatMonth_; + repeatDay_ = other.repeatDay_; +} + +uint8_t ReminderRequestCalendar::GetDaysOfMonth(const uint16_t &year, const uint8_t &month) const +{ + uint8_t days; + uint8_t daysArray[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + uint8_t february = 2; + uint8_t leapMonth = 29; + uint8_t nonLeapMonth = 28; + if (month == february) { + days = ((((0 == year % 4) && (0 != year % 100)) || (0 == year % 400)) ? leapMonth : nonLeapMonth); + } else { + days = daysArray[month - 1]; + } + return days; +} + +uint8_t ReminderRequestCalendar::GetNextDay( + const uint16_t &settedYear, const uint8_t &settedMonth, const tm &now, const tm &target) const +{ + uint32_t repeatDayTmp = repeatDay_; + uint8_t daysOfSpecialMonth = GetDaysOfMonth(settedYear, settedMonth); + uint8_t setDayTmp = INVALID_U8_VALUE; + for (uint8_t i = 1; i <= daysOfSpecialMonth; i++) { + if ((repeatDayTmp & (1 << (i - 1))) > 0) { + struct tm setTime; + setTime.tm_year = GetCTime(TimeTransferType::YEAR, settedYear); + setTime.tm_mon = GetCTime(TimeTransferType::MONTH, settedMonth); + setTime.tm_mday = i; + setTime.tm_hour = target.tm_hour; + setTime.tm_min = target.tm_min; + setTime.tm_sec = target.tm_sec; + + struct tm nowTime; + nowTime.tm_year = now.tm_year; + nowTime.tm_mon = now.tm_mon; + nowTime.tm_mday = now.tm_mday; + nowTime.tm_hour = now.tm_hour; + nowTime.tm_min = now.tm_min; + nowTime.tm_sec = now.tm_sec; + if (mktime(&nowTime) >= mktime(&setTime)) { + continue; + } else { + setDayTmp = i; + return setDayTmp; + } + } + } + return setDayTmp; +} + +uint64_t ReminderRequestCalendar::GetNextTriggerTime() const +{ + uint64_t triggerTimeInMilli = INVALID_LONG_LONG_VALUE; + time_t now; + time(&now); // unit is seconds. + struct tm nowTime = *(localtime(&now)); + nowTime.tm_sec = 0; + struct tm tarTime; + tarTime.tm_year = GetCTime(TimeTransferType::YEAR, firstDesignateYear_); + tarTime.tm_mon = GetCTime(TimeTransferType::MONTH, firstDesignateMonth_); + tarTime.tm_mday = firstDesignateDay_; + tarTime.tm_hour = hour_; + tarTime.tm_min = minute_; + tarTime.tm_sec = 0; + + if (!(repeatMonth_ > 0 && repeatDay_ > 0)) { + const time_t target = mktime(&tarTime); + if (now <= target) { + triggerTimeInMilli = static_cast(target) * MILLI_SECONDS; + ANSR_LOGD("Now time is: %{public}s", GetDateTimeInfo(now).c_str()); + ANSR_LOGD("Tar time is: %{public}s", GetDateTimeInfo(target).c_str()); + } + return triggerTimeInMilli; + } + triggerTimeInMilli = GetNextTriggerTimeAsRepeatReminder(nowTime, tarTime); + return triggerTimeInMilli; +} + +uint64_t ReminderRequestCalendar::GetNextTriggerTimeAsRepeatReminder(const tm &nowTime, const tm &tarTime) const +{ + uint64_t triggerTimeInMilli = INVALID_LONG_LONG_VALUE; + uint16_t setYear = static_cast(GetActualTime(TimeTransferType::YEAR, nowTime.tm_year)); + uint8_t setMonth = INVALID_U8_VALUE; + uint8_t setDay = INVALID_U8_VALUE; + uint8_t beginMonth = static_cast(GetActualTime(TimeTransferType::MONTH, nowTime.tm_mon)); + uint8_t count = 1; + uint16_t repeatMonthTmp = repeatMonth_; + for (uint8_t i = beginMonth; i < (MAX_MONTHS_OF_YEAR + beginMonth + 1); i++) { + if ((repeatMonthTmp & (1 << ((i - 1) % MAX_MONTHS_OF_YEAR))) > 0) { + setMonth = (i % MAX_MONTHS_OF_YEAR); + setMonth = setMonth == 0 ? DECEMBER : setMonth; + if (count != 1) { + setYear = setMonth <= beginMonth ? setYear + 1 : setYear; + } + setDay = GetNextDay(setYear, setMonth, nowTime, tarTime); + } + if (setDay != INVALID_U8_VALUE) { + break; + } + count++; + } + if ((triggerTimeInMilli = GetTimeInstantMilli(setYear, setMonth, setDay, hour_, minute_, second_)) + != INVALID_LONG_LONG_VALUE) { + ANSR_LOGD("Next calendar time:%{public}u/%{public}u/%{public}u %{public}u:%{public}u:%{public}u", + setYear, setMonth, setDay, hour_, minute_, second_); + } + return triggerTimeInMilli; +} + +uint64_t ReminderRequestCalendar::GetTimeInstantMilli( + uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second) const +{ + struct tm tar; + tar.tm_year = GetCTime(TimeTransferType::YEAR, year); + tar.tm_mon = GetCTime(TimeTransferType::MONTH, month); + tar.tm_mday = day; + tar.tm_hour = hour; + tar.tm_min = minute; + tar.tm_sec = second; + const time_t target = mktime(&tar); + if (target < 0) { + ANSR_LOGW("GetTImeInstantMilli less than 0."); + return INVALID_LONG_LONG_VALUE; + } + return static_cast(target) * MILLI_SECONDS; +} + +void ReminderRequestCalendar::InitDateTime() +{ + dateTime_.tm_year = GetCTime(TimeTransferType::YEAR, year_); + dateTime_.tm_mon = GetCTime(TimeTransferType::MONTH, month_); + dateTime_.tm_mday = day_; + dateTime_.tm_hour = hour_; + dateTime_.tm_min = minute_; + dateTime_.tm_sec = second_; +} + +void ReminderRequestCalendar::InitDateTime(const tm &dateTime) +{ + dateTime_.tm_year = dateTime.tm_year; + dateTime_.tm_mon = dateTime.tm_mon; + dateTime_.tm_mday = dateTime.tm_mday; + dateTime_.tm_hour = dateTime.tm_hour; + dateTime_.tm_min = dateTime.tm_min; + dateTime_.tm_sec = dateTime.tm_sec; +} + +bool ReminderRequestCalendar::IsRepeatReminder() const +{ + return (repeatMonth_ > 0 && repeatDay_ > 0) || (GetTimeInterval() > 0 && GetSnoozeTimes() > 0); +} + + +bool ReminderRequestCalendar::IsRepeatMonth(uint8_t month) const +{ + return (repeatMonth_ & (1 << (month - 1))) > 0; +} + +bool ReminderRequestCalendar::IsRepeatDay(uint8_t day) const{ + return (repeatDay_ & (1 << (day - 1))) > 0; +} + +void ReminderRequestCalendar::SetDay(const uint8_t &day, const bool &isSet) +{ + if (day < 1 || day > MAX_DAYS_OF_MONTH) { + return; + } + if (isSet) { + repeatDay_ |= 1 << (day - 1); + } else { + repeatDay_ &= ~(1 << (day - 1)); + } +} + +void ReminderRequestCalendar::SetMonth(const uint8_t &month, const bool &isSet) +{ + if (month < JANUARY || month > DECEMBER) { + return; + } + if (isSet) { + repeatMonth_ |= 1 << (month - 1); + } else { + repeatMonth_ &= ~ (1 << (month - 1)); + } +} + +void ReminderRequestCalendar::SetRepeatMonths(const std::vector &repeatMonths) +{ + if (repeatMonths.size() > MAX_MONTHS_OF_YEAR) { + ANSR_LOGW("The length of repeat months array should not larger than %{public}u", MAX_MONTHS_OF_YEAR); + throw std::invalid_argument( + "The length of repeat months array should not larger than " + std::to_string(MAX_MONTHS_OF_YEAR)); + } + repeatMonth_ = 0; + for (auto it = repeatMonths.begin(); it != repeatMonths.end(); ++it) { + SetMonth((*it), true); + } +} + +void ReminderRequestCalendar::SetRepeatDaysOfMonth(const std::vector &repeateDays) +{ + if (repeateDays.size() > MAX_DAYS_OF_MONTH) { + ANSR_LOGW("The length of repeat days array should not larger than %{public}u", MAX_DAYS_OF_MONTH); + throw std::invalid_argument( + "The length of repeat days array should not larger than " + std::to_string(MAX_DAYS_OF_MONTH)); + } + repeatDay_ = 0; + for (auto it = repeateDays.begin(); it != repeateDays.end(); ++it) { + SetDay((*it), true); + } +} + +std::vector ReminderRequestCalendar::GetRepeatMonths() const +{ + std::vector repeatMonths; + for (int i = 0; i < 12; i++) { + if (IsRepeatMonth(i + 1)) { + repeatMonths.push_back(i + 1); + } + } + return repeatMonths; +} + +std::vector ReminderRequestCalendar::GetRepeatDays() const +{ + std::vector repeatDays; + for (int i = 0; i < 31; i++) { + if (IsRepeatDay(i + 1)) { + repeatDays.push_back(i + 1); + } + } + return repeatDays; +} + +bool ReminderRequestCalendar::OnDateTimeChange() +{ + return ReminderRequest::OnDateTimeChange(); +} + +bool ReminderRequestCalendar::OnTimeZoneChange() +{ + return ReminderRequest::OnTimeZoneChange(); +} + +bool ReminderRequestCalendar::UpdateNextReminder() +{ + ANSR_LOGD("UpdateNextReminder calendar time"); + if (!IsRepeatReminder()) { + ANSR_LOGI("No need to update next trigger time as it is an one-time reminder."); + SetSnoozeTimesDynamic(GetSnoozeTimes()); + SetExpired(true); + return false; + } + uint8_t leftSnoozeTimes = GetSnoozeTimesDynamic(); + if (leftSnoozeTimes > 0 && (GetTimeInterval() > 0)) { + ANSR_LOGI("Left snooze times: %{public}d, update next triggerTime", leftSnoozeTimes); + SetTriggerTimeInMilli(GetTriggerTimeInMilli() + GetTimeInterval() * MILLI_SECONDS); + SetSnoozeTimesDynamic(--leftSnoozeTimes); + } else { + SetSnoozeTimesDynamic(GetSnoozeTimes()); + if (repeatMonth_ == 0 || repeatDay_ == 0) { + ANSR_LOGI("Not a day repeat reminder, no need to update to next trigger time."); + SetExpired(true); + return false; + } else { + uint64_t nextTriggerTime = GetNextTriggerTime(); + if (nextTriggerTime != INVALID_LONG_LONG_VALUE) { + ANSR_LOGI("Set next trigger time successful, reset dynamic snoozeTimes"); + SetTriggerTimeInMilli(nextTriggerTime); + } else { + ANSR_LOGW("Set next trigger time invalidate"); + SetExpired(true); + return false; + } + } + } + return true; +} + +uint64_t ReminderRequestCalendar::PreGetNextTriggerTimeIgnoreSnooze(bool ignoreRepeat, bool forceToGetNext) const +{ + if (ignoreRepeat || (repeatMonth_ > 0 && repeatDay_ > 0)) { + return GetNextTriggerTime(); + } else { + return INVALID_LONG_LONG_VALUE; + } +} + +bool ReminderRequestCalendar::Marshalling(Parcel &parcel) const +{ + ReminderRequest::Marshalling(parcel); + + // write int + if (!parcel.WriteUint16(year_)) { + ANSR_LOGE("Failed to write year"); + return false; + } + if (!parcel.WriteUint8(month_)) { + ANSR_LOGE("Failed to write month"); + return false; + } + if (!parcel.WriteUint8(day_)) { + ANSR_LOGE("Failed to write day"); + return false; + } + if (!parcel.WriteUint8(hour_)) { + ANSR_LOGE("Failed to write hour"); + return false; + } + if (!parcel.WriteUint8(minute_)) { + ANSR_LOGE("Failed to write minute"); + return false; + } + if (!parcel.WriteUint8(second_)) { + ANSR_LOGE("Failed to write second"); + return false; + } + if (!parcel.WriteUint16(repeatMonth_)) { + ANSR_LOGE("Failed to write repeatMonth"); + return false; + } + if (!parcel.WriteUint32(repeatDay_)) { + ANSR_LOGE("Failed to write repeateDay"); + return false; + } + if (!parcel.WriteUint16(firstDesignateYear_)) { + ANSR_LOGE("Failed to write firstDesignateYear"); + return false; + } + if (!parcel.WriteUint8(firstDesignateMonth_)) { + ANSR_LOGE("Failed to write firstDesignateMonth"); + return false; + } + if (!parcel.WriteUint8(firstDesignateDay_)) { + ANSR_LOGE("Failed to write firstDesignateDay"); + return false; + } + return true; +} + +ReminderRequestCalendar *ReminderRequestCalendar::Unmarshalling(Parcel &parcel) +{ + ANSR_LOGD("New calendar"); + auto objptr = new ReminderRequestCalendar(); + if ((objptr != nullptr) && !objptr->ReadFromParcel(parcel)) { + delete objptr; + objptr = nullptr; + } + return objptr; +} + +bool ReminderRequestCalendar::ReadFromParcel(Parcel &parcel) +{ + ReminderRequest::ReadFromParcel(parcel); + + // read int + if (!parcel.ReadUint16(year_)) { + ANSR_LOGE("Failed to read year"); + return false; + } + if (!parcel.ReadUint8(month_)) { + ANSR_LOGE("Failed to read month"); + return false; + } + if (!parcel.ReadUint8(day_)) { + ANSR_LOGE("Failed to read day"); + return false; + } + if (!parcel.ReadUint8(hour_)) { + ANSR_LOGE("Failed to read hour"); + return false; + } + if (!parcel.ReadUint8(minute_)) { + ANSR_LOGE("Failed to read minute"); + return false; + } + if (!parcel.ReadUint8(second_)) { + ANSR_LOGE("Failed to read second"); + return false; + } + if (!parcel.ReadUint16(repeatMonth_)) { + ANSR_LOGE("Failed to read repeatMonth"); + return false; + } + if (!parcel.ReadUint32(repeatDay_)) { + ANSR_LOGE("Failed to read repeateDay"); + return false; + } + InitDateTime(); + if (!parcel.ReadUint16(firstDesignateYear_)) { + ANSR_LOGE("Failed to read firstDesignateYear"); + return false; + } + if (!parcel.ReadUint8(firstDesignateMonth_)) { + ANSR_LOGE("Failed to read firstDesignateMonth"); + return false; + } + if (!parcel.ReadUint8(firstDesignateDay_)) { + ANSR_LOGE("Failed to read firstDesignateDay"); + return false; + } + return true; +} +} +} \ No newline at end of file diff --git a/frameworks/ans/native/src/reminder_request_timer.cpp b/frameworks/ans/native/src/reminder_request_timer.cpp index 00b975cc7..773e18eba 100644 --- a/frameworks/ans/native/src/reminder_request_timer.cpp +++ b/frameworks/ans/native/src/reminder_request_timer.cpp @@ -47,10 +47,10 @@ uint64_t ReminderRequestTimer::GetInitInfo() const return countDownTimeInSeconds_; } -uint64_t ReminderRequestTimer::PreGetNextTriggerTimeIgnoreSnooze(bool forceToGetNext) const +uint64_t ReminderRequestTimer::PreGetNextTriggerTimeIgnoreSnooze(bool ignoreRepeat, bool forceToGetNext) const { ANSR_LOGD("countdonw time not support PreGetNextTriggerTimeIgnoreSnooze"); - return ReminderRequest::INVALID_LONG_VALUE; + return ReminderRequest::INVALID_LONG_LONG_VALUE; } bool ReminderRequestTimer::OnDateTimeChange() diff --git a/frameworks/ans/native/test/unittest/BUILD.gn b/frameworks/ans/native/test/unittest/BUILD.gn index 4662527a8..fca3be04e 100644 --- a/frameworks/ans/native/test/unittest/BUILD.gn +++ b/frameworks/ans/native/test/unittest/BUILD.gn @@ -31,6 +31,7 @@ ohos_unittest("ans_reminder_unit_test") { sources = [ "${native_path}/test/unittest/reminder_request_alarm_test.cpp", + "${native_path}/test/unittest/reminder_request_calendar_test.cpp", "${native_path}/test/unittest/reminder_request_test.cpp", "${native_path}/test/unittest/reminder_request_timer_test.cpp", ] diff --git a/frameworks/ans/native/test/unittest/reminder_request_calendar_test.cpp b/frameworks/ans/native/test/unittest/reminder_request_calendar_test.cpp new file mode 100644 index 000000000..89767ab5f --- /dev/null +++ b/frameworks/ans/native/test/unittest/reminder_request_calendar_test.cpp @@ -0,0 +1,286 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "ans_log_wrapper.h" +#include "reminder_request_calendar.h" +#include "reminder_helper.h" + +using namespace testing::ext; +namespace OHOS { +namespace Notification { +class ReminderRequestCalendarTest : public testing::Test { +public: + static void SetUpTestCase() + { + ReminderHelper::CancelAllReminders(); + } + static void TearDownTestCase() {} + void SetUp() {} + void TearDown() + { + ReminderHelper::CancelAllReminders(); + } + + std::shared_ptr CreateCalendar(tm &nowTime) { + time_t now; + time(&now); // unit is seconds. + nowTime = *(localtime(&now)); + nowTime.tm_year = 0; + nowTime.tm_mon = 0; + nowTime.tm_mday = 1; + nowTime.tm_hour = 1; + nowTime.tm_min = 1; + std::vector repeatMonths; + std::vector repeatDays; + repeatMonths.push_back(1); + repeatDays.push_back(1); + auto calendar = std::make_shared(nowTime, repeatMonths, repeatDays); + return calendar; + } + + bool IsVectorEqual(std::vector &vectorA, std::vector &vectorB) { + if (vectorA.size() != vectorB.size()) { + return false; + } + if (vectorA.size() == 0) { + return true; + } + auto vitA = vectorA.begin(); + auto vitB = vectorB.begin(); + while (vitA != vectorA.end()) { + if (*vitA != *vitB) { + return false; + } + ++vitA; + ++vitB; + } + return true; + } +}; + +/** + * @tc.number : initDateTime_00100 + * @tc.name : + * @tc.desc : Check firstDesignateYear set successfully. + */ +HWTEST_F(ReminderRequestCalendarTest, initDateTime_00100, Function | SmallTest | Level1) +{ + struct tm nowTime; + auto calendar = ReminderRequestCalendarTest::CreateCalendar(nowTime); + int firstDesignateYear = calendar->GetActualTime(ReminderRequest::TimeTransferType::YEAR, nowTime.tm_year); + EXPECT_TRUE(firstDesignateYear == calendar->GetFirstDesignateYear()) << "Set first designate year error."; +} + +/** + * @tc.number : initDateTime_00200 + * @tc.name : + * @tc.desc : Check firstDesignateMonth set successfully. + */ +HWTEST_F(ReminderRequestCalendarTest, initDateTime_00200, Function | SmallTest | Level1) +{ + struct tm nowTime; + auto calendar = ReminderRequestCalendarTest::CreateCalendar(nowTime); + int firstDesignateMonth = calendar->GetActualTime(ReminderRequest::TimeTransferType::MONTH, nowTime.tm_mon); + EXPECT_TRUE(firstDesignateMonth == calendar->GetFirstDesignageMonth()) << "Set first designate month error."; +} + +/** + * @tc.number : initDateTime_00300 + * @tc.name : + * @tc.desc : Check firstDesignateDay set successfully. + */ +HWTEST_F(ReminderRequestCalendarTest, initDateTime_00300, Function | SmallTest | Level1) +{ + struct tm nowTime; + auto calendar = ReminderRequestCalendarTest::CreateCalendar(nowTime); + int firstDesignateDay = nowTime.tm_mday; + EXPECT_TRUE(firstDesignateDay == calendar->GetFirstDesignateDay()) << "Set first designate day error."; +} + +/** + * @tc.number : initDateTime_00400 + * @tc.name : + * @tc.desc : Check repeatMonth set with normal value successfully. + */ +HWTEST_F(ReminderRequestCalendarTest, initDateTime_00400, Function | SmallTest | Level1) +{ + time_t now; + time(&now); // unit is seconds. + struct tm nowTime = *(localtime(&now)); + std::vector repeatMonths; + std::vector repeatDays; + repeatMonths.push_back(1); + repeatDays.push_back(1); + auto calendar = std::make_shared(nowTime, repeatMonths, repeatDays); + std::vector actualRepeatMonths = calendar->GetRepeatMonths(); + EXPECT_TRUE(ReminderRequestCalendarTest::IsVectorEqual(repeatMonths, actualRepeatMonths)) + << "Set repeat month with 1 error."; + + repeatMonths.clear(); + repeatMonths.push_back(12); + calendar = std::make_shared(nowTime, repeatMonths, repeatDays); + actualRepeatMonths = calendar->GetRepeatMonths(); + EXPECT_TRUE(ReminderRequestCalendarTest::IsVectorEqual(repeatMonths, actualRepeatMonths)) + << "Set repeat month with 12 error."; + + repeatMonths.clear(); + for (uint8_t i = 1; i <= 12; i++) { + repeatMonths.push_back(i); + } + calendar = std::make_shared(nowTime, repeatMonths, repeatDays); + actualRepeatMonths = calendar->GetRepeatMonths(); + EXPECT_TRUE(ReminderRequestCalendarTest::IsVectorEqual(repeatMonths, actualRepeatMonths)) + << "Set repeat month with 1~12 error."; +} + +/** + * @tc.number : initDateTime_00500 + * @tc.name : + * @tc.desc : Check repeatMonth set with exception value successfully. + */ +HWTEST_F(ReminderRequestCalendarTest, initDateTime_00500, Function | SmallTest | Level1) +{ + time_t now; + time(&now); // unit is seconds. + struct tm nowTime = *(localtime(&now)); + nowTime.tm_year += 1; + std::vector repeatMonths; + std::vector repeatDays; + repeatMonths.push_back(-1); + repeatDays.push_back(1); + auto calendar = std::make_shared(nowTime, repeatMonths, repeatDays); + std::vector actualRepeatMonths = calendar->GetRepeatMonths(); + EXPECT_TRUE(actualRepeatMonths.size() == 0) << "Set repeat month with -1 error."; + + repeatMonths.clear(); + repeatMonths.push_back(13); + calendar = std::make_shared(nowTime, repeatMonths, repeatDays); + actualRepeatMonths = calendar->GetRepeatMonths(); + EXPECT_TRUE(actualRepeatMonths.size() == 0) << "Set repeat month with 13 error."; + + for (uint8_t i = 1; i <= 12; i++) { + repeatMonths.push_back(i); + } + repeatMonths.push_back(1); + try { + auto calendar = std::make_shared(nowTime, repeatMonths, repeatDays); + EXPECT_TRUE(false) << "length of repeat month > 12 should throw exception."; + } catch (const std::invalid_argument &e) { + ANSR_LOGI("length of repeat month > 12 throw exception."); + } +} + +/** + * @tc.number : initDateTime_00600 + * @tc.name : + * @tc.desc : Check repeatDay set with nomal value successfully. + */ +HWTEST_F(ReminderRequestCalendarTest, initDateTime_00600, Function | SmallTest | Level1) +{ + time_t now; + time(&now); // unit is seconds. + struct tm nowTime = *(localtime(&now)); + std::vector repeatMonths; + std::vector repeatDays; + repeatMonths.push_back(1); + repeatDays.push_back(1); + auto calendar = std::make_shared(nowTime, repeatMonths, repeatDays); + std::vector actualRepeatDays = calendar->GetRepeatDays(); + EXPECT_TRUE(ReminderRequestCalendarTest::IsVectorEqual(repeatDays, actualRepeatDays)) + << "Set repeat day with 1 error."; + + repeatDays.clear(); + repeatDays.push_back(31); + calendar = std::make_shared(nowTime, repeatMonths, repeatDays); + actualRepeatDays = calendar->GetRepeatDays(); + EXPECT_TRUE(ReminderRequestCalendarTest::IsVectorEqual(repeatDays, actualRepeatDays)) + << "Set repeat day with 31 error."; + + repeatDays.clear(); + for (uint8_t i = 1; i <= 31; i++) { + repeatDays.push_back(i); + } + calendar = std::make_shared(nowTime, repeatMonths, repeatDays); + actualRepeatDays = calendar->GetRepeatDays(); + EXPECT_TRUE(ReminderRequestCalendarTest::IsVectorEqual(repeatDays, actualRepeatDays)) + << "Set repeat day with 1~31 error."; +} + +/** + * @tc.number : initDateTime_00700 + * @tc.name : + * @tc.desc : Check repeatDay set with exception value successfully. + */ +HWTEST_F(ReminderRequestCalendarTest, initDateTime_00700, Function | SmallTest | Level1) +{ + time_t now; + time(&now); // unit is seconds. + struct tm nowTime = *(localtime(&now)); + nowTime.tm_year += 1; + std::vector repeatMonths; + std::vector repeatDays; + repeatMonths.push_back(-1); + repeatDays.push_back(-1); + auto calendar = std::make_shared(nowTime, repeatMonths, repeatDays); + std::vector actualRepeatDays = calendar->GetRepeatDays(); + EXPECT_TRUE(actualRepeatDays.size() == 0) << "Set repeat day with -1 error."; + + repeatDays.clear(); + repeatDays.push_back(32); + calendar = std::make_shared(nowTime, repeatMonths, repeatDays); + actualRepeatDays = calendar->GetRepeatDays(); + EXPECT_TRUE(actualRepeatDays.size() == 0) << "Set repeat day with 32 error."; + + repeatDays.clear(); + for (uint8_t i = 1; i <= 31; i++) { + repeatDays.push_back(i); + } + repeatDays.push_back(1); + try { + calendar = std::make_shared(nowTime, repeatMonths, repeatDays); + ANSR_LOGI("length of repeat month > 32 should throw exception."); + } catch (const std::invalid_argument &e) { + ANSR_LOGI("length of repeat month > 32 throw exception."); + } +} + +/** + * @tc.number : initDateTime_00800 + * @tc.name : + * @tc.desc : Check hour set successfully. + */ +HWTEST_F(ReminderRequestCalendarTest, initDateTime_00800, Function | SmallTest | Level1) +{ + struct tm nowTime; + auto calendar = ReminderRequestCalendarTest::CreateCalendar(nowTime); + EXPECT_TRUE(1 == calendar->GetHour()) << "Set hour error."; +} + +/** + * @tc.number : initDateTime_00900 + * @tc.name : + * @tc.desc : Check minut set successfully. + */ +HWTEST_F(ReminderRequestCalendarTest, initDateTime_00900, Function | SmallTest | Level1) +{ + struct tm nowTime; + auto calendar = ReminderRequestCalendarTest::CreateCalendar(nowTime); + EXPECT_TRUE(1 == calendar->GetMinute()) << "Set minute error."; + EXPECT_TRUE(0 == calendar->GetSecond()) << "Set seconds error."; +} +} +} \ No newline at end of file diff --git a/frameworks/ans/native/test/unittest/reminder_request_test.cpp b/frameworks/ans/native/test/unittest/reminder_request_test.cpp index 0be99c939..1f189e9f5 100644 --- a/frameworks/ans/native/test/unittest/reminder_request_test.cpp +++ b/frameworks/ans/native/test/unittest/reminder_request_test.cpp @@ -56,7 +56,7 @@ HWTEST_F(ReminderRequestTest, CanRemove_00100, Function | SmallTest | Level1) HWTEST_F(ReminderRequestTest, CanRemove_00200, Function | SmallTest | Level1) { auto rrc = std::make_shared(); - rrc->OnShow(false, true); + rrc->OnShow(false, false, true); EXPECT_FALSE(rrc->CanRemove()) << "When shown, canRemove should be false"; } @@ -68,7 +68,7 @@ HWTEST_F(ReminderRequestTest, CanRemove_00200, Function | SmallTest | Level1) HWTEST_F(ReminderRequestTest, CanRemove_00300, Function | SmallTest | Level1) { auto rrc = std::make_shared(); - rrc->OnShow(false, true); + rrc->OnShow(false, false, true); rrc->OnClose(false); EXPECT_TRUE(rrc->CanRemove()) << "When reminder is expired and closed, can remove should be false"; } @@ -81,7 +81,7 @@ HWTEST_F(ReminderRequestTest, CanRemove_00300, Function | SmallTest | Level1) HWTEST_F(ReminderRequestTest, CanRemove_00400, Function | SmallTest | Level1) { auto rrc = std::make_shared(); - rrc->OnShow(false, true); + rrc->OnShow(false, false, true); rrc->OnSameNotificationIdCovered(); EXPECT_TRUE(rrc->CanRemove()) << "When reminder is expired and covered by \ sameNotification id, can remove should be true"; @@ -142,7 +142,7 @@ HWTEST_F(ReminderRequestTest, StateCheck_00400, Function | SmallTest | Level1) HWTEST_F(ReminderRequestTest, StateCheck_00500, Function | SmallTest | Level1) { auto rrc = std::make_shared(); - rrc->OnShow(true, true); + rrc->OnShow(false, true, true); EXPECT_TRUE((rrc->GetState() & ReminderRequestTest::REMINDER_STATUS_SHOWING) != 0); } @@ -154,7 +154,7 @@ HWTEST_F(ReminderRequestTest, StateCheck_00500, Function | SmallTest | Level1) HWTEST_F(ReminderRequestTest, StateCheck_00600, Function | SmallTest | Level1) { auto rrc = std::make_shared(); - rrc->OnShow(false, true); + rrc->OnShow(false, false, true); EXPECT_TRUE((rrc->GetState() & ReminderRequestTest::REMINDER_STATUS_SHOWING) != 0); } @@ -167,7 +167,7 @@ HWTEST_F(ReminderRequestTest, StateCheck_00700, Function | SmallTest | Level1) { auto rrc = std::make_shared(); uint8_t stateBefore = rrc->GetState(); - rrc->OnShow(true, false); + rrc->OnShow(false, true, false); EXPECT_EQ(rrc->GetState(), stateBefore); } @@ -180,7 +180,7 @@ HWTEST_F(ReminderRequestTest, StateCheck_00800, Function | SmallTest | Level1) { auto rrc = std::make_shared(); uint8_t stateBefore = rrc->GetState(); - rrc->OnShow(false, false); + rrc->OnShow(false, false, false); EXPECT_EQ(rrc->GetState(), stateBefore); } diff --git a/frameworks/ans/native/test/unittest/reminder_request_timer_test.cpp b/frameworks/ans/native/test/unittest/reminder_request_timer_test.cpp index 3bd1e48e7..6b39c09bf 100644 --- a/frameworks/ans/native/test/unittest/reminder_request_timer_test.cpp +++ b/frameworks/ans/native/test/unittest/reminder_request_timer_test.cpp @@ -44,7 +44,8 @@ public: HWTEST_F(ReminderRequestTimerTest, initCountDownTime_00100, Function | SmallTest | Level1) { try { - auto rrc = std::make_shared(0); + uint64_t countDownTimeInSeconds = 0; + auto rrc = std::make_shared(countDownTimeInSeconds); EXPECT_TRUE(false) << "countDownTime < 0 should throw exception."; } catch (const std::invalid_argument &e) { ANSR_LOGI("countDownTime < 0 throw exception."); @@ -74,13 +75,16 @@ HWTEST_F(ReminderRequestTimerTest, initCountDownTime_00200, Function | SmallTest */ HWTEST_F(ReminderRequestTimerTest, initCountDownTime_00300, Function | SmallTest | Level1) { - auto rrc = std::make_shared(1); + uint64_t countDownTimeInSeconds = 1; + auto rrc = std::make_shared(countDownTimeInSeconds); EXPECT_TRUE(rrc->GetInitInfo() == 1) << "countDownTime is not 1"; - auto rrc2 = std::make_shared(10); + countDownTimeInSeconds = 10; + auto rrc2 = std::make_shared(countDownTimeInSeconds); EXPECT_TRUE(rrc2->GetInitInfo() == 10) << "countDownTime is not 10"; - auto rrc3 = std::make_shared(100); + countDownTimeInSeconds = 100; + auto rrc3 = std::make_shared(countDownTimeInSeconds); EXPECT_TRUE(rrc3->GetInitInfo() == 100) << "countDownTime is not 1"; } } diff --git a/frameworks/ans/test/moduletest/BUILD.gn b/frameworks/ans/test/moduletest/BUILD.gn index 9c8579d91..2c117a4cf 100644 --- a/frameworks/ans/test/moduletest/BUILD.gn +++ b/frameworks/ans/test/moduletest/BUILD.gn @@ -346,5 +346,6 @@ group("moduletest") { ":ans_innerkits_module_publish_test", ":ans_innerkits_module_setting_test", ":ans_innerkits_module_slot_test", + ":ReminderAgentTest", ] } diff --git a/interfaces/innerkits/ans/native/include/reminder_request.h b/interfaces/innerkits/ans/native/include/reminder_request.h index 87445ac4c..65b4ff193 100644 --- a/interfaces/innerkits/ans/native/include/reminder_request.h +++ b/interfaces/innerkits/ans/native/include/reminder_request.h @@ -72,11 +72,21 @@ public: */ enum class UpdateNotificationType : uint8_t { COMMON, - ACTION_BUTTON, REMOVAL_WANT_AGENT, + WANT_AGENT, + MAX_SCREEN_WANT_AGENT, CONTENT }; + /** + * @brief Enumerates the Time type for converting between c time and acture time. + */ + enum class TimeTransferType : uint8_t { + YEAR, + MONTH, + WEEK + }; + /** * @brief Attributes of action button. */ @@ -100,6 +110,11 @@ public: std::string abilityName = ""; }; + struct MaxScreenAgentInfo { + std::string pkgName = ""; + std::string abilityName = ""; + }; + /** * @brief Copy construct from an exist reminder. * @@ -131,6 +146,8 @@ public: */ bool CanRemove(); + bool CanShow() const; + /** * @brief Obtains all the information of the reminder. * @@ -159,6 +176,8 @@ public: */ std::string GetExpiredContent() const; + std::shared_ptr GetMaxScreenWantAgentInfo() const; + /** * @brief Obtains notification id. * @@ -180,6 +199,8 @@ public: */ int32_t GetReminderId() const; + uint64_t GetReminderTimeInMilli() const; + /** * @brief Obtains reminder type. * @@ -187,6 +208,13 @@ public: */ ReminderType GetReminderType() const; + /** + * @brief Obtains the ringing or vibration duration configured for this reminder. + * + * @return uint16_t The ringing or vibration duration in seconds. + */ + uint16_t GetRingDuration() const; + /** * @brief Obtains slot type. * @@ -194,8 +222,18 @@ public: */ NotificationConstant::SlotType GetSlotType() const; + std::string GetSnoozeContent() const; + uint8_t GetSnoozeTimes() const; + uint8_t GetSnoozeTimesDynamic() const; uint8_t GetState() const; + /** + * @brief Obtains the Time Interval in seconds. + * + * @return uint64_t Time Interval in seconds. + */ + uint64_t GetTimeInterval() const; + /** * @brief Obtains title. * @@ -223,6 +261,13 @@ public: */ void InitReminderId(); + /** + * @brief Check the reminder is alerting or not. + * + * @return true if the reminder is playing sound or vibrating. + */ + bool IsAlerting() const; + /** * @brief Check the reminder is expired or not. * @@ -260,10 +305,16 @@ public: /** * @brief Show the reminder on panel. TriggerTime will be updated to next. * + * @param isPlaySoundOrVibration true means it is play sound or vibration. * @param isSysTimeChanged true means it is called when the system time is changed by user, otherwise false. * @param allowToNotify true means that the notification will be shown as normal, otherwise false. */ - void OnShow(bool isSysTimeChanged, bool allowToNotify); + void OnShow(bool isPlaySoundOrVibration, bool isSysTimeChanged, bool allowToNotify); + void OnShowFail(); + bool OnSnooze(); + void OnStart(); + void OnStop(); + bool OnTerminate(); /** * @brief When timezone change, reminder need to refresh next trigger time. @@ -304,6 +355,8 @@ public: */ ReminderRequest& SetExpiredContent(const std::string &expiredContent); + ReminderRequest& SetMaxScreenWantAgentInfo(const std::shared_ptr &maxScreenWantAgentInfo); + /** * @brief Sets notification id. * @@ -319,6 +372,16 @@ public: */ void SetReminderId(int32_t reminderId); + void SetReminderTimeInMilli(const uint64_t reminderTimeInMilli); + + /** + * @brief Sets the ringing or vibration duration for this reminder, in seconds. + * + * @param ringDurationInSeconds Indicates the duration. The defautl is 1 second. + * @return Current reminder self. + */ + ReminderRequest& SetRingDuration(const uint64_t ringDurationInSeconds); + /** * @brief Sets slot type. * @@ -327,6 +390,41 @@ public: */ ReminderRequest& SetSlotType(const NotificationConstant::SlotType &slotType); + ReminderRequest& SetSnoozeContent(const std::string &snoozeContent); + + /** + * @brief Set the number of snooze times for this reminder. + * + * @note If the value of snoozeTimes is less than or equals to 0, this reminder is a one-shot + * reminder and will not be snoozed. + * + * It the value of snoozeTimes is greater than 0, for example, snoozeTimes=3, this reminder + * will be snoozed three times after the first alarm, that is, this reminder will be triggered + * for four times. + * + * This method does not take affect on the reminders for countdown timers. + * + * @param snoozeTimes Indicates the number of times that the reminder will be snoozed. + * @return ReminderRequest& Current reminder self. + */ + ReminderRequest& SetSnoozeTimes(const uint8_t snoozeTimes); + + ReminderRequest& SetSnoozeTimesDynamic(const uint8_t snooziTimes); + + /** + * @brief Sets the Time Interval for this reminder, in seconds. The default value is 0. + * + * @note The minimum snooze interval is 5 minute. If the snooze interval is set to a value greater + * than 0 and less than 5 minutes, the system converts it to 5 minutes by default. + * + * This method does not take effect on the reminders for countdown timers. + * + * @param timeIntervalInSeconds Indicates the snooze interval to set. If the value is less or equals to 0, + * the reminder will not be snoozed. + * @return ReminderRequest& Current reminder self. + */ + ReminderRequest& SetTimeInterval(const uint64_t timeIntervalInSeconds); + /** * @brief Sets title. * @@ -350,6 +448,8 @@ public: */ ReminderRequest& SetWantAgentInfo(const std::shared_ptr &wantAgentInfo); + bool ShouldShowImmediately() const; + /** * @brief Updates {@link triggerTimeInMilli_} to next. * @note If next trigger time not exist, {@link isExpired_} flag will be set with true. @@ -371,7 +471,9 @@ public: void UpdateNotificationRequest(UpdateNotificationType type, std::string extra); static int32_t GLOBAL_ID; - static const uint64_t INVALID_LONG_VALUE; + static const uint64_t INVALID_LONG_LONG_VALUE; + static const uint16_t INVALID_U16_VALUE; + static const uint8_t INVALID_U8_VALUE; static const uint16_t MILLI_SECONDS; static const uint16_t SAME_TIME_DISTINGUISH_MILLISECONDS; static const std::string NOTIFICATION_LABEL; @@ -401,41 +503,80 @@ public: */ static const std::string REMINDER_EVENT_REMOVE_NOTIFICATION; static const std::string PARAM_REMINDER_ID; + static int GetActualTime(const TimeTransferType &type, int cTime); + static int GetCTime(const TimeTransferType &type, int actualTime); protected: ReminderRequest(); explicit ReminderRequest(ReminderType reminderType); - virtual uint64_t PreGetNextTriggerTimeIgnoreSnooze(bool forceToGetNext) const - { - return INVALID_LONG_VALUE; + std::string GetDateTimeInfo(const time_t &timeInSecond) const; + virtual uint64_t PreGetNextTriggerTimeIgnoreSnooze(bool ignoreRepeat, bool forceToGetNext) const { + return INVALID_LONG_LONG_VALUE; } + static const int BASE_YEAR; private: - void AddActionButtons(); + void AddActionButtons(const bool includeSnooze); void AddRemovalWantAgent(); + std::shared_ptr CreateWantAgent(AppExecFwk::ElementName &element) const; + uint64_t GetNowInstantMilli() const; + std::string GetShowTime(const uint64_t showTime) const; std::string GetState(const uint8_t state) const; bool HandleSysTimeChange(uint64_t oriTriggerTime, uint64_t optTriggerTime); bool HandleTimeZoneChange(uint64_t oldZoneTriggerTime, uint64_t newZoneTriggerTime, uint64_t optTriggerTime); void InitNotificationRequest(); + void SetMaxScreenWantAgent(AppExecFwk::ElementName &element); void SetState(bool deSet, const uint8_t newState, std::string function); - void SetWantAgent(); + void SetWantAgent(AppExecFwk::ElementName &element); + void UpdateActionButtons(const bool &setSnooze); + bool UpdateNextReminder(const bool &force); + void UpdateNotificationContent(const bool &setSnooze); void UpdateNotificationCommon(); + /** + * @brief Update the notification, which will be shown for the "Alerting" reminder. + * 1. Update the notification label/content. + * 2. Restore the snooze action button. + */ + void UpdateNotificationStateForAlert(); + + /** + * @brief Update the notification, which will be shown when user do a snooze. + * 1. Update the notification label/content. + * 2. Remove the snooze action button. + */ + void UpdateNotificationStateForSnooze(); + static const uint8_t REMINDER_STATUS_INACTIVE; + static const uint8_t REMINDER_STATUS_ACTIVE; + static const uint8_t REMINDER_STATUS_ALERTING; static const uint8_t REMINDER_STATUS_SHOWING; + static const uint8_t REMINDER_STATUS_SNOOZE; + static const uint32_t MIN_TIME_INTERVAL_IN_MILLI; std::string content_ {}; std::string expiredContent_ {}; + std::string snoozeContent_ {}; + std::string displayContent_ {}; std::string title_ {}; bool isExpired_ {false}; + uint8_t snoozeTimes_ {0}; + uint8_t snoozeTimesDynamic_ {0}; uint8_t state_ {0}; int32_t notificationId_ {0}; int32_t reminderId_ {-1}; + + // Indicates the reminder has been shown in the past time. + // When the reminder has been created but not showed, it is equals to 0. + uint64_t reminderTimeInMilli_ {0}; + uint64_t ringDurationInMilli_ {MILLI_SECONDS}; uint64_t triggerTimeInMilli_ {0}; + uint64_t timeIntervalInMilli_ {0}; ReminderType reminderType_ {ReminderType::INVALID}; NotificationConstant::SlotType slotType_ {NotificationConstant::SlotType::SOCIAL_COMMUNICATION}; sptr notificationRequest_ = nullptr; std::shared_ptr wantAgentInfo_ = nullptr; + std::shared_ptr maxScreenWantAgentInfo_ = nullptr; std::map actionButtonMap_ {}; }; } // namespace Reminder diff --git a/interfaces/innerkits/ans/native/include/reminder_request_alarm.h b/interfaces/innerkits/ans/native/include/reminder_request_alarm.h index e05550d84..5d7471eff 100644 --- a/interfaces/innerkits/ans/native/include/reminder_request_alarm.h +++ b/interfaces/innerkits/ans/native/include/reminder_request_alarm.h @@ -98,7 +98,7 @@ public: bool ReadFromParcel(Parcel &parcel) override; protected: - virtual uint64_t PreGetNextTriggerTimeIgnoreSnooze(bool forceToGetNext) const override; + virtual uint64_t PreGetNextTriggerTimeIgnoreSnooze(bool ignoreRepeat, bool forceToGetNext) const override; private: ReminderRequestAlarm() : ReminderRequest() {}; @@ -124,6 +124,7 @@ private: * @return true if it is a repeat day. */ bool IsRepeatDay(int day) const; + bool IsRepeatReminder() const; void SetDaysOfWeek(bool set, std::vector daysOfWeek); /** @@ -142,6 +143,7 @@ private: static const uint16_t SECONDS_PER_HOUR; static const uint8_t MINUTES_PER_HOUR; static const int8_t INVALID_INT_VALUE; + static const int8_t DEFAULT_SNOOZE_TIMES; uint8_t hour_ = {0}; uint8_t minute_ = {0}; diff --git a/interfaces/innerkits/ans/native/include/reminder_request_calendar.h b/interfaces/innerkits/ans/native/include/reminder_request_calendar.h new file mode 100644 index 000000000..a2b788cf7 --- /dev/null +++ b/interfaces/innerkits/ans/native/include/reminder_request_calendar.h @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef BASE_NOTIFICATION_ANS_STANDARD_FRAMEWORKS_ANS_CORE_INCLUDE_REMINDER_REQUEST_CALENDAR_H +#define BASE_NOTIFICATION_ANS_STANDARD_FRAMEWORKS_ANS_CORE_INCLUDE_REMINDER_REQUEST_CALENDAR_H + +#include "reminder_request.h" + +#include + +namespace OHOS { +namespace Notification { +class ReminderRequestCalendar : public ReminderRequest { +public: + /** + * @brief A {@link ReminderRequest} child class used for creating reminders of calendar clocks. + * + * @note The params must meet the following conditions. + * otherwise the application may crash due to an illegal parameter exception. + *
    + *
  • The length of repeatMonths vectory cannot exceed 12.
  • + *
  • The length of repeateDays vectory cannot exceed 31.
  • + *
  • There must be at least one valid reminder time. Ensure that the time specified by dateTime + * does not expired, or repeatMonths and repeateDays are valid.
  • + *
+ * + * The repeateMonths and repeatDays must both be set to implements repeated reminders. + * By default, this reminder is not snoozed. You can call {@link SetTimeInterval} to + * set the snooze interval. + * + * @param dateTime Indicates the date and time when this calendar event reminder will be triggered. + * The time is accurate to minute. For example, the value + * {@link LocalDateTime(2021, 3, 3, 16, 15)} indicates that the reminder will be + * triggered at 16:15 on March 3, 2021. + * @param repeatMonths Indicates the months in which this reminder will be repeated. For example, + * the value {2, 4} indicates that the reminder will be triggered on particular + * days in February and April. + * @param repeatDays Indicates the days in a month when this reminder will be repeated. For example, + * the value {2, 4} indicates that the reminder will be triggered on the second + * and fourth day of the specific months. + */ + ReminderRequestCalendar(const tm &dateTime, + const std::vector &repeatMonths, const std::vector &repeatDays); + + explicit ReminderRequestCalendar(const ReminderRequestCalendar &other); + ReminderRequestCalendar& operator = (const ReminderRequestCalendar &other); + ~ReminderRequestCalendar() {} + + inline uint16_t GetYear() const + { + return year_; + } + + inline uint8_t GetMonth() const + { + return month_; + } + + inline uint8_t GetDay() const + { + return day_; + } + + inline uint8_t GetHour() const + { + return hour_; + } + + inline uint8_t GetMinute() const + { + return minute_; + } + + inline uint8_t GetSecond() const + { + return second_; + } + + inline uint16_t GetFirstDesignateYear() const + { + return firstDesignateYear_; + } + + inline uint16_t GetFirstDesignageMonth() const + { + return firstDesignateMonth_; + } + + inline uint16_t GetFirstDesignateDay() const + { + return firstDesignateDay_; + } + + std::vector GetRepeatMonths() const; + std::vector GetRepeatDays() const; + + virtual bool OnDateTimeChange() override; + virtual bool OnTimeZoneChange() override; + virtual bool UpdateNextReminder() override; + + /** + * Marshal a reminder object into a Parcel. + * + * @param parcel Indicates the Parcel. + */ + virtual bool Marshalling(Parcel &parcel) const override; + + /** + * Unmarshal object from a Parcel. + * + * @param parcel Indicates the Parcel. + * @return reminder object. + */ + static ReminderRequestCalendar *Unmarshalling(Parcel &parcel); + + /** + * Unmarshal unique properties of alarm from a Parcel. + * + * @param parcel Indicates the Parcel. + * @return true if read parcel success. + */ + bool ReadFromParcel(Parcel &parcel) override; + + static const uint8_t MAX_MONTHS_OF_YEAR; + static const uint8_t MAX_DAYS_OF_MONTH; + +protected: + virtual uint64_t PreGetNextTriggerTimeIgnoreSnooze(bool ignoreRepeat, bool forceToGetNext) const override; + +private: + ReminderRequestCalendar() : ReminderRequest() {} + + uint8_t GetDaysOfMonth(const uint16_t &year, const uint8_t &month) const; + uint8_t GetNextDay(const uint16_t &settedYear, const uint8_t &settedMonth, const tm &now, const tm &target) const; + uint64_t GetNextTriggerTime() const; + uint64_t GetNextTriggerTimeAsRepeatReminder(const tm &nowTime, const tm &tarTime) const; + uint64_t GetTimeInstantMilli( + uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second) const; + + /** + * @brief Init dateTime_ when read from parcel. + */ + void InitDateTime(); + void InitDateTime(const tm &dateTime); + bool IsRepeatReminder() const; + bool IsRepeatMonth(uint8_t month) const; + bool IsRepeatDay(uint8_t day) const; + void SetDay(const uint8_t &day, const bool &isSet); + void SetMonth(const uint8_t &month, const bool &isSet); + void SetRepeatMonths(const std::vector &repeatMonths); + void SetRepeatDaysOfMonth(const std::vector &repeateDays); + + static const uint8_t JANUARY; + static const uint8_t DECEMBER; + static const uint8_t DEFAULT_SNOOZE_TIMES; + + tm dateTime_; + uint16_t firstDesignateYear_ {1}; + uint8_t firstDesignateMonth_ {1}; + uint8_t firstDesignateDay_ {1}; + uint16_t year_ {1}; + uint8_t month_ {1}; + uint8_t day_ {1}; + uint8_t hour_ {1}; + uint8_t minute_ {1}; + uint8_t second_ {0}; + uint16_t repeatMonth_; + uint32_t repeatDay_; +}; +} +} +#endif // BASE_NOTIFICATION_ANS_STANDARD_FRAMEWORKS_ANS_CORE_INCLUDE_REMINDER_REQUEST_CALENDAR_H \ No newline at end of file diff --git a/interfaces/innerkits/ans/native/include/reminder_request_timer.h b/interfaces/innerkits/ans/native/include/reminder_request_timer.h index 03705509c..a33c0142e 100644 --- a/interfaces/innerkits/ans/native/include/reminder_request_timer.h +++ b/interfaces/innerkits/ans/native/include/reminder_request_timer.h @@ -62,7 +62,7 @@ public: bool ReadFromParcel(Parcel &parcel) override; protected: - virtual uint64_t PreGetNextTriggerTimeIgnoreSnooze(bool forceToGetNext) const override; + virtual uint64_t PreGetNextTriggerTimeIgnoreSnooze(bool ignoreRepeat, bool forceToGetNext) const override; private: ReminderRequestTimer() {}; diff --git a/interfaces/kits/napi/ans/include/reminder/reminder_common.h b/interfaces/kits/napi/ans/include/reminder/reminder_common.h index 0f9b9e057..63b1d0f79 100644 --- a/interfaces/kits/napi/ans/include/reminder/reminder_common.h +++ b/interfaces/kits/napi/ans/include/reminder/reminder_common.h @@ -26,22 +26,38 @@ namespace ReminderAgentNapi { using namespace OHOS::Notification; namespace { -const char* REMINDER_TYPE = "reminderType"; -const char* ALARM_HOUR = "hour"; -const char* ALARM_MINUTE = "minute"; -const char* ALARM_DAYS_OF_WEEK = "daysOfWeek"; -const char* TIMER_COUNT_DOWN_TIME = "triggerTimeInSeconds"; const char* ACTION_BUTTON = "actionButton"; const char* ACTION_BUTTON_TITLE = "title"; const char* ACTION_BUTTON_TYPE = "type"; -const char* WANT_AGENT = "wantAgent"; -const char* WANT_AGENT_PKG = "pkgName"; -const char* WANT_AGENT_ABILITY = "abilityName"; -const char* TITLE = "title"; +const char* ALARM_HOUR = "hour"; +const char* ALARM_DAYS_OF_WEEK = "daysOfWeek"; +const char* ALARM_MINUTE = "minute"; +const char* CALENDAR_DATE_TIME = "dateTime"; +const char* CALENDAR_YEAR = "year"; +const char* CALENDAR_MONTH = "month"; +const char* CALENDAR_DAY = "day"; +const char* CALENDAR_HOUR = "hour"; +const char* CALENDAR_MINUTE = "minute"; +const char* CALENDAR_SECOND = "second"; +const char* CALENDAR_REPEAT_MONTHS = "repeatMonths"; +const char* CALENDAR_REPEAT_DAYS = "repeatDays"; const char* CONTENT = "content"; const char* EXPIRED_CONTENT = "expiredContent"; +const char* MAX_SCREEN_WANT_AGENT = "maxScreenWantAgent"; +const char* MAX_SCREEN_WANT_AGENT_PKG = "pkgName"; +const char* MAX_SCREEN_WANT_AGENT_ABILITY = "abilityName"; const char* NOTIFICATION_ID = "notificationId"; +const char* REMINDER_TYPE = "reminderType"; +const char* RING_DURATION = "ringDuration"; const char* SLOT_TYPE = "slotType"; +const char* SNOOZE_CONTENT = "snoozeContent"; +const char* SNOOZE_TIMES = "snoozeTimes"; +const char* TIME_INTERVAL = "timeInterval"; +const char* TITLE = "title"; +const char* TIMER_COUNT_DOWN_TIME = "triggerTimeInSeconds"; +const char* WANT_AGENT = "wantAgent"; +const char* WANT_AGENT_PKG = "pkgName"; +const char* WANT_AGENT_ABILITY = "abilityName"; } class ReminderCommon { @@ -58,7 +74,7 @@ public: const char* propertyName, char* propertyVal, const int32_t size); static bool GetInt32(const napi_env &env, const napi_value &value, - const char* propertyName, int32_t& propertyVal); + const char* propertyName, int32_t& propertyVal, bool isNecessary); static bool GetInt64(const napi_env &env, const napi_value &value, const char* propertyName, int64_t& propertyVal); @@ -67,8 +83,20 @@ public: const char* propertyName, napi_value& propertyVal); private: - static bool CreateReminder(const napi_env &env, const napi_value &value, - const int32_t &reminderType, std::shared_ptr& reminder); + static bool CheckCalendarParams(const int32_t &year, const int32_t &month, const int32_t &day, + const int32_t &hour, const int32_t &min); + + static napi_value CreateReminderTimer( + const napi_env &env, const napi_value &value, std::shared_ptr& reminder); + + static napi_value CreateReminderAlarm( + const napi_env &env, const napi_value &value, std::shared_ptr& reminder); + + static napi_value CreateReminderCalendar( + const napi_env &env, const napi_value &value, std::shared_ptr& reminder); + + static bool CreateReminder( + const napi_env &env, const napi_value &value, std::shared_ptr& reminder); static bool GetPropertyValIfExist(const napi_env &env, const napi_value &value, const char* propertyName, napi_value& propertyVal); @@ -76,20 +104,17 @@ private: static void GenWantAgent( const napi_env &env, const napi_value &value, std::shared_ptr& reminder); - static bool GenActionButtons( - const napi_env &env, const napi_value &value, std::shared_ptr& reminder); - - static napi_value GenReminder( + static void GenMaxScreenWantAgent( const napi_env &env, const napi_value &value, std::shared_ptr& reminder); - static napi_value CreateReminderTimer( + static bool GenActionButtons( const napi_env &env, const napi_value &value, std::shared_ptr& reminder); - static napi_value CreateReminderAlarm( + static napi_value GenReminder( const napi_env &env, const napi_value &value, std::shared_ptr& reminder); - static napi_value ParseDaysOfWeek( - const napi_env &env, const napi_value &value, std::vector &daysOfWeek); + static napi_value ParseInt32Array(const napi_env &env, const napi_value &value, + const char* propertyName, std::vector &propertyVal, uint8_t maxLen); }; } // namespace OHOS } // namespace ReminderAgentNapi diff --git a/interfaces/kits/napi/ans/src/reminder/native_module.cpp b/interfaces/kits/napi/ans/src/reminder/native_module.cpp index 386a92f3c..f4fe3650b 100644 --- a/interfaces/kits/napi/ans/src/reminder/native_module.cpp +++ b/interfaces/kits/napi/ans/src/reminder/native_module.cpp @@ -51,12 +51,18 @@ napi_value ConstantInit(napi_env env, napi_value exports) if (napi_create_int32(env, static_cast(ReminderRequest::ReminderType::ALARM), &prop) == napi_ok) { napi_set_named_property(env, objReminderType, "REMINDER_TYPE_ALARM", prop); } + if (napi_create_int32(env, static_cast(ReminderRequest::ReminderType::CALENDAR), &prop) == napi_ok) { + napi_set_named_property(env, objReminderType, "REMINDER_TYPE_CALENDAR", prop); + } napi_value objButtonType = nullptr; napi_create_object(env, &objButtonType); if (napi_create_int32(env, static_cast(ReminderRequest::ActionButtonType::CLOSE), &prop) == napi_ok) { napi_set_named_property(env, objButtonType, "ACTION_BUTTON_TYPE_CLOSE", prop); } + if (napi_create_int32(env, static_cast(ReminderRequest::ActionButtonType::SNOOZE), &prop) == napi_ok) { + napi_set_named_property(env, objButtonType, "ACTION_BUTTON_TYPE_SNOOZE", prop); + } napi_property_descriptor exportFuncs[] = { DECLARE_NAPI_PROPERTY("ReminderType", objReminderType), diff --git a/interfaces/kits/napi/ans/src/reminder/publish.cpp b/interfaces/kits/napi/ans/src/reminder/publish.cpp index 699925f0c..2f792d959 100644 --- a/interfaces/kits/napi/ans/src/reminder/publish.cpp +++ b/interfaces/kits/napi/ans/src/reminder/publish.cpp @@ -16,6 +16,7 @@ #include "ans_log_wrapper.h" #include "common.h" #include "reminder_request_alarm.h" +#include "reminder_request_calendar.h" #include "reminder_request_timer.h" #include "reminder/publish.h" @@ -105,8 +106,7 @@ napi_value ParseCanCelParameter(const napi_env &env, const napi_callback_info &i // argv[0]: reminder id int32_t reminderId = -1; - if (!ReminderCommon::GetInt32(env, argv[0], nullptr, reminderId)) { - ANSR_LOGW("Param id of cancels Reminder should be a number."); + if (!ReminderCommon::GetInt32(env, argv[0], nullptr, reminderId, true)) { return nullptr; } if (reminderId < 0) { @@ -279,42 +279,99 @@ napi_value CancelAllReminders(napi_env env, napi_callback_info info) } } +void ParseReminderTimer(const napi_env &env, ReminderRequest &reminder, napi_value &result) +{ + napi_value value = nullptr; + ReminderRequestTimer& timer = (ReminderRequestTimer&)reminder; + napi_create_uint32(env, timer.GetInitInfo(), &value); + napi_set_named_property(env, result, TIMER_COUNT_DOWN_TIME, value); +} + +void ParseReminderAlarm(const napi_env &env, ReminderRequest &reminder, napi_value &result) +{ + // hour + napi_value value = nullptr; + ReminderRequestAlarm& alarm = (ReminderRequestAlarm&)reminder; + napi_create_uint32(env, static_cast(alarm.GetHour()), &value); + napi_set_named_property(env, result, ALARM_HOUR, value); + + // minute + napi_create_uint32(env, static_cast(alarm.GetMinute()), &value); + napi_set_named_property(env, result, ALARM_MINUTE, value); + + // daysOfWeek + napi_create_array(env, &value); + napi_set_named_property(env, result, ALARM_DAYS_OF_WEEK, value); + int count = 0; + for (auto day : alarm.GetDaysOfWeek()) { + if (day) { + napi_value napiDay = nullptr; + napi_create_int32(env, day, &napiDay); + napi_set_element(env, value, count, napiDay); + count++; + } + } +} + +void ParseReminderCalendar(const napi_env &env, ReminderRequest &reminder, napi_value &result) +{ + // dateTime + napi_value value = nullptr; + ReminderRequestCalendar& calender = (ReminderRequestCalendar&)reminder; + napi_value dateTime = nullptr; + napi_create_object(env, &dateTime); + napi_set_named_property(env, result, CALENDAR_DATE_TIME, dateTime); + + napi_create_uint32(env, static_cast(calender.GetYear()), &value); + napi_set_named_property(env, dateTime, CALENDAR_YEAR, value); + napi_create_uint32(env, static_cast(calender.GetMonth()), &value); + napi_set_named_property(env, dateTime, CALENDAR_MONTH, value); + napi_create_uint32(env, static_cast(calender.GetDay()), &value); + napi_set_named_property(env, dateTime, CALENDAR_DAY, value); + napi_create_uint32(env, static_cast(calender.GetHour()), &value); + napi_set_named_property(env, dateTime, CALENDAR_HOUR, value); + napi_create_uint32(env, static_cast(calender.GetMinute()), &value); + napi_set_named_property(env, dateTime, CALENDAR_MINUTE, value); + napi_create_uint32(env, static_cast(calender.GetSecond()), &value); + napi_set_named_property(env, dateTime, CALENDAR_SECOND, value); + + // repeatMonths + napi_create_array(env, &value); + napi_set_named_property(env, result, CALENDAR_REPEAT_MONTHS, value); + int count = 0; + for (auto month : calender.GetRepeatMonths()) { + napi_value napiDay = nullptr; + napi_create_int32(env, month, &napiDay); + napi_set_element(env, value, count, napiDay); + count++; + } + + // repeatDays + napi_create_array(env, &value); + napi_set_named_property(env, result, CALENDAR_REPEAT_DAYS, value); + count = 0; + for (auto day : calender.GetRepeatDays()) { + napi_value napiDay = nullptr; + napi_create_int32(env, day, &napiDay); + napi_set_element(env, value, count, napiDay); + count++; + } +} + void ParseReminder( const napi_env &env, ReminderRequest::ReminderType &type, ReminderRequest &reminder, napi_value &result) { - napi_value value = nullptr; switch (type) { case ReminderRequest::ReminderType::TIMER: { - ReminderRequestTimer& timer = (ReminderRequestTimer&)reminder; - napi_create_uint32(env, timer.GetInitInfo(), &value); - napi_set_named_property(env, result, TIMER_COUNT_DOWN_TIME, value); + ParseReminderTimer(env, reminder, result); break; } case ReminderRequest::ReminderType::ALARM: { - ANSR_LOGD("Parse alarm info"); - - // hour - ReminderRequestAlarm& alarm = (ReminderRequestAlarm&)reminder; - napi_create_uint32(env, static_cast(alarm.GetHour()), &value); - - // minute - napi_set_named_property(env, result, ALARM_HOUR, value); - napi_create_uint32(env, static_cast(alarm.GetMinute()), &value); - napi_set_named_property(env, result, ALARM_MINUTE, value); - - // daysOfWeek - napi_create_array(env, &value); - napi_set_named_property(env, result, ALARM_DAYS_OF_WEEK, value); - int count = 0; - for (auto day : alarm.GetDaysOfWeek()) { - if (day) { - napi_value napiDay = nullptr; - napi_create_int32(env, day, &napiDay); - napi_set_element(env, value, count, napiDay); - count++; - } - } - ANSR_LOGD("Parse alarm info end"); + ParseReminderAlarm(env, reminder, result); + break; + } + case ReminderRequest::ReminderType::CALENDAR: { + ParseReminderCalendar(env, reminder, result); break; } default: { @@ -334,6 +391,7 @@ void ParseActionButtons(const napi_env &env, ReminderRequest &reminder, napi_val int index = 0; for (std::map::iterator it = actionButtonsMap.begin(); it != actionButtonsMap.end(); ++it) { + // create obj napi_value actionButton = nullptr; napi_create_object(env, &actionButton); @@ -364,6 +422,20 @@ void ParseWantAgent(const napi_env &env, ReminderRequest &reminder, napi_value & napi_set_named_property(env, wantAgentInfo, WANT_AGENT_ABILITY, info); } +void ParseMaxScreenWantAgent(const napi_env &env, ReminderRequest &reminder, napi_value &result) +{ + // create obj + napi_value maxScreenWantAgentInfo = nullptr; + napi_create_object(env, &maxScreenWantAgentInfo); + napi_set_named_property(env, result, MAX_SCREEN_WANT_AGENT, maxScreenWantAgentInfo); + + napi_value info = nullptr; + napi_create_string_utf8(env, (reminder.GetMaxScreenWantAgentInfo()->pkgName).c_str(), NAPI_AUTO_LENGTH, &info); + napi_set_named_property(env, maxScreenWantAgentInfo, MAX_SCREEN_WANT_AGENT_PKG, info); + napi_create_string_utf8(env, (reminder.GetMaxScreenWantAgentInfo()->abilityName).c_str(), NAPI_AUTO_LENGTH, &info); + napi_set_named_property(env, maxScreenWantAgentInfo, MAX_SCREEN_WANT_AGENT_ABILITY, info); +} + napi_value SetValidReminder(const napi_env &env, ReminderRequest &reminder, napi_value &result) { ANSR_LOGI("enter"); @@ -392,10 +464,26 @@ napi_value SetValidReminder(const napi_env &env, ReminderRequest &reminder, napi napi_create_string_utf8(env, reminder.GetExpiredContent().c_str(), NAPI_AUTO_LENGTH, &value); napi_set_named_property(env, result, EXPIRED_CONTENT, value); + // snoozeContent + napi_create_string_utf8(env, reminder.GetSnoozeContent().c_str(), NAPI_AUTO_LENGTH, &value); + napi_set_named_property(env, result, SNOOZE_CONTENT, value); + + // ringDuration + napi_create_int64(env, reminder.GetRingDuration(), &value); + napi_set_named_property(env, result, RING_DURATION, value); + + // timeInterval + napi_create_int64(env, reminder.GetTimeInterval(), &value); + napi_set_named_property(env, result, TIME_INTERVAL, value); + // notificationId napi_create_int32(env, reminder.GetNotificationId(), &value); napi_set_named_property(env, result, NOTIFICATION_ID, value); + // snoozeTimes + napi_create_int32(env, reminder.GetSnoozeTimes(), &value); + napi_set_named_property(env, result, SNOOZE_TIMES, value); + // slotType NotificationNapi::SlotType jsSlotType; NotificationNapi::Common::SlotTypeCToJS(reminder.GetSlotType(), jsSlotType); @@ -405,9 +493,11 @@ napi_value SetValidReminder(const napi_env &env, ReminderRequest &reminder, napi // wantAgent ParseWantAgent(env, reminder, result); + // maxScreenWantAgent + ParseMaxScreenWantAgent(env, reminder, result); + // actionButtons ParseActionButtons(env, reminder, result); - return NotificationNapi::Common::NapiGetBoolean(env, true); } diff --git a/interfaces/kits/napi/ans/src/reminder/reminder_common.cpp b/interfaces/kits/napi/ans/src/reminder/reminder_common.cpp index 7b60e4780..4bf5d4985 100644 --- a/interfaces/kits/napi/ans/src/reminder/reminder_common.cpp +++ b/interfaces/kits/napi/ans/src/reminder/reminder_common.cpp @@ -16,6 +16,7 @@ #include "ans_log_wrapper.h" #include "common.h" #include "reminder_request_alarm.h" +#include "reminder_request_calendar.h" #include "reminder_request_timer.h" #include "reminder/reminder_common.h" @@ -30,7 +31,7 @@ napi_value ReminderCommon::GetReminderRequest( napi_valuetype valuetype = napi_undefined; NAPI_CALL(env, napi_typeof(env, value, &valuetype)); if (valuetype != napi_object) { - ANSR_LOGE("Wrong argument type. Object expected."); + ANSR_LOGW("Wrong argument type. Object expected."); return nullptr; } @@ -53,7 +54,7 @@ bool ReminderCommon::GenActionButtons( bool isArray = false; napi_is_array(env, actionButtons, &isArray); if (!isArray) { - ANSR_LOGE("Wrong argument type:%{public}s. array expected.", ACTION_BUTTON); + ANSR_LOGW("Wrong argument type:%{public}s. array expected.", ACTION_BUTTON); return false; } @@ -64,15 +65,16 @@ bool ReminderCommon::GenActionButtons( napi_get_element(env, actionButtons, i, &actionButton); NAPI_CALL(env, napi_typeof(env, actionButton, &valuetype)); if (valuetype != napi_object) { - ANSR_LOGE("Wrong element type:%{public}s. object expected.", ACTION_BUTTON); + ANSR_LOGW("Wrong element type:%{public}s. object expected.", ACTION_BUTTON); return false; } int32_t buttonType = static_cast(ReminderRequest::ActionButtonType::INVALID); if (GetStringUtf8(env, actionButton, ReminderAgentNapi::ACTION_BUTTON_TITLE, str, NotificationNapi::STR_MAX_SIZE) && - GetInt32(env, actionButton, ReminderAgentNapi::ACTION_BUTTON_TYPE, buttonType)) { - if (ReminderRequest::ActionButtonType(buttonType) != ReminderRequest::ActionButtonType::CLOSE) { + GetInt32(env, actionButton, ReminderAgentNapi::ACTION_BUTTON_TYPE, buttonType, false)) { + if (ReminderRequest::ActionButtonType(buttonType) != ReminderRequest::ActionButtonType::CLOSE && + ReminderRequest::ActionButtonType(buttonType) != ReminderRequest::ActionButtonType::SNOOZE) { ANSR_LOGW("Wrong argument type:%{public}s. buttonType not support.", ACTION_BUTTON); return false; } @@ -105,9 +107,32 @@ void ReminderCommon::GenWantAgent( } } -bool ReminderCommon::CreateReminder(const napi_env &env, const napi_value &value, - const int32_t &reminderType, std::shared_ptr& reminder) +void ReminderCommon::GenMaxScreenWantAgent( + const napi_env &env, const napi_value &value, std::shared_ptr& reminder) +{ + char str[NotificationNapi::STR_MAX_SIZE] = {0}; + napi_value maxScreenWantAgent = nullptr; + if (GetObject(env, value, ReminderAgentNapi::MAX_SCREEN_WANT_AGENT, maxScreenWantAgent)) { + std::shared_ptr maxScreenWantAgentInfo( + new ReminderRequest::MaxScreenAgentInfo()); + if (GetStringUtf8(env, maxScreenWantAgent, + ReminderAgentNapi::MAX_SCREEN_WANT_AGENT_PKG, str, NotificationNapi::STR_MAX_SIZE)) { + maxScreenWantAgentInfo->pkgName = str; + } + if (GetStringUtf8(env, maxScreenWantAgent, + ReminderAgentNapi::MAX_SCREEN_WANT_AGENT_ABILITY, str, NotificationNapi::STR_MAX_SIZE)) { + maxScreenWantAgentInfo->abilityName = str; + } + reminder->SetMaxScreenWantAgentInfo(maxScreenWantAgentInfo); + } +} +bool ReminderCommon::CreateReminder( + const napi_env &env, const napi_value &value, std::shared_ptr& reminder) { + napi_value result = nullptr; + napi_get_named_property(env, value, ReminderAgentNapi::REMINDER_TYPE, &result); + int32_t reminderType = -1; + napi_get_value_int32(env, result, &reminderType); switch (ReminderRequest::ReminderType(reminderType)) { case ReminderRequest::ReminderType::TIMER: CreateReminderTimer(env, value, reminder); @@ -115,8 +140,11 @@ bool ReminderCommon::CreateReminder(const napi_env &env, const napi_value &value case ReminderRequest::ReminderType::ALARM: CreateReminderAlarm(env, value, reminder); break; + case ReminderRequest::ReminderType::CALENDAR: + CreateReminderCalendar(env, value, reminder); + break; default: - ANSR_LOGW("Reminder type is not support."); + ANSR_LOGW("Reminder type is not support. (type:%{public}d)", reminderType); break; } if (reminder == nullptr) { @@ -133,16 +161,12 @@ napi_value ReminderCommon::GenReminder( bool hasProperty = false; NAPI_CALL(env, napi_has_named_property(env, value, ReminderAgentNapi::REMINDER_TYPE, &hasProperty)); if (!hasProperty) { - ANSR_LOGE("Property %{public}s expected.", ReminderAgentNapi::REMINDER_TYPE); + ANSR_LOGW("Property %{public}s expected.", ReminderAgentNapi::REMINDER_TYPE); return nullptr; } - napi_value result = nullptr; - napi_get_named_property(env, value, ReminderAgentNapi::REMINDER_TYPE, &result); - int32_t propertyVal = -1; - napi_get_value_int32(env, result, &propertyVal); // createReminder - if (!CreateReminder(env, value, propertyVal, reminder)) { + if (!CreateReminder(env, value, reminder)) { return nullptr; } char str[NotificationNapi::STR_MAX_SIZE] = {0}; @@ -162,14 +186,51 @@ napi_value ReminderCommon::GenReminder( reminder->SetExpiredContent(str); } + // snoozeContent + if (GetStringUtf8(env, value, ReminderAgentNapi::SNOOZE_CONTENT, str, NotificationNapi::STR_MAX_SIZE)) { + reminder->SetSnoozeContent(str); + } + + // ringDuration + int64_t propVal = 0; + if (GetInt64(env, value, ReminderAgentNapi::RING_DURATION, propVal)) { + if (propVal < 0) { + reminder->SetRingDuration(0); + } else { + uint64_t ringDuration = static_cast(propVal); + reminder->SetRingDuration(ringDuration); + } + } + + // timeInterval + if (GetInt64(env, value, ReminderAgentNapi::TIME_INTERVAL, propVal)) { + if (propVal < 0) { + reminder->SetTimeInterval(0); + } else { + uint64_t timeInterval = static_cast(propVal); + reminder->SetTimeInterval(timeInterval); + } + } + // notificationId - if (GetInt32(env, value, ReminderAgentNapi::NOTIFICATION_ID, propertyVal)) { + int32_t propertyVal = 0; + if (GetInt32(env, value, ReminderAgentNapi::NOTIFICATION_ID, propertyVal, false)) { reminder->SetNotificationId(propertyVal); } + // snoozeTimes + if (GetInt32(env, value, ReminderAgentNapi::SNOOZE_TIMES, propertyVal, false)) { + if (propertyVal < 0) { + reminder->SetSnoozeTimes(0); + } else { + uint8_t snoozeTimes = propertyVal > UINT8_MAX ? UINT8_MAX : propertyVal; + reminder->SetSnoozeTimes(static_cast(snoozeTimes)); + } + } + // slotType int32_t slotType = 0; - if (GetInt32(env, value, ReminderAgentNapi::SLOT_TYPE, slotType)) { + if (GetInt32(env, value, ReminderAgentNapi::SLOT_TYPE, slotType, false)) { enum NotificationConstant::SlotType actureType = NotificationConstant::SlotType::OTHER; if (!NotificationNapi::Common::SlotTypeJSToC(NotificationNapi::SlotType(slotType), actureType)) { ANSR_LOGW("slot type not support."); @@ -181,6 +242,9 @@ napi_value ReminderCommon::GenReminder( // wantAgent GenWantAgent(env, value, reminder); + // maxScreenWantAgent + GenMaxScreenWantAgent(env, value, reminder); + // actionButtons if (!GenActionButtons(env, value, reminder)) { return nullptr; @@ -201,7 +265,7 @@ bool ReminderCommon::GetStringUtf8(const napi_env &env, const napi_value &value, napi_get_named_property(env, value, propertyName, &result); NAPI_CALL(env, napi_typeof(env, result, &valuetype)); if (valuetype != napi_string) { - ANSR_LOGE("Wrong argument type:%{public}s. string expected.", propertyName); + ANSR_LOGW("Wrong argument type:%{public}s. string expected.", propertyName); return false; } NAPI_CALL(env, napi_get_value_string_utf8(env, result, propertyVal, size - 1, &strLen)); @@ -210,10 +274,13 @@ bool ReminderCommon::GetStringUtf8(const napi_env &env, const napi_value &value, } bool ReminderCommon::GetInt32(const napi_env &env, const napi_value &value, - const char* propertyName, int32_t& propertyVal) + const char* propertyName, int32_t& propertyVal, bool isNecessary) { napi_value result = nullptr; if (!GetPropertyValIfExist(env, value, propertyName, result)) { + if (isNecessary) { + ANSR_LOGW("Correct property %{public}s expected.", propertyName); + } return false; } napi_get_value_int32(env, result, &propertyVal); @@ -270,7 +337,7 @@ bool ReminderCommon::GetObject(const napi_env &env, const napi_value &value, napi_get_named_property(env, value, propertyName, &propertyVal); NAPI_CALL(env, napi_typeof(env, propertyVal, &valuetype)); if (valuetype != napi_object) { - ANSR_LOGE("Wrong argument type:%{public}s. object expected.", propertyName); + ANSR_LOGW("Wrong argument type:%{public}s. object expected.", propertyName); return false; } return true; @@ -281,14 +348,13 @@ napi_value ReminderCommon::CreateReminderTimer( { int64_t propertyCountDownTime = 0; if (!GetInt64(env, value, ReminderAgentNapi::TIMER_COUNT_DOWN_TIME, propertyCountDownTime)) { - ANSR_LOGE("Correct property %{public}s expected.", ReminderAgentNapi::TIMER_COUNT_DOWN_TIME); + ANSR_LOGW("Correct property %{public}s expected.", ReminderAgentNapi::TIMER_COUNT_DOWN_TIME); return nullptr; } - if (propertyCountDownTime <= 0 || - propertyCountDownTime > static_cast((UINT64_MAX / ReminderRequest::MILLI_SECONDS))) { - ANSR_LOGE("Property %{public}s must between (0, %{public}llu).", - ReminderAgentNapi::ALARM_MINUTE, (unsigned long long)(UINT64_MAX / ReminderRequest::MILLI_SECONDS)); + if (propertyCountDownTime <= 0) { + ANSR_LOGW("Create countDown reminder fail: designated %{public}s should be set larger than 0.", + ReminderAgentNapi::TIMER_COUNT_DOWN_TIME); return nullptr; } @@ -301,54 +367,128 @@ napi_value ReminderCommon::CreateReminderAlarm( { // hour int32_t propertyHourVal = 0; - if (!GetInt32(env, value, ReminderAgentNapi::ALARM_HOUR, propertyHourVal)) { - ANSR_LOGE("Correct property %{public}s expected.", ReminderAgentNapi::ALARM_HOUR); + if (!GetInt32(env, value, ReminderAgentNapi::ALARM_HOUR, propertyHourVal, true)) { return nullptr; } // minute int32_t propertyMinuteVal = 0; - if (!GetInt32(env, value, ReminderAgentNapi::ALARM_MINUTE, propertyMinuteVal)) { - ANSR_LOGE("Correct property %{public}s expected.", ReminderAgentNapi::ALARM_MINUTE); + if (!GetInt32(env, value, ReminderAgentNapi::ALARM_MINUTE, propertyMinuteVal, true)) { return nullptr; } if (propertyHourVal < 0 || propertyHourVal > 23) { - ANSR_LOGE("Property %{public}s must between [0, 23].", ReminderAgentNapi::ALARM_HOUR); + ANSR_LOGW("Create alarm reminder fail: designated %{public}s must between [0, 23].", + ReminderAgentNapi::ALARM_HOUR); return nullptr; } if (propertyMinuteVal < 0 || propertyMinuteVal > 59) { - ANSR_LOGE("Property %{public}s must between [0, 59].", ReminderAgentNapi::ALARM_MINUTE); + ANSR_LOGW("Create alarm reminder fail: designated %{public}s must between [0, 59].", + ReminderAgentNapi::ALARM_MINUTE); return nullptr; } // daysOfWeek std::vector daysOfWeek; - ParseDaysOfWeek(env, value, daysOfWeek); + uint8_t maxDaysOfWeek = 7; + if (ParseInt32Array(env, value, ReminderAgentNapi::ALARM_DAYS_OF_WEEK, daysOfWeek, maxDaysOfWeek) == nullptr) { + return nullptr; + } reminder = std::make_shared( static_cast(propertyHourVal), static_cast(propertyMinuteVal), daysOfWeek); return NotificationNapi::Common::NapiGetNull(env); } -napi_value ReminderCommon::ParseDaysOfWeek( - const napi_env &env, const napi_value &value, std::vector &daysOfWeek) +napi_value ReminderCommon::CreateReminderCalendar( + const napi_env &env, const napi_value &value, std::shared_ptr& reminder) +{ + napi_value dateTimeObj = nullptr; + if (!GetObject(env, value, ReminderAgentNapi::CALENDAR_DATE_TIME, dateTimeObj)) { + ANSR_LOGW("Create calender reminder fail: dateTime must be setted."); + return nullptr; + } + + // year month day hour minute second + int32_t propertyYearVal = 0; + int32_t propertyMonthVal = 0; + int32_t propertyDayVal = 0; + int32_t propertyHourVal = 0; + int32_t propertyMinteVal = 0; + if (!GetInt32(env, dateTimeObj, ReminderAgentNapi::CALENDAR_YEAR, propertyYearVal, true) + || !GetInt32(env, dateTimeObj, ReminderAgentNapi::CALENDAR_MONTH, propertyMonthVal, true) + || !GetInt32(env, dateTimeObj, ReminderAgentNapi::CALENDAR_DAY, propertyDayVal, true) + || !GetInt32(env, dateTimeObj, ReminderAgentNapi::CALENDAR_HOUR, propertyHourVal, true) + || !GetInt32(env, dateTimeObj, ReminderAgentNapi::CALENDAR_MINUTE, propertyMinteVal, true)) { + return nullptr; + } + if (!CheckCalendarParams(propertyYearVal, propertyMonthVal, propertyDayVal, + propertyHourVal, propertyMinteVal)) { + return nullptr; + } + + // repeatMonth + std::vector repeatMonths; + if (ParseInt32Array(env, value, ReminderAgentNapi::CALENDAR_REPEAT_MONTHS, repeatMonths, + ReminderRequestCalendar::MAX_MONTHS_OF_YEAR) == nullptr) { + return nullptr; + } + + // repeatDay + std::vector repeatDays; + if (ParseInt32Array(env, value, ReminderAgentNapi::CALENDAR_REPEAT_DAYS, repeatDays, + ReminderRequestCalendar::MAX_DAYS_OF_MONTH) == nullptr) { + return nullptr; + } + + tm dateTime; + dateTime.tm_year = ReminderRequest::GetCTime(ReminderRequest::TimeTransferType::YEAR, propertyYearVal); + dateTime.tm_mon = ReminderRequest::GetCTime(ReminderRequest::TimeTransferType::MONTH, propertyMonthVal); + dateTime.tm_mday = propertyDayVal; + dateTime.tm_hour = propertyHourVal; + dateTime.tm_min = propertyMinteVal; + dateTime.tm_sec = 0; + reminder = std::make_shared(dateTime, repeatMonths, repeatDays); + return NotificationNapi::Common::NapiGetNull(env); +} + +bool ReminderCommon::CheckCalendarParams(const int32_t &year, const int32_t &month, const int32_t &day, + const int32_t &hour, const int32_t &min) +{ + if (year < 0 || year > UINT16_MAX) { + ANSR_LOGW("Create calender reminder fail: designated %{public}s must between [0, %{public}u]", + ReminderAgentNapi::CALENDAR_YEAR, UINT16_MAX); + return false; + } + if (month < 1 || month > ReminderRequestCalendar::MAX_MONTHS_OF_YEAR) { + ANSR_LOGW("Create calender reminder fail: designated %{public}s must between [1, %{public}u]", + ReminderAgentNapi::CALENDAR_MONTH, ReminderRequestCalendar::MAX_MONTHS_OF_YEAR); + return false; + } + if (day < 1 || day > ReminderRequestCalendar::MAX_DAYS_OF_MONTH) { + ANSR_LOGW("Create calender reminder fail: designated %{public}s must between [1, %{public}u]", + ReminderAgentNapi::CALENDAR_DAY, ReminderRequestCalendar::MAX_DAYS_OF_MONTH); + return false; + } + return true; +} + +napi_value ReminderCommon::ParseInt32Array(const napi_env &env, const napi_value &value, + const char* propertyName, std::vector &propertyVal, uint8_t maxLen) { napi_value result = nullptr; - if (!GetObject(env, value, ReminderAgentNapi::ALARM_DAYS_OF_WEEK, result)) { + if (!GetObject(env, value, propertyName, result)) { return NotificationNapi::Common::NapiGetNull(env); } if (result != nullptr) { bool isArray = false; napi_is_array(env, result, &isArray); if (!isArray) { - ANSR_LOGE("Property %{public}s is expected to be an array.", ReminderAgentNapi::ALARM_DAYS_OF_WEEK); + ANSR_LOGW("Property %{public}s is expected to be an array.", propertyName); return nullptr; } uint32_t length = 0; napi_get_array_length(env, result, &length); - uint8_t maxDaysOfWeek = 7; - if (length > maxDaysOfWeek) { - ANSR_LOGE( - "The max length of array of %{public}s is %{public}d.", ALARM_DAYS_OF_WEEK, maxDaysOfWeek); + if (length > maxLen) { + ANSR_LOGW("The max length of array of %{public}s is %{public}d.", propertyName, maxLen); return nullptr; } napi_valuetype valuetype = napi_undefined; @@ -358,20 +498,18 @@ napi_value ReminderCommon::ParseDaysOfWeek( napi_get_element(env, result, i, &repeatDayVal); NAPI_CALL(env, napi_typeof(env, repeatDayVal, &valuetype)); if (valuetype != napi_number) { - ANSR_LOGE("%{public}s's element is expected to be number.", - ReminderAgentNapi::ALARM_DAYS_OF_WEEK); + ANSR_LOGW("%{public}s's element is expected to be number.", propertyName); return nullptr; } napi_get_value_int32(env, repeatDayVal, &propertyDayVal); - if (propertyDayVal < 1 || propertyDayVal > maxDaysOfWeek) { - ANSR_LOGE("%{public}s's element must between [1, %{public}d].", - ReminderAgentNapi::ALARM_DAYS_OF_WEEK, maxDaysOfWeek); + if (propertyDayVal < 1 || propertyDayVal > maxLen) { + ANSR_LOGW("%{public}s's element must between [1, %{public}d].", propertyName, maxLen); return nullptr; } - daysOfWeek.push_back(static_cast(propertyDayVal)); + propertyVal.push_back(static_cast(propertyDayVal)); } } return NotificationNapi::Common::NapiGetNull(env); } } -} \ No newline at end of file +} diff --git a/services/ans/BUILD.gn b/services/ans/BUILD.gn index c8d570535..12c62d307 100644 --- a/services/ans/BUILD.gn +++ b/services/ans/BUILD.gn @@ -71,8 +71,10 @@ ohos_shared_library("libans") { external_deps = [ "ability_runtime:abilitykit_native", + "ability_runtime:app_manager", "distributeddatamgr:distributeddata_inner", "multimedia_image_standard:image_native", + "multimedia_media_standard:media_client", "os_account_standard:os_account_innerkits", "time_native:time_service", ] diff --git a/services/ans/include/advanced_notification_service.h b/services/ans/include/advanced_notification_service.h index f7029a8c4..b4b7abeb0 100644 --- a/services/ans/include/advanced_notification_service.h +++ b/services/ans/include/advanced_notification_service.h @@ -131,6 +131,8 @@ public: // Distributed KvStore void OnDistributedKvStoreDeathRecipient(); + ErrCode CancelPreparedNotification( + int notificationId, const std::string &label, const sptr &bundleOption); ErrCode PrepareNotificationInfo( const sptr &request, sptr &bundleOption); ErrCode PublishPreparedNotification( diff --git a/services/ans/include/reminder_data_manager.h b/services/ans/include/reminder_data_manager.h index 8990973c2..531060b79 100644 --- a/services/ans/include/reminder_data_manager.h +++ b/services/ans/include/reminder_data_manager.h @@ -20,6 +20,7 @@ #include #include "advanced_notification_service.h" +#include "player.h" #include "reminder_request.h" #include "reminder_timer_info.h" @@ -78,6 +79,13 @@ public: void GetValidReminders( const sptr bundleOption, std::vector> &reminders); + /** + * @brief Triggered when third party application died. + * + * @param bundleOption Indicates the bundleOption of third party application. + */ + void OnProcessDiedLocked(const sptr bundleOption); + /** * Publishs a scheduled reminder. * @@ -105,18 +113,60 @@ public: * * @param isSysTimeChanged Indicates it is triggered as dateTime changed by user or not. */ - void ShowReminder(bool isSysTimeChanged); + void ShowActiveReminder(); + + /** + * @brief Snooze the reminder by manual. + * 1) Snooze the trigger time to the next. + * 2) Update the notification(Update notification lable/content...; Stop audio player and vibrator) + * 3) Show the notification dialog in the SystemUI + * 4) Start a new reminder, which is recent one now. + * + * @param want Which contains the given reminder. + */ + void SnoozeReminder(const OHOS::EventFwk::Want &want); + + /** + * @brief Terminate the alerting reminder. + * + * 1. Stop sound and vibrate. + * 2. Stop the alerting timer. + * 3. Update the reminder state. + * 4. Update the display content of the notification. + * + * @param want Which contains the given reminder. + */ + void TerminateAlerting(const OHOS::EventFwk::Want &want); static const uint8_t TIME_ZONE_CHANGE; static const uint8_t DATE_TIME_CHANGE; private: + enum class TimerType : uint8_t { + TRIGGER_TIMER, + ALERTING_TIMER + }; + + /** + * Add default slot to the reminder if no slot set by user. + * + * @param reminder Indicates the reminder. + */ + void AddDefaultSlotIfNeeded(sptr &reminder); + + /** + * Add reminder to showed reminder vector. + * + * @param reminder Indicates the showed reminder. + */ + void AddToShowedReminders(const sptr &reminder); + /** * Cancels the notification relative to the reminder. * * @param reminder Indicates the reminder. */ - void CancelNotification(sptr &reminder) const; + void CancelNotification(const sptr &reminder) const; /** * Check whether the number limit of reminders if exceeded. @@ -125,15 +175,17 @@ private: * @return true if number limit is exceeded. */ bool CheckReminderLimitExceededLocked(const std::string &bundleName) const; - - void CloseReminder(const int32_t &reminderId, bool cancelNotification); + void CloseReminder(const sptr &reminder, bool cancelNotification); /** * Create a information for timer, such as timer type, repeat policy, interval and want agent. * + * @param type Indicates the timer type. * @return pointer of ReminderTimerInfo. */ - std::shared_ptr CreateTimerInfo() const; + std::shared_ptr CreateTimerInfo(TimerType type) const; + + std::string GetSoundUri(const sptr &reminder); /** * Find the reminder from reminderVector_ by reminder id. @@ -159,7 +211,7 @@ private: * @param reminderId Indicates the reminder id. * @return pointer of NotificationBundleOption or nullptr. */ - sptr FindNotificationBundleOption(const int32_t &reminderId); + sptr FindNotificationBundleOption(const int32_t &reminderId) const; /** * Obtains the recent reminder which is not expired from reminder vector. @@ -197,6 +249,8 @@ private: */ void HandleSameNotificationIdShowing(const sptr reminder); + bool HandleSysTimeChange(const sptr reminder) const; + /** * Judge the two reminders is belong to the same application or not. * @@ -208,6 +262,18 @@ private: bool IsBelongToSameApp( const sptr reminder, const std::string otherPkgName, const int otherUserId); + void PlaySoundAndVibrationLocked(const sptr &reminder); + void PlaySoundAndVibration(const sptr &reminder); + void StopSoundAndVibrationLocked(const sptr &reminder); + void StopSoundAndVibration(const sptr &reminder); + + /** + * Remove from showed reminder vector. + * + * @param reminder Indicates the reminder need to remove. + */ + void RemoveFromShowedReminders(const sptr &reminder); + /** * @brief Refresh the all reminders due to date/time or timeZone change by user. * @@ -227,12 +293,30 @@ private: /** * Resets timer status. - * 1. Sets timerId_ with 0. - * 2. Sets activeReminderId_ with -1. + * 1. Sets timerId_ or timerIdAlerting_ with 0. + * 2. Sets activeReminderId_ or alertingReminderId with -1. + * + * @param type Indicates the timer type. + */ + void ResetStates(TimerType type); + + void SetActiveReminder(const sptr &reminder); + void SetAlertingReminder(const sptr &reminder); + void ShowActiveReminderExtendLocked(sptr &reminder); + + /** + * @brief Show the reminder on SystemUI. + * + * @param reminder Indicates the reminder to show. + * @param isNeedToPlaySound Indicates whether need to play sound. + * @param isNeedToStartNext Indicates whether need to start next reminder. + * @param isSysTimeChanged Indicates whether it is triggerred as system time changed by user. + * @param needScheduleTimeout Indicates whether need to control the ring duration. */ - void ResetStates(); + void ShowReminder(const sptr &reminder, const bool &isNeedToPlaySound, + const bool &isNeedToStartNext, const bool &isSysTimeChanged, const bool &needScheduleTimeout); - void ShowDesignatedReminderLocked(sptr &reminder, bool isSysTimeChanged); + void SnoozeReminderImpl(sptr &reminder); /** * Starts the recent reminder timing. @@ -243,18 +327,42 @@ private: * Starts timing actually. * * @param reminderRequest Indicates the reminder. + * @param type Indicates the timer type. */ - void StartTimerLocked(sptr &reminderRequest); + void StartTimerLocked(const sptr &reminderRequest, TimerType type); + void StartTimer(const sptr &reminderRequest, TimerType type); /** - * Stops timing. + * @brief Stop the alerting timer and update reminder information. + * + * 1. Stop sound and vibrate. + * 2. Stop the alerting timer. + * + * @param reminder Indicates the target reminder. */ - void StopTimer(); + void StopAlertingReminder(const sptr &reminder); /** * Stops timing. + * + * @param type Indicates the timer type. + */ + void StopTimer(TimerType type); + void StopTimerLocked(TimerType type); + + /** + * @brief Terminate the alerting reminder. + * + * 1. Stop sound and vibrate. + * 2. Stop the alerting timer. + * 3. Update the reminder state. + * 4. Update the display content of the notification. + * + * @param reminder Indicates the reminder. + * @param reason Indicates the description information. */ - void StopTimerLocked(); + void TerminateAlerting(const sptr &reminder, const std::string &reason); + void TerminateAlerting(const uint16_t waitInMilli, const sptr &reminder); /** * @brief Assign unique reminder id and save reminder in memory. @@ -265,6 +373,8 @@ private: void UpdateAndSaveReminderLocked( const sptr &reminder, const sptr &bundleOption); + void UpdateNotification(const sptr &reminder); + static bool cmp(sptr &reminderRequest, sptr &other); /** @@ -276,6 +386,8 @@ private: * Used for multi-thread syncronise. */ static std::mutex MUTEX; + static std::mutex SHOW_MUTEX; + static std::mutex ALERT_MUTEX; /** * Max number of reminders limit for the whole system. @@ -287,27 +399,44 @@ private: */ static const int16_t MAX_NUM_REMINDER_LIMIT_APP; - static const uint16_t SAME_TIME_DISTINGUISH_MILLISECONDS; - /** * Vector used to record all the reminders in system. */ std::vector> reminderVector_; + /** + * Vector used to record all the reminders which has been shown on panel. + */ + std::vector> shownReminderVector_; + /** * Map used to record all the bundle information of the reminders in system. */ std::map> notificationBundleOptionMap_; /** - * Indicates the id of the timer that has called StartTimerLocked. + * This timer is used to control the triggerTime of next reminder. */ uint64_t timerId_ {0}; + /** + * This timer is used to control the ringDuration of the alerting reminder. + */ + uint64_t timerIdAlerting_ {0}; + /** * Indicates the active reminder that timing is taking effect. */ - int32_t activeReminderId_ {-1}; + int32_t activeReminderId_ = -1; + sptr activeReminder_ = nullptr; + + /** + * Indicates the reminder which is playing sound or vibration. + */ + int32_t alertingReminderId_ = -1; + sptr alertingReminder_ = nullptr; + + std::shared_ptr soundPlayer_ = nullptr; /** * Indicates the total count of reminders in system. @@ -317,5 +446,4 @@ private: }; } // namespace OHOS } // namespace Nofitifcation - #endif // BASE_NOTIFICATION_ANS_STANDARD_FRAMEWORKS_ANS_CORE_INCLUDE_REMINDER_DATA_MANAGER_H \ No newline at end of file diff --git a/services/ans/include/reminder_event_manager.h b/services/ans/include/reminder_event_manager.h index 25a20792a..bfc72148d 100644 --- a/services/ans/include/reminder_event_manager.h +++ b/services/ans/include/reminder_event_manager.h @@ -40,6 +40,10 @@ public: virtual void OnReceiveEvent(const EventFwk::CommonEventData &data); private: + sptr GetBundleOption(const OHOS::EventFwk::Want &want) const; + void HandlePackageRemove(OHOS::EventFwk::Want &want) const; + void HandleProcessDied(OHOS::EventFwk::Want &want) const; + int32_t GetUid(const int userId, const std::string bundleName) const; std::shared_ptr reminderDataManager_; }; }; diff --git a/services/ans/include/reminder_timer_info.h b/services/ans/include/reminder_timer_info.h index 0bc1e891e..043492369 100644 --- a/services/ans/include/reminder_timer_info.h +++ b/services/ans/include/reminder_timer_info.h @@ -31,6 +31,10 @@ public: ReminderTimerInfo(ReminderTimerInfo &other) = delete; ReminderTimerInfo& operator = (const ReminderTimerInfo &other) = delete; + inline void SetAction(const std::string &action) { + action_ = action; + } + /** * When timing is up, this function will execute as call back. */ @@ -56,10 +60,8 @@ public: */ void SetWantAgent(std::shared_ptr wantAgent) override; - /** - * Publish common event. - */ - bool PublishCommonEvent(const std::string &action) const; +private: + std::string action_; }; } // namespace OHOS } // namespace Notification diff --git a/services/ans/src/advanced_notification_service.cpp b/services/ans/src/advanced_notification_service.cpp index 484f975bc..61f7b0daa 100644 --- a/services/ans/src/advanced_notification_service.cpp +++ b/services/ans/src/advanced_notification_service.cpp @@ -292,6 +292,33 @@ ErrCode AdvancedNotificationService::AssignToNotificationList(const std::shared_ return result; } +ErrCode AdvancedNotificationService::CancelPreparedNotification( + int notificationId, const std::string &label, const sptr &bundleOption) +{ + if (bundleOption == nullptr) { + return ERR_ANS_INVALID_BUNDLE; + } + ErrCode result = ERR_OK; + handler_->PostSyncTask(std::bind([&]() { + sptr notification = nullptr; + result = RemoveFromNotificationList(bundleOption, label, notificationId, notification, true); + if (result != ERR_OK) { + return; + } + + if (notification != nullptr) { + int reason = NotificationConstant::APP_CANCEL_REASON_DELETE; + UpdateRecentNotification(notification, true, reason); + sptr sortingMap = GenerateSortingMap(); + NotificationSubscriberManager::GetInstance()->NotifyCanceled(notification, sortingMap, reason); +#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED + DoDistributedDelete("", notification); +#endif + } + })); + return result; +} + ErrCode AdvancedNotificationService::PrepareNotificationInfo( const sptr &request, sptr &bundleOption) { @@ -454,29 +481,7 @@ ErrCode AdvancedNotificationService::Cancel(int notificationId, const std::strin { ANS_LOGD("%{public}s", __FUNCTION__); sptr bundleOption = GenerateBundleOption(); - if (bundleOption == nullptr) { - return ERR_ANS_INVALID_BUNDLE; - } - - ErrCode result = ERR_OK; - handler_->PostSyncTask(std::bind([&]() { - sptr notification = nullptr; - result = RemoveFromNotificationList(bundleOption, label, notificationId, notification, true); - if (result != ERR_OK) { - return; - } - - if (notification != nullptr) { - int reason = NotificationConstant::APP_CANCEL_REASON_DELETE; - UpdateRecentNotification(notification, true, reason); - sptr sortingMap = GenerateSortingMap(); - NotificationSubscriberManager::GetInstance()->NotifyCanceled(notification, sortingMap, reason); -#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED - DoDistributedDelete("", notification); -#endif - } - })); - return result; + return CancelPreparedNotification(notificationId, label, bundleOption); } ErrCode AdvancedNotificationService::CancelAll() @@ -2825,4 +2830,4 @@ void AdvancedNotificationService::TriggerRemoveWantAgent(const sptr ReminderDataManager::REMINDER_DATA_MANAGER = nullptr; std::mutex ReminderDataManager::MUTEX; +std::mutex ReminderDataManager::SHOW_MUTEX; +std::mutex ReminderDataManager::ALERT_MUTEX; void ReminderDataManager::PublishReminder(sptr &reminder, sptr &bundleOption) @@ -49,9 +52,13 @@ void ReminderDataManager::CancelReminder( ANSR_LOGW("Cancel reminder, not find the reminder"); return; } - if (activeReminderId_ != -1 && activeReminderId_ == reminderId) { - ANSR_LOGD("Cancel active reminder, id=%{public}d", activeReminderId_); - StopTimerLocked(); + if (activeReminderId_ == reminderId) { + ANSR_LOGD("Cancel active reminder, id=%{public}d", reminderId); + StopTimerLocked(TimerType::TRIGGER_TIMER); + } + if (alertingReminderId_ == reminderId) { + StopTimerLocked(TimerType::ALERTING_TIMER); + StopSoundAndVibrationLocked(reminder); } int32_t id = reminderId; RemoveReminderLocked(id); @@ -59,7 +66,7 @@ void ReminderDataManager::CancelReminder( StartRecentReminder(); } -void ReminderDataManager::CancelNotification(sptr &reminder) const +void ReminderDataManager::CancelNotification(const sptr &reminder) const { if (!(reminder->IsShowing())) { ANSR_LOGD("No need to cancel notification"); @@ -75,7 +82,9 @@ void ReminderDataManager::CancelNotification(sptr &reminder) co ANSR_LOGE("Cancel notification fail"); return; } - advancedNotificationService_->Cancel(notification->GetNotificationId(), ReminderRequest::NOTIFICATION_LABEL); + sptr bundleOption = FindNotificationBundleOption(reminder->GetReminderId()); + advancedNotificationService_->CancelPreparedNotification( + notification->GetNotificationId(), ReminderRequest::NOTIFICATION_LABEL, bundleOption); } bool ReminderDataManager::CheckReminderLimitExceededLocked(const std::string &bundleName) const @@ -113,10 +122,10 @@ void ReminderDataManager::CancelAllReminders(const sptrsecond->GetBundleName() == bundleOption->GetBundleName()) { - StopTimer(); + StopTimer(TimerType::TRIGGER_TIMER); } } for (auto vit = reminderVector_.begin(); vit != reminderVector_.end();) { @@ -124,15 +133,19 @@ void ReminderDataManager::CancelAllReminders(const sptrsecond->GetBundleName() == bundleOption->GetBundleName()) { - CancelNotification(*vit); - ANSR_LOGD("Containers(vector/map) remove. reminderId=%{public}d", reminderId); - vit = reminderVector_.erase(vit); - notificationBundleOptionMap_.erase(mit); - totalCount_--; - continue; + ++vit; + continue; + } + if (mit->second->GetBundleName() == bundleOption->GetBundleName()) { + if ((*vit)->IsAlerting()) { + StopAlertingReminder(*vit); } + CancelNotification(*vit); + ANSR_LOGD("Containers(vector/map) remove. reminderId=%{public}d", reminderId); + vit = reminderVector_.erase(vit); + notificationBundleOptionMap_.erase(mit); + totalCount_--; + continue; } ++vit; } @@ -160,13 +173,88 @@ void ReminderDataManager::GetValidReminders( } } -std::shared_ptr ReminderDataManager::CreateTimerInfo() const +void ReminderDataManager::AddToShowedReminders(const sptr &reminder) +{ + std::lock_guard lock(ReminderDataManager::SHOW_MUTEX); + for (auto it = shownReminderVector_.begin(); it != shownReminderVector_.end(); ++it) { + if (reminder->GetReminderId() == (*it)->GetReminderId()) { + ANSR_LOGD("Showed reminder is already exist"); + return; + } + } + ANSR_LOGD("Containers(shownVector) add. reminderId=%{public}d", reminder->GetReminderId()); + shownReminderVector_.push_back(reminder); +} + +void ReminderDataManager::OnProcessDiedLocked(const sptr bundleOption) +{ + std::string bundleName = bundleOption->GetBundleName(); + int32_t uid = bundleOption->GetUid(); + ANSR_LOGI("OnProcessDiedLocked, bundleName=%{public}s, uid=%{public}d", bundleName.c_str(), uid); + std::lock_guard lock(ReminderDataManager::SHOW_MUTEX); + for (auto it = shownReminderVector_.begin(); it != shownReminderVector_.end(); ++it) { + int32_t reminderId = (*it)->GetReminderId(); + auto mit = notificationBundleOptionMap_.find(reminderId); + if (mit == notificationBundleOptionMap_.end()) { + ANSR_LOGE("Get bundle option occur error, reminderId=%{public}d", reminderId); + continue; + } + if (mit->second->GetBundleName() != bundleName || mit->second->GetUid() != uid) { + continue; + } + if ((*it)->IsAlerting()) { + TerminateAlerting((*it), "onProcessDied"); + } else { + CancelNotification(*it); + (*it)->OnClose(false); + ANSR_LOGD("Containers(shownVector) remove. reminderId=%{public}d", reminderId); + shownReminderVector_.erase(it); + --it; + } + } +} + +std::shared_ptr ReminderDataManager::CreateTimerInfo(TimerType type) const { auto sharedTimerInfo = std::make_shared(); sharedTimerInfo->SetType(sharedTimerInfo->TIMER_TYPE_WAKEUP|sharedTimerInfo->TIMER_TYPE_EXACT); sharedTimerInfo->SetRepeat(false); sharedTimerInfo->SetInterval(0); - sharedTimerInfo->SetWantAgent(nullptr); + + int requestCode = 10; + std::vector flags; + flags.push_back(WantAgent::WantAgentConstant::Flags::UPDATE_PRESENT_FLAG); + auto want = std::make_shared(); + + switch (type) { + case (TimerType::TRIGGER_TIMER): { + want->SetAction(ReminderRequest::REMINDER_EVENT_ALARM_ALERT); + break; + } + case (TimerType::ALERTING_TIMER): { + if (alertingReminderId_ == -1) { + ANSR_LOGE("Create alerting time out timer Illegal."); + return sharedTimerInfo; + } + want->SetAction(ReminderRequest::REMINDER_EVENT_ALERT_TIMEOUT); + want->SetParam(ReminderRequest::PARAM_REMINDER_ID, alertingReminderId_); + break; + } + default: + ANSR_LOGE("TimerType not support"); + break; + } + std::vector> wants; + wants.push_back(want); + WantAgent::WantAgentInfo wantAgentInfo( + requestCode, + WantAgent::WantAgentConstant::OperationType::SEND_COMMON_EVENT, + flags, + wants, + nullptr + ); + std::shared_ptr wantAgent = WantAgent::WantAgentHelper::GetWantAgent(wantAgentInfo); + sharedTimerInfo->SetWantAgent(wantAgent); return sharedTimerInfo; } @@ -202,7 +290,7 @@ sptr ReminderDataManager::FindReminderRequestLocked( return reminder; } -sptr ReminderDataManager::FindNotificationBundleOption(const int32_t &reminderId) +sptr ReminderDataManager::FindNotificationBundleOption(const int32_t &reminderId) const { auto it = notificationBundleOptionMap_.find(reminderId); if (it == notificationBundleOptionMap_.end()) { @@ -220,21 +308,27 @@ bool ReminderDataManager::cmp(sptr &reminderRequest, sptr(want.GetIntParam(ReminderRequest::PARAM_REMINDER_ID, -1)); - CloseReminder(reminderId, cancelNotification); -} - -void ReminderDataManager::CloseReminder(const int32_t &reminderId, bool cancelNotification) -{ sptr reminder = FindReminderRequestLocked(reminderId); if (reminder == nullptr) { ANSR_LOGW("Invilate reminder id: %{public}d", reminderId); return; } - if (activeReminderId_ != -1 && activeReminderId_ == reminderId) { + CloseReminder(reminder, cancelNotification); +} + +void ReminderDataManager::CloseReminder(const sptr &reminder, bool cancelNotification) +{ + int32_t reminderId = reminder->GetReminderId(); + if (activeReminderId_ == reminderId) { ANSR_LOGD("Stop active reminder due to CloseReminder"); - StopTimerLocked(); + StopTimerLocked(TimerType::TRIGGER_TIMER); + } + if (alertingReminderId_ == reminderId) { + StopTimerLocked(TimerType::ALERTING_TIMER); + StopSoundAndVibrationLocked(reminder); } reminder->OnClose(true); + RemoveFromShowedReminders(reminder); if (cancelNotification) { CancelNotification(reminder); } @@ -256,7 +350,7 @@ void ReminderDataManager::RefreshRemindersDueToSysTimeChange(uint8_t type) ANSR_LOGI("Refresh all reminders due to %{public}s changed by user", typeInfo.c_str()); if (activeReminderId_ != -1) { ANSR_LOGD("Stop active reminder due to date/time or timeZone change"); - StopTimerLocked(); + StopTimerLocked(TimerType::TRIGGER_TIMER); } std::vector> showImmediately = RefreshRemindersLocked(type); if (!showImmediately.empty()) { @@ -266,19 +360,62 @@ void ReminderDataManager::RefreshRemindersDueToSysTimeChange(uint8_t type) StartRecentReminder(); } +void ReminderDataManager::TerminateAlerting(const OHOS::EventFwk::Want &want) +{ + int32_t reminderId = static_cast(want.GetIntParam(ReminderRequest::PARAM_REMINDER_ID, -1)); + sptr reminder = FindReminderRequestLocked(reminderId); + if (reminder == nullptr) { + ANSR_LOGE("Invilate reminder id: %{public}d", reminderId); + return; + } + TerminateAlerting(reminder, "timeOut"); +} + +void ReminderDataManager::TerminateAlerting(const uint16_t waitInMilli, const sptr &reminder) +{ + sleep(waitInMilli); + TerminateAlerting(reminder, "waitInMillis"); +} + +void ReminderDataManager::TerminateAlerting(const sptr &reminder, const std::string &reason) +{ + ANSR_LOGI("Terminate the alerting reminder, %{public}s, called by %{public}s", + reminder->Dump().c_str(), reason.c_str()); + StopAlertingReminder(reminder); + + if (reminder == nullptr) { + ANSR_LOGE("TerminateAlerting illegal."); + return; + } + if (!reminder->OnTerminate()) { + return; + } + int32_t reminderId = reminder->GetReminderId(); + sptr bundleOption = FindNotificationBundleOption(reminderId); + sptr notificationRequest = reminder->GetNotificationRequest(); + if (bundleOption == nullptr) { + ANSR_LOGE("Get bundle option fail, reminderId=%{public}d", reminderId); + return; + } + ANSR_LOGD("publish(update) notification.(reminderId=%{public}d)", reminder->GetReminderId()); + UpdateNotification(reminder); + advancedNotificationService_->PublishPreparedNotification(notificationRequest, bundleOption); +} + void ReminderDataManager::UpdateAndSaveReminderLocked( const sptr &reminder, const sptr &bundleOption) { std::lock_guard lock(ReminderDataManager::MUTEX); reminder->InitReminderId(); int32_t reminderId = reminder->GetReminderId(); - ANSR_LOGD("Containers(vector/map) add. reminderId=%{public}d", reminderId); + ANSR_LOGD("Containers(map) add. reminderId=%{public}d", reminderId); auto ret = notificationBundleOptionMap_.insert( std::pair>(reminderId, bundleOption)); if (!ret.second) { ANSR_LOGE("Containers add to map error"); return; } + ANSR_LOGD("Containers(vector) add. reminderId=%{public}d", reminderId); reminderVector_.push_back(reminder); totalCount_++; } @@ -288,97 +425,207 @@ void ReminderDataManager::SetService(AdvancedNotificationService *advancedNotifi advancedNotificationService_ = advancedNotificationService; } -void ReminderDataManager::ShowReminder(bool isSysTimeChanged) +void ReminderDataManager::ShowActiveReminder() { - ANSR_LOGD("ShowReminder"); + ANSR_LOGI("Begin to show reminder."); if (activeReminderId_ == -1) { ANSR_LOGE("Active reminder not exist"); return; } - sptr reminder = FindReminderRequestLocked(activeReminderId_); - ShowDesignatedReminderLocked(reminder, isSysTimeChanged); - ResetStates(); + if (HandleSysTimeChange(activeReminder_)) { + ResetStates(TimerType::TRIGGER_TIMER); + return; + } + ShowActiveReminderExtendLocked(activeReminder_); + ResetStates(TimerType::TRIGGER_TIMER); StartRecentReminder(); } -void ReminderDataManager::ShowDesignatedReminderLocked(sptr &reminder, bool isSysTimeChanged) +bool ReminderDataManager::HandleSysTimeChange(const sptr reminder) const +{ + if (reminder->CanShow()) { + return false; + } else { + ANSR_LOGI("handleSystimeChange, no need to show reminder again."); + return true; + } +} + +void ReminderDataManager::SetActiveReminder(const sptr &reminder) +{ + if (reminder == nullptr) { + // activeReminder_ should not be set with null as it point to actual object. + activeReminderId_ = -1; + } else { + activeReminderId_ = reminder->GetReminderId(); + activeReminder_ = reminder; + } +} + +void ReminderDataManager::SetAlertingReminder(const sptr &reminder) +{ + if (reminder == nullptr) { + // alertingReminder_ should not be set with null as it point to actual object. + alertingReminderId_ = -1; + } else { + alertingReminderId_ = reminder->GetReminderId(); + alertingReminder_ = reminder; + } +} + +void ReminderDataManager::ShowActiveReminderExtendLocked(sptr &reminder) { std::lock_guard lock(ReminderDataManager::MUTEX); uint64_t triggerTime = reminder->GetTriggerTimeInMilli(); + bool isAlerting = false; + sptr playSoundReminder = nullptr; for (auto it = reminderVector_.begin(); it != reminderVector_.end(); ++it) { if ((*it)->IsExpired()) { continue; } - if ((*it)->GetTriggerTimeInMilli() - triggerTime > ReminderDataManager::SAME_TIME_DISTINGUISH_MILLISECONDS) { + if ((*it)->GetTriggerTimeInMilli() - triggerTime > ReminderRequest::SAME_TIME_DISTINGUISH_MILLISECONDS) { continue; } - if (isSysTimeChanged) { - if ((*it)->GetReminderId() != reminder->GetReminderId()) { - continue; - } - } - int32_t reminderId = (*it)->GetReminderId(); - sptr bundleOption = FindNotificationBundleOption(reminderId); - sptr notificationRequest = (*it)->GetNotificationRequest(); - if (bundleOption == nullptr) { - ANSR_LOGE("Get bundle option fail, reminderId=%{public}d", reminderId); - continue; + if (!isAlerting) { + playSoundReminder = (*it); + isAlerting = true; + } else { + ShowReminder((*it), false, false, false, false); } - if (advancedNotificationService_ == nullptr) { - ANSR_LOGE("ShowReminder fail"); - (*it)->OnShow(isSysTimeChanged, false); + } + if (playSoundReminder != nullptr) { + ShowReminder(playSoundReminder, true, false, false, true); + } +} + +void ReminderDataManager::ShowReminder(const sptr &reminder, const bool &isNeedToPlaySound, + const bool &isNeedToStartNext, const bool &isSysTimeChanged, const bool &needScheduleTimeout) +{ + ANSR_LOGD("Show the reminder(Play sound: %{public}d), %{public}s" + , static_cast(isNeedToPlaySound), reminder->Dump().c_str()); + int32_t reminderId = reminder->GetReminderId(); + sptr bundleOption = FindNotificationBundleOption(reminderId); + sptr notificationRequest = reminder->GetNotificationRequest(); + if (bundleOption == nullptr) { + ANSR_LOGE("Get bundle option fail, reminderId=%{public}d", reminderId); + return; + } + if (advancedNotificationService_ == nullptr) { + ANSR_LOGE("ShowReminder fail"); + reminder->OnShow(false, isSysTimeChanged, false); + return; + } + if (isNeedToPlaySound) { // todo if shouldAlert + PlaySoundAndVibration(reminder); // play sound and vibration + reminder->OnShow(true, isSysTimeChanged, true); + if (needScheduleTimeout) { + StartTimer(reminder, TimerType::ALERTING_TIMER); } else { - ANSR_LOGD("publish notification.(reminderId=%{public}d)", reminderId); - (*it)->UpdateNotificationRequest(ReminderRequest::UpdateNotificationType::COMMON, ""); - (*it)->UpdateNotificationRequest(ReminderRequest::UpdateNotificationType::REMOVAL_WANT_AGENT, ""); - (*it)->UpdateNotificationRequest(ReminderRequest::UpdateNotificationType::ACTION_BUTTON, ""); - advancedNotificationService_->PublishPreparedNotification(notificationRequest, bundleOption); - (*it)->OnShow(isSysTimeChanged, true); - HandleSameNotificationIdShowing((*it)); + TerminateAlerting(ReminderRequest::MILLI_SECONDS, reminder); } + } else { + reminder->OnShow(false, isSysTimeChanged, true); + } + AddToShowedReminders(reminder); + ANSR_LOGD("publish notification.(reminderId=%{public}d)", reminder->GetReminderId()); + UpdateNotification(reminder); // this should be called after OnShow + ErrCode errCode + = advancedNotificationService_->PublishPreparedNotification(notificationRequest, bundleOption); + if (errCode != ERR_OK) { + reminder->OnShowFail(); + RemoveFromShowedReminders(reminder); + } else { + HandleSameNotificationIdShowing(reminder); + } + if (isNeedToStartNext) { + StartRecentReminder(); } } -void ReminderDataManager::StartRecentReminder() +void ReminderDataManager::UpdateNotification(const sptr &reminder) { - sptr reminder = GetRecentReminderLocked(); + reminder->UpdateNotificationRequest(ReminderRequest::UpdateNotificationType::COMMON, ""); + reminder->UpdateNotificationRequest(ReminderRequest::UpdateNotificationType::REMOVAL_WANT_AGENT, ""); + reminder->UpdateNotificationRequest(ReminderRequest::UpdateNotificationType::WANT_AGENT, ""); + reminder->UpdateNotificationRequest(ReminderRequest::UpdateNotificationType::MAX_SCREEN_WANT_AGENT, ""); +} + +void ReminderDataManager::SnoozeReminder(const OHOS::EventFwk::Want &want) +{ + int32_t reminderId = static_cast(want.GetIntParam(ReminderRequest::PARAM_REMINDER_ID, -1)); + sptr reminder = FindReminderRequestLocked(reminderId); if (reminder == nullptr) { - ANSR_LOGI("No reminder need to start"); + ANSR_LOGW("Invilate reminder id: %{public}d", reminderId); return; } + SnoozeReminderImpl(reminder); +} - bool toStart = true; - if (activeReminderId_ != -1) { - if (activeReminderId_ != reminder->GetReminderId()) { - ANSR_LOGI("Stop active reminder"); - StopTimerLocked(); - } else { - ANSR_LOGI("Recent reminder has already run, no need to start again."); - toStart = false; - } +void ReminderDataManager::SnoozeReminderImpl(sptr &reminder) +{ + ANSR_LOGI("Snooze the reminder request, %{public}s", reminder->Dump().c_str()); + int32_t reminderId = reminder->GetReminderId(); + if (activeReminderId_ == reminderId) { + ANSR_LOGD("Cancel active reminder, id=%{public}d", activeReminderId_); + StopTimerLocked(TimerType::TRIGGER_TIMER); } - if (toStart) { - ANSR_LOGI("Start recent reminder"); - StartTimerLocked(reminder); + + // 1) Snooze the reminder by manual + if (alertingReminderId_ == reminder->GetReminderId()) { + StopTimerLocked(TimerType::ALERTING_TIMER); + StopSoundAndVibrationLocked(reminder); } + reminder->OnSnooze(); + + // 2) Show the notification dialog in the systemUI + sptr bundleOption = FindNotificationBundleOption(reminderId); + sptr notificationRequest = reminder->GetNotificationRequest(); + if (bundleOption == nullptr) { + ANSR_LOGW("snoozeReminder, invalid bundle option"); + return; + } + ANSR_LOGD("publish(update) notification.(reminderId=%{public}d)", reminder->GetReminderId()); + UpdateNotification(reminder); + advancedNotificationService_->PublishPreparedNotification(notificationRequest, bundleOption); + StartRecentReminder(); } -void ReminderDataManager::StopTimer() +// snoozeReminder(bool snoozeAll) + +void ReminderDataManager::StartRecentReminder() { - if (timerId_ == 0) { - ANSR_LOGD("Timer is not running"); + sptr reminder = GetRecentReminderLocked(); + if (reminder == nullptr) { + ANSR_LOGI("No reminder need to start"); + SetActiveReminder(reminder); return; } - ANSR_LOGD("Stop timer id=%{public}llu", (unsigned long long)timerId_); - sptr timer = MiscServices::TimeServiceClient::GetInstance(); - timer->StopTimer(timerId_); - ResetStates(); + if (activeReminderId_ == reminder->GetReminderId()) { + ANSR_LOGI("Recent reminder has already run, no need to start again."); + return; + } + if (activeReminderId_ != -1) { + StopTimerLocked(TimerType::TRIGGER_TIMER); + activeReminder_->OnStop(); + } + ANSR_LOGI("Start recent reminder"); + StartTimerLocked(reminder, TimerType::TRIGGER_TIMER); + reminder->OnStart(); + SetActiveReminder(reminder); } -void ReminderDataManager::StopTimerLocked() +void ReminderDataManager::StopAlertingReminder(const sptr &reminder) { - std::lock_guard lock(ReminderDataManager::MUTEX); - StopTimer(); + if (reminder == nullptr) { + ANSR_LOGE("StopAlertingReminder illegal."); + return; + } + if (alertingReminderId_ == -1 || reminder->GetReminderId() != alertingReminderId_) { + ANSR_LOGE("StopAlertingReminder is illegal."); + return; + } + StopSoundAndVibration(alertingReminder_); + StopTimer(TimerType::ALERTING_TIMER); } std::string ReminderDataManager::Dump() const @@ -435,27 +682,27 @@ sptr ReminderDataManager::GetRecentReminderLocked() { std::lock_guard lock(ReminderDataManager::MUTEX); sort(reminderVector_.begin(), reminderVector_.end(), cmp); - for (auto reminder = reminderVector_.begin(); reminder != reminderVector_.end();) { - if (!(*reminder)->IsExpired()) { - ANSR_LOGD("GetRecentReminderLocked: %{public}s", (*reminder)->Dump().c_str()); - return *reminder; - } - if (!(*reminder)->CanRemove()) { - ANSR_LOGD("Reminder has been expired: %{public}s", (*reminder)->Dump().c_str()); - reminder++; + for (auto it = reminderVector_.begin(); it != reminderVector_.end();) { + if (!(*it)->IsExpired()) { + ANSR_LOGI("GetRecentReminderLocked: %{public}s", (*it)->Dump().c_str()); + return *it; + } + if (!(*it)->CanRemove()) { + ANSR_LOGD("Reminder has been expired: %{public}s", (*it)->Dump().c_str()); + it++; continue; } - int32_t reminderId = (*reminder)->GetReminderId(); + int32_t reminderId = (*it)->GetReminderId(); ANSR_LOGD("Containers(vector) remove. reminderId=%{public}d", reminderId); - auto it = notificationBundleOptionMap_.find((*reminder)->GetReminderId()); - if (it == notificationBundleOptionMap_.end()) { + auto mit = notificationBundleOptionMap_.find((*it)->GetReminderId()); + if (mit == notificationBundleOptionMap_.end()) { ANSR_LOGE("Remove notificationBundleOption(reminderId=%{public}d) fail", - (*reminder)->GetReminderId()); + (*it)->GetReminderId()); } else { - ANSR_LOGD("Containers(map) remove. reminderId=%{public}d", reminderId); - notificationBundleOptionMap_.erase(it); + ANSR_LOGD("Containers(vector/map) remove. reminderId=%{public}d", reminderId); + notificationBundleOptionMap_.erase(mit); } - reminder = reminderVector_.erase(reminder); + it = reminderVector_.erase(it); totalCount_--; } return nullptr; @@ -482,13 +729,21 @@ std::vector> ReminderDataManager::GetSameBundleRemindersLo void ReminderDataManager::HandleImmediatelyShow( std::vector> &showImmediately, bool isSysTimeChanged) { + bool isAlerting = false; for (auto it = showImmediately.begin(); it != showImmediately.end(); ++it) { - ShowDesignatedReminderLocked((*it), isSysTimeChanged); + if (!isAlerting) { + ShowReminder((*it), true, false, isSysTimeChanged, false); + isAlerting = true; + } else { + ShowReminder((*it), false, false, isSysTimeChanged, false); + } } } sptr ReminderDataManager::HandleRefreshReminder(uint8_t &type, sptr &reminder) { + reminder->SetReminderTimeInMilli(ReminderRequest::INVALID_LONG_LONG_VALUE); + uint64_t triggerTimeBefore = reminder->GetTriggerTimeInMilli(); bool needShowImmediately = false; if (type == TIME_ZONE_CHANGE) { needShowImmediately = reminder->OnTimeZoneChange(); @@ -497,6 +752,11 @@ sptr ReminderDataManager::HandleRefreshReminder(uint8_t &type, needShowImmediately = reminder->OnDateTimeChange(); } if (!needShowImmediately) { + uint64_t triggerTimeAfter = reminder->GetTriggerTimeInMilli(); + if (triggerTimeBefore != triggerTimeAfter + || reminder->GetReminderId() == alertingReminderId_) { + CloseReminder(reminder, true); + } return nullptr; } else { return reminder; @@ -505,7 +765,7 @@ sptr ReminderDataManager::HandleRefreshReminder(uint8_t &type, void ReminderDataManager::HandleSameNotificationIdShowing(const sptr reminder) { - // not add ReminderDataManager::MUTEX, as ShowDesignatedReminderLocked has locked + // not add ReminderDataManager::MUTEX, as ShowActiveReminderExtendLocked has locked int32_t notificationId = reminder->GetNotificationId(); ANSR_LOGD("HandleSameNotificationIdShowing notificationId=%{public}d", notificationId); int32_t curReminderId = reminder->GetReminderId(); @@ -524,7 +784,11 @@ void ReminderDataManager::HandleSameNotificationIdShowing(const sptrGetNotificationId() && IsBelongToSameApp(reminder, bundleOption->GetBundleName(), 0)) { + if ((*it)->IsAlerting()) { + StopAlertingReminder(*it); + } (*it)->OnSameNotificationIdCovered(); + RemoveFromShowedReminders(*it); } } } @@ -545,6 +809,87 @@ bool ReminderDataManager::IsBelongToSameApp( return false; } +void ReminderDataManager::PlaySoundAndVibrationLocked(const sptr &reminder) +{ + std::lock_guard lock(ReminderDataManager::ALERT_MUTEX); // todo check died lock + PlaySoundAndVibration(reminder); +} + +void ReminderDataManager::PlaySoundAndVibration(const sptr &reminder) +{ + if (reminder == nullptr) { + ANSR_LOGE("Play sound and vibration failed as reminder is null."); + return; + } + if (alertingReminderId_ != -1) { + TerminateAlerting(alertingReminder_, "PlaySoundAndVibration"); + } + ANSR_LOGD("Play sound and vibration, reminderId=%{public}d", reminder->GetReminderId()); + if (soundPlayer_ == nullptr) { + soundPlayer_ = Media::PlayerFactory::CreatePlayer(); + } + std::string uri = GetSoundUri(reminder); + ANSR_LOGD("uri:%{public}s", uri.c_str()); + soundPlayer_->SetSource(uri); + soundPlayer_->SetLooping(true); + soundPlayer_->Prepare(); + soundPlayer_->Play(); + SetAlertingReminder(reminder); +} + +std::string ReminderDataManager::GetSoundUri(const sptr &reminder) +{ + sptr bundle = FindNotificationBundleOption(reminder->GetReminderId()); + std::vector> slots; + ErrCode errCode = advancedNotificationService_->GetSlotsByBundle(bundle, slots); + Uri uri = DEFAULT_NOTIFICATION_SOUND; + if (errCode != ERR_OK) { + ANSR_LOGW("Get sound uri fail, use default sound instead."); + return uri.GetSchemeSpecificPart(); + } + for (auto it = slots.begin(); it != slots.end(); ++it) { + if ((*it)->GetType() == reminder->GetSlotType()) { + uri = (*it)->GetSound(); + break; + } + } + return uri.GetSchemeSpecificPart(); +} + +void ReminderDataManager::StopSoundAndVibrationLocked(const sptr &reminder) +{ + std::lock_guard lock(ReminderDataManager::ALERT_MUTEX); + StopSoundAndVibration(reminder); +} + +void ReminderDataManager::StopSoundAndVibration(const sptr &reminder) +{ + if (reminder == nullptr) { + ANSR_LOGE("Stop sound and vibration failed as reminder is null."); + return; + } + if (alertingReminderId_ == -1 || (reminder->GetReminderId() != alertingReminderId_)) { + ANSR_LOGE("Stop sound and vibration failed as alertingReminder is illegal."); + return; + } + ANSR_LOGD("Stop sound and vibration, reminderId=%{public}d", reminder->GetReminderId()); + soundPlayer_->Stop(); + sptr nullReminder = nullptr; + SetAlertingReminder(nullReminder); +} + +void ReminderDataManager::RemoveFromShowedReminders(const sptr &reminder) +{ + std::lock_guard lock(ReminderDataManager::SHOW_MUTEX); + for (auto it = shownReminderVector_.begin(); it != shownReminderVector_.end(); ++it) { + if ((*it)->GetReminderId() == reminder->GetReminderId()) { + ANSR_LOGD("Containers(shownVector) remove. reminderId=%{public}d", reminder->GetReminderId()); + shownReminderVector_.erase(it); + break; + } + } +} + std::vector> ReminderDataManager::RefreshRemindersLocked(uint8_t type) { std::lock_guard lock(ReminderDataManager::MUTEX); @@ -566,7 +911,6 @@ void ReminderDataManager::RemoveReminderLocked(const int32_t &reminderId) ANSR_LOGD("Containers(vector) remove. reminderId=%{public}d", reminderId); it = reminderVector_.erase(it); totalCount_--; - ANSR_LOGD("Remove reminder(id=%{public}d) success", reminderId); break; } else { ++it; @@ -576,26 +920,117 @@ void ReminderDataManager::RemoveReminderLocked(const int32_t &reminderId) if (it == notificationBundleOptionMap_.end()) { ANSR_LOGE("Remove notificationBundleOption(reminderId=%{public}d) fail", reminderId); } else { - ANSR_LOGD("Containers(map) remove: reminderId=%{public}d", reminderId); + ANSR_LOGD("Containers(map) remove. reminderId=%{public}d", reminderId); notificationBundleOptionMap_.erase(it); } } -void ReminderDataManager::ResetStates() +void ReminderDataManager::StartTimerLocked(const sptr &reminderRequest, TimerType type) +{ + std::lock_guard lock(ReminderDataManager::MUTEX); + StartTimer(reminderRequest, type); +} + +void ReminderDataManager::StartTimer(const sptr &reminderRequest, TimerType type) { - ANSR_LOGD("ResetStates"); - timerId_ = 0; - activeReminderId_ = -1; + sptr timer = MiscServices::TimeServiceClient::GetInstance(); + time_t now; + (void)time(&now); // unit is seconds. + uint64_t triggerTime = 0; + switch (type) { + case TimerType::TRIGGER_TIMER: { + if (timerId_ != 0) { + ANSR_LOGE("Trigger timer has already started."); + break; + } + triggerTime = reminderRequest->GetTriggerTimeInMilli(); + timerId_ = timer->CreateTimer(REMINDER_DATA_MANAGER->CreateTimerInfo(type)); + timer->StartTimer(timerId_, triggerTime); + SetActiveReminder(reminderRequest); + ANSR_LOGD("Start timing (next triggerTime), timerId=%{public}llu", (unsigned long long)timerId_); + break; + } + case TimerType::ALERTING_TIMER: { + if (timerIdAlerting_ != 0) { + ANSR_LOGE("Alerting time out timer has already started."); + break; + } + triggerTime = now * ReminderRequest::MILLI_SECONDS + + static_cast(reminderRequest->GetRingDuration() * ReminderRequest::MILLI_SECONDS); + timerIdAlerting_ = timer->CreateTimer(REMINDER_DATA_MANAGER->CreateTimerInfo(type)); + timer->StartTimer(timerIdAlerting_, triggerTime); + ANSR_LOGD( + "Start timing (alerting time out), timerId=%{public}llu", (unsigned long long)timerIdAlerting_); + break; + } + default: { + ANSR_LOGE("TimerType not support"); + break; + } + } + if (triggerTime == 0) { + ANSR_LOGW("Start timer fail"); + } else { + ANSR_LOGD("Timing info: now:(%{public}lld), tar:(%{public}llu)", + (long long)(now * ReminderRequest::MILLI_SECONDS), (unsigned long long)(triggerTime)); + } } -void ReminderDataManager::StartTimerLocked(sptr &reminderRequest) +void ReminderDataManager::StopTimerLocked(TimerType type) { - ANSR_LOGD("Start timer: millSeconds=%{public}llu", (unsigned long long)(reminderRequest->GetTriggerTimeInMilli())); std::lock_guard lock(ReminderDataManager::MUTEX); + StopTimer(type); +} + +void ReminderDataManager::StopTimer(TimerType type) +{ sptr timer = MiscServices::TimeServiceClient::GetInstance(); - timerId_ = timer->CreateTimer(REMINDER_DATA_MANAGER->CreateTimerInfo()); - timer->StartTimer(timerId_, reminderRequest->GetTriggerTimeInMilli()); - activeReminderId_ = reminderRequest->GetReminderId(); + uint64_t timerId = 0; + switch (type) { + case TimerType::TRIGGER_TIMER: { + timerId = timerId_; + ANSR_LOGD("Stop timing (next triggerTime)"); + break; + } + case TimerType::ALERTING_TIMER: { + timerId = timerIdAlerting_; + ANSR_LOGD("Stop timing (alerting time out)"); + break; + } + default: { + ANSR_LOGE("TimerType not support"); + break; + } + } + if (timerId == 0) { + ANSR_LOGD("Timer is not running"); + return; + } + ANSR_LOGD("Stop timer id=%{public}llu", (unsigned long long)timerId); + timer->StopTimer(timerId); + ResetStates(type); +} + +void ReminderDataManager::ResetStates(TimerType type) +{ + switch (type) { + case TimerType::TRIGGER_TIMER: { + ANSR_LOGD("ResetStates(activeReminder)"); + timerId_ = 0; + activeReminderId_ = -1; + break; + } + case TimerType::ALERTING_TIMER: { + ANSR_LOGD("ResetStates(alertingReminder)"); + timerIdAlerting_ = 0; + alertingReminderId_ = -1; + break; + } + default: { + ANSR_LOGE("TimerType not support"); + break; + } + } } } } \ No newline at end of file diff --git a/services/ans/src/reminder_event_manager.cpp b/services/ans/src/reminder_event_manager.cpp index 117c8312c..d085adff0 100644 --- a/services/ans/src/reminder_event_manager.cpp +++ b/services/ans/src/reminder_event_manager.cpp @@ -14,9 +14,14 @@ */ #include "ans_log_wrapper.h" +#include "appmgr/app_mgr_constants.h" +#include "bundle_mgr_interface.h" #include "common_event_manager.h" #include "common_event_support.h" #include "bundle_constants.h" +#include "if_system_ability_manager.h" +#include "iservice_registry.h" +#include "system_ability_definition.h" #include "reminder_event_manager.h" @@ -32,7 +37,9 @@ void ReminderEventManager::init(std::shared_ptr &reminderDa { MatchingSkills matchingSkills; matchingSkills.AddEvent(ReminderRequest::REMINDER_EVENT_ALARM_ALERT); + matchingSkills.AddEvent(ReminderRequest::REMINDER_EVENT_ALERT_TIMEOUT); matchingSkills.AddEvent(ReminderRequest::REMINDER_EVENT_CLOSE_ALERT); + matchingSkills.AddEvent(ReminderRequest::REMINDER_EVENT_SNOOZE_ALERT); matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED); matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_PACKAGE_DATA_CLEARED); matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_PACKAGE_RESTARTED); @@ -58,34 +65,37 @@ void ReminderEventManager::ReminderEventSubscriber::OnReceiveEvent(const EventFw { Want want = data.GetWant(); std::string action = want.GetAction(); - ANSR_LOGD("Recieved common event:%{public}s", action.c_str()); + ANSR_LOGI("Recieved common event:%{public}s", action.c_str()); if (action == ReminderRequest::REMINDER_EVENT_ALARM_ALERT) { - reminderDataManager_->ShowReminder(false); + reminderDataManager_->ShowActiveReminder(); + return; + } + if (action == ReminderRequest::REMINDER_EVENT_ALERT_TIMEOUT) { + reminderDataManager_->TerminateAlerting(want); return; } if (action == ReminderRequest::REMINDER_EVENT_CLOSE_ALERT) { reminderDataManager_->CloseReminder(want, true); return; } + if (action == ReminderRequest::REMINDER_EVENT_SNOOZE_ALERT) { + reminderDataManager_->SnoozeReminder(want); + return; + } if (action == ReminderRequest::REMINDER_EVENT_REMOVE_NOTIFICATION) { reminderDataManager_->CloseReminder(want, false); return; } if (action == CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED) { - OHOS::AppExecFwk::ElementName ele = want.GetElement(); - std::string bundleName = ele.GetBundleName(); - int uid = want.GetIntParam(OHOS::AppExecFwk::Constants::UID, -1); - ANSR_LOGD("bundleName=%{public}s, uid=%{public}d", bundleName.c_str(), uid); - sptr bundleOption = new NotificationBundleOption(bundleName, uid); - reminderDataManager_->CancelAllReminders(bundleOption); + HandlePackageRemove(want); return; } if (action == CommonEventSupport::COMMON_EVENT_PACKAGE_DATA_CLEARED) { - // todo + HandlePackageRemove(want); return; } if (action == CommonEventSupport::COMMON_EVENT_PACKAGE_RESTARTED) { - // todo + HandleProcessDied(want); return; } if (action == CommonEventSupport::COMMON_EVENT_TIMEZONE_CHANGED) { @@ -97,5 +107,43 @@ void ReminderEventManager::ReminderEventSubscriber::OnReceiveEvent(const EventFw return; } } + +void ReminderEventManager::ReminderEventSubscriber::HandlePackageRemove(OHOS::EventFwk::Want &want) const +{ + sptr bundleOption = GetBundleOption(want); + reminderDataManager_->CancelAllReminders(bundleOption); +} + +void ReminderEventManager::ReminderEventSubscriber::HandleProcessDied(OHOS::EventFwk::Want &want) const +{ + sptr bundleOption = GetBundleOption(want); + reminderDataManager_->OnProcessDiedLocked(bundleOption); +} + +sptr ReminderEventManager::ReminderEventSubscriber::GetBundleOption( + const OHOS::EventFwk::Want &want) const +{ + OHOS::AppExecFwk::ElementName ele = want.GetElement(); + std::string bundleName = ele.GetBundleName(); + int userId = want.GetIntParam(OHOS::AppExecFwk::Constants::USER_ID, -1); + int32_t uid = GetUid(userId, bundleName); + ANSR_LOGD("bundleName=%{public}s, uid=%{public}d", bundleName.c_str(), uid); + sptr bundleOption = new NotificationBundleOption(bundleName, uid); + return bundleOption; +} + +int32_t ReminderEventManager::ReminderEventSubscriber::GetUid(const int userId, const std::string bundleName) const +{ + AppExecFwk::ApplicationInfo info; + OHOS::sptr systemAbilityManager + = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + OHOS::sptr remoteObject + = systemAbilityManager->GetSystemAbility(OHOS::BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); + OHOS::sptr bundleMgr + = OHOS::iface_cast(remoteObject); + bundleMgr->GetApplicationInfo(bundleName, AppExecFwk::ApplicationFlag::GET_BASIC_APPLICATION_INFO, + static_cast(userId), info); + return static_cast(info.uid); +} } // namespace OHOS -} // namespace Notification \ No newline at end of file +} // namespace Notification diff --git a/services/ans/src/reminder_timer_info.cpp b/services/ans/src/reminder_timer_info.cpp index 3c7c39c87..486ae1d00 100644 --- a/services/ans/src/reminder_timer_info.cpp +++ b/services/ans/src/reminder_timer_info.cpp @@ -44,19 +44,7 @@ void ReminderTimerInfo::SetWantAgent(std::shared_ptr Date: Mon, 24 Jan 2022 22:16:19 +0800 Subject: [PATCH 02/10] fix codeCheck Signed-off-by: derek Change-Id: I799007a8f24844f659a78f302d636aedff8187e9 --- .../kits/napi/ans/src/reminder/publish.cpp | 24 +++++++------------ 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/interfaces/kits/napi/ans/src/reminder/publish.cpp b/interfaces/kits/napi/ans/src/reminder/publish.cpp index 2f792d959..162dca0a3 100644 --- a/interfaces/kits/napi/ans/src/reminder/publish.cpp +++ b/interfaces/kits/napi/ans/src/reminder/publish.cpp @@ -206,10 +206,8 @@ napi_value CancelReminder(napi_env env, napi_callback_info info) napi_delete_reference(env, asynccallbackinfo->info.callback); } napi_delete_async_work(env, asynccallbackinfo->asyncWork); - if (asynccallbackinfo) { - delete asynccallbackinfo; - asynccallbackinfo = nullptr; - } + delete asynccallbackinfo; + asynccallbackinfo = nullptr; ANSR_LOGI("Cancel napi_create_async_work complete end"); }, (void *)asynccallbackinfo, @@ -262,10 +260,8 @@ napi_value CancelAllReminders(napi_env env, napi_callback_info info) napi_delete_reference(env, asynccallbackinfo->info.callback); } napi_delete_async_work(env, asynccallbackinfo->asyncWork); - if (asynccallbackinfo) { - delete asynccallbackinfo; - asynccallbackinfo = nullptr; - } + delete asynccallbackinfo; + asynccallbackinfo = nullptr; ANSR_LOGD("CancelAll napi_create_async_work complete end"); }, (void *)asynccallbackinfo, @@ -568,10 +564,8 @@ napi_value GetValidReminders(napi_env env, napi_callback_info info) napi_delete_reference(env, asynccallbackinfo->info.callback); } napi_delete_async_work(env, asynccallbackinfo->asyncWork); - if (asynccallbackinfo) { - delete asynccallbackinfo; - asynccallbackinfo = nullptr; - } + delete asynccallbackinfo; + asynccallbackinfo = nullptr; }, (void *)asynccallbackinfo, &asynccallbackinfo->asyncWork); @@ -631,10 +625,8 @@ napi_value PublishReminder(napi_env env, napi_callback_info info) napi_delete_reference(env, asynccallbackinfo->info.callback); } napi_delete_async_work(env, asynccallbackinfo->asyncWork); - if (asynccallbackinfo) { - delete asynccallbackinfo; - asynccallbackinfo = nullptr; - } + delete asynccallbackinfo; + asynccallbackinfo = nullptr; ANSR_LOGI("Publish napi_create_async_work complete end"); }, (void *)asynccallbackinfo, -- Gitee From a84b926af61382890f2031638ff65909dbc4ebdb Mon Sep 17 00:00:00 2001 From: derek Date: Tue, 25 Jan 2022 17:22:02 +0800 Subject: [PATCH 03/10] fix codeCheck Signed-off-by: derek Change-Id: I8ac924a5c41b79f4c478bbcffeb2f9770cf4b5ac --- .../ans/native/src/reminder_request.cpp | 65 +++++++++++-------- .../ans/native/src/reminder_request_alarm.cpp | 38 ++++++----- .../native/src/reminder_request_calendar.cpp | 32 ++++++--- .../reminder_request_calendar_test.cpp | 52 +++++++++++++-- .../ans/native/include/reminder_request.h | 13 +++- .../include/reminder_request_calendar.h | 2 - .../kits/napi/ans/src/reminder/publish.cpp | 1 - services/ans/include/reminder_timer_info.h | 3 +- services/ans/src/reminder_data_manager.cpp | 4 +- 9 files changed, 145 insertions(+), 65 deletions(-) diff --git a/frameworks/ans/native/src/reminder_request.cpp b/frameworks/ans/native/src/reminder_request.cpp index bb8245dfb..f50bdc0a1 100644 --- a/frameworks/ans/native/src/reminder_request.cpp +++ b/frameworks/ans/native/src/reminder_request.cpp @@ -107,17 +107,13 @@ bool ReminderRequest::CanShow() const std::string ReminderRequest::Dump() const { - struct tm *timeInfo; - const time_t nextTriggerTime = static_cast(triggerTimeInMilli_ / 1000); - timeInfo = localtime(&nextTriggerTime); - uint8_t dateTimeLen = 80; - char dateTimeBuffer[dateTimeLen]; - (void)strftime(dateTimeBuffer, dateTimeLen, "%Y-%m-%d %H:%M:%S", timeInfo); + const time_t nextTriggerTime = static_cast(triggerTimeInMilli_ / MILLI_SECONDS); + std::string dateTimeInfo = GetTimeInfoInner(nextTriggerTime, TimeFormat::YMDHMS); return "Reminder[" "reminderId=" + std::to_string(reminderId_) + ", type=" + std::to_string(static_cast(reminderType_)) + ", state=" + GetState(state_) + - ", nextTriggerTime=" + dateTimeBuffer + + ", nextTriggerTime=" + dateTimeInfo.c_str() + "]"; } @@ -231,7 +227,8 @@ bool ReminderRequest::HandleSysTimeChange(uint64_t oriTriggerTime, uint64_t optT return showImmediately; } -bool ReminderRequest::HandleTimeZoneChange(uint64_t oldZoneTriggerTime, uint64_t newZoneTriggerTime, uint64_t optTriggerTime) +bool ReminderRequest::HandleTimeZoneChange( + uint64_t oldZoneTriggerTime, uint64_t newZoneTriggerTime, uint64_t optTriggerTime) { if (isExpired_) { return false; @@ -449,8 +446,8 @@ bool ReminderRequest::ShouldShowImmediately() const return true; } -std::map ReminderRequest::GetActionButtons() const +std::map ReminderRequest::GetActionButtons( + ) const { return actionButtonMap_; } @@ -573,7 +570,7 @@ bool ReminderRequest::UpdateNextReminder() void ReminderRequest::UpdateNotificationRequest(UpdateNotificationType type, std::string extra) { - switch(type) { + switch (type) { case UpdateNotificationType::COMMON: { ANSR_LOGI("UpdateNotification common information"); UpdateNotificationCommon(); @@ -861,13 +858,7 @@ bool ReminderRequest::IsAlerting() const std::string ReminderRequest::GetDateTimeInfo(const time_t &timeInSecond) const { - struct tm *timeInfo; - timeInfo = localtime(&timeInSecond); - uint8_t dateTimeLen = 80; - char dateTimeBuffer[dateTimeLen]; - strftime(dateTimeBuffer, dateTimeLen, "%Y-%m-%d %H:%M:%S", timeInfo); - std::string dateTimeInfo(dateTimeBuffer); - return dateTimeInfo; + return GetTimeInfoInner(timeInSecond, TimeFormat::YMDHMS); } uint64_t ReminderRequest::GetNowInstantMilli() const @@ -886,17 +877,39 @@ std::string ReminderRequest::GetShowTime(const uint64_t showTime) const if (reminderType_ == ReminderType::TIMER) { return ""; } else { - struct tm *timeInfo; - const time_t showTimeInSecond = static_cast(showTime / 1000); - timeInfo = localtime(&showTimeInSecond); - uint8_t dateTimeLen = 80; - char dateTimeBuffer[dateTimeLen]; - strftime(dateTimeBuffer, dateTimeLen, "%H:%M", timeInfo); - std::string time = dateTimeBuffer; - return time; + const time_t showTimeInSecond = static_cast(showTime / MILLI_SECONDS); + return GetTimeInfoInner(showTimeInSecond, TimeFormat::HM); } } +std::string ReminderRequest::GetTimeInfoInner(const time_t &timeInSecond, const TimeFormat &format) const +{ + uint8_t dateTimeLen = 80; + char dateTimeBuffer[dateTimeLen]; + struct tm *timeInfo; + timeInfo = localtime(&timeInSecond); + if (timeInfo == nullptr) { + ANSR_LOGW("GetTimeInfoInner fail."); + } else { + switch (format) { + case TimeFormat::YMDHMS: { + (void)strftime(dateTimeBuffer, dateTimeLen, "%Y-%m-%d %H:%M:%S", timeInfo); + break; + } + case TimeFormat::HM: { + (void)strftime(dateTimeBuffer, dateTimeLen, "%H:%M", timeInfo); + break; + } + default: { + ANSR_LOGW("Time format not support."); + break; + } + } + } + std::string dateTimeInfo(dateTimeBuffer); + return dateTimeInfo; +} + std::string ReminderRequest::GetState(const uint8_t state) const { std::string stateInfo = "'"; diff --git a/frameworks/ans/native/src/reminder_request_alarm.cpp b/frameworks/ans/native/src/reminder_request_alarm.cpp index 918736dcd..f1334689b 100644 --- a/frameworks/ans/native/src/reminder_request_alarm.cpp +++ b/frameworks/ans/native/src/reminder_request_alarm.cpp @@ -103,6 +103,17 @@ uint64_t ReminderRequestAlarm::GetNextTriggerTime(bool forceToGetNext) const time_t now; (void)time(&now); // unit is seconds. struct tm *nowTime = localtime(&now); + if (nowTime == nullptr) { + ANSR_LOGW("Get local time fail."); + return 0; + } + + ANSR_LOGD("Now: year=%{public}d, mon=%{public}d, day=%{public}d, hour=%{public}d, " + "min=%{public}d, sec=%{public}d, week=%{public}d, \n Target: tar_hour=%{public}d, tar_min=%{public}d", + GetActualTime(TimeTransferType::YEAR, nowTime->tm_year), + GetActualTime(TimeTransferType::MONTH, nowTime->tm_mon), + nowTime->tm_mday, nowTime->tm_hour, nowTime->tm_min, nowTime->tm_sec, + GetActualTime(TimeTransferType::WEEK, nowTime->tm_wday), hour_, minute_); struct tm tar; tar.tm_year = nowTime->tm_year; @@ -112,13 +123,6 @@ uint64_t ReminderRequestAlarm::GetNextTriggerTime(bool forceToGetNext) const tar.tm_min = minute_; tar.tm_sec = 0; - ANSR_LOGD("Now: year=%{public}d, mon=%{public}d, day=%{public}d, hour=%{public}d, " - "min=%{public}d, sec=%{public}d, week=%{public}d, \n Target: tar_hour=%{public}d, tar_min=%{public}d", - GetActualTime(TimeTransferType::YEAR, nowTime->tm_year), - GetActualTime(TimeTransferType::MONTH, nowTime->tm_mon), - nowTime->tm_mday, nowTime->tm_hour, nowTime->tm_min, nowTime->tm_sec, - GetActualTime(TimeTransferType::WEEK, nowTime->tm_wday), hour_, minute_); - const time_t target = mktime(&tar); int8_t nextDayInterval = GetNextAlarm(now, target); time_t nextTriggerTime = 0; @@ -134,6 +138,9 @@ uint64_t ReminderRequestAlarm::GetNextTriggerTime(bool forceToGetNext) const nextTriggerTime = target + nextDayInterval * HOURS_PER_DAY * SECONDS_PER_HOUR; } struct tm *test = localtime(&nextTriggerTime); + if (test == nullptr) { + return 0; + } ANSR_LOGI("NextTriggerTime: year=%{public}d, mon=%{public}d, day=%{public}d, hour=%{public}d, " "min=%{public}d, sec=%{public}d, week=%{public}d, nextTriggerTime=%{public}lld", GetActualTime(TimeTransferType::YEAR, test->tm_year), @@ -223,16 +230,15 @@ bool ReminderRequestAlarm::UpdateNextReminder() ANSR_LOGI("No need to update next triggerTime"); SetExpired(true); return false; + } + uint64_t nextTriggerTime = GetNextTriggerTime(true); + if (nextTriggerTime != INVALID_LONG_LONG_VALUE) { + ANSR_LOGI("Set next trigger time successful, reset dynamic snoozeTimes"); + SetTriggerTimeInMilli(nextTriggerTime); } else { - uint64_t nextTriggerTime = GetNextTriggerTime(true); - if (nextTriggerTime != INVALID_LONG_LONG_VALUE) { - ANSR_LOGI("Set next trigger time successful, reset dynamic snoozeTimes"); - SetTriggerTimeInMilli(nextTriggerTime); - } else { - ANSR_LOGW("Set reminder to expired"); - SetExpired(true); - return false; - } + ANSR_LOGW("Set reminder to expired"); + SetExpired(true); + return false; } } return true; diff --git a/frameworks/ans/native/src/reminder_request_calendar.cpp b/frameworks/ans/native/src/reminder_request_calendar.cpp index 42dbc3018..7e60eec85 100644 --- a/frameworks/ans/native/src/reminder_request_calendar.cpp +++ b/frameworks/ans/native/src/reminder_request_calendar.cpp @@ -26,8 +26,8 @@ const uint8_t ReminderRequestCalendar::DECEMBER = 12; const uint8_t ReminderRequestCalendar::DEFAULT_SNOOZE_TIMES = 3; ReminderRequestCalendar::ReminderRequestCalendar(const tm &dateTime, - const std::vector &repeatMonths, const std::vector &repeatDays) : - ReminderRequest(ReminderRequest::ReminderType::CALENDAR) + const std::vector &repeatMonths, const std::vector &repeatDays) + : ReminderRequest(ReminderRequest::ReminderType::CALENDAR) { // 1. record the infomation which designated by user at first time. firstDesignateYear_ = GetActualTime(TimeTransferType::YEAR, dateTime.tm_year); @@ -44,7 +44,11 @@ ReminderRequestCalendar::ReminderRequestCalendar(const tm &dateTime, uint64_t nextTriggerTime = INVALID_LONG_LONG_VALUE; if ((nextTriggerTime = GetNextTriggerTime()) != INVALID_LONG_LONG_VALUE) { time_t target = static_cast(nextTriggerTime / MILLI_SECONDS); - dateTime_ = *(localtime(&target)); + tm *tar =localtime(&target); + if (tar == nullptr) { + throw std::invalid_argument("Get localtime error"); + } + dateTime_ = *tar; } else { ANSR_LOGW("Not exist next trigger time, please check the param of ReminderRequestCalendar constructor."); throw std::invalid_argument( @@ -82,8 +86,12 @@ uint8_t ReminderRequestCalendar::GetDaysOfMonth(const uint16_t &year, const uint uint8_t february = 2; uint8_t leapMonth = 29; uint8_t nonLeapMonth = 28; + uint16_t solarYear = 400; + uint8_t leapParam1 = 4; + uint8_t leapParam2 = 100; if (month == february) { - days = ((((0 == year % 4) && (0 != year % 100)) || (0 == year % 400)) ? leapMonth : nonLeapMonth); + days = ((((0 == year % leapParam1) && (0 != year % leapParam2)) || (0 == year % solarYear)) + ? leapMonth : nonLeapMonth); } else { days = daysArray[month - 1]; } @@ -128,8 +136,13 @@ uint64_t ReminderRequestCalendar::GetNextTriggerTime() const { uint64_t triggerTimeInMilli = INVALID_LONG_LONG_VALUE; time_t now; - time(&now); // unit is seconds. - struct tm nowTime = *(localtime(&now)); + (void)time(&now); // unit is seconds. + tm *nowTmp = localtime(&now); + if (nowTmp == nullptr) { + ANSR_LOGW("Get local time fail."); + return triggerTimeInMilli; + } + struct tm nowTime = *nowTmp; nowTime.tm_sec = 0; struct tm tarTime; tarTime.tm_year = GetCTime(TimeTransferType::YEAR, firstDesignateYear_); @@ -232,7 +245,8 @@ bool ReminderRequestCalendar::IsRepeatMonth(uint8_t month) const return (repeatMonth_ & (1 << (month - 1))) > 0; } -bool ReminderRequestCalendar::IsRepeatDay(uint8_t day) const{ +bool ReminderRequestCalendar::IsRepeatDay(uint8_t day) const +{ return (repeatDay_ & (1 << (day - 1))) > 0; } @@ -289,7 +303,7 @@ void ReminderRequestCalendar::SetRepeatDaysOfMonth(const std::vector &r std::vector ReminderRequestCalendar::GetRepeatMonths() const { std::vector repeatMonths; - for (int i = 0; i < 12; i++) { + for (int i = 0; i < MAX_MONTHS_OF_YEAR; i++) { if (IsRepeatMonth(i + 1)) { repeatMonths.push_back(i + 1); } @@ -300,7 +314,7 @@ std::vector ReminderRequestCalendar::GetRepeatMonths() const std::vector ReminderRequestCalendar::GetRepeatDays() const { std::vector repeatDays; - for (int i = 0; i < 31; i++) { + for (int i = 0; i < MAX_DAYS_OF_MONTH; i++) { if (IsRepeatDay(i + 1)) { repeatDays.push_back(i + 1); } diff --git a/frameworks/ans/native/test/unittest/reminder_request_calendar_test.cpp b/frameworks/ans/native/test/unittest/reminder_request_calendar_test.cpp index 89767ab5f..4396dc228 100644 --- a/frameworks/ans/native/test/unittest/reminder_request_calendar_test.cpp +++ b/frameworks/ans/native/test/unittest/reminder_request_calendar_test.cpp @@ -35,10 +35,15 @@ public: ReminderHelper::CancelAllReminders(); } - std::shared_ptr CreateCalendar(tm &nowTime) { + std::shared_ptr CreateCalendar(tm &nowTime) + { time_t now; time(&now); // unit is seconds. - nowTime = *(localtime(&now)); + tm *tmp = localtime(&now); + if (tmp == nullptr) { + return nullptr; + } + nowTime = *tmp; nowTime.tm_year = 0; nowTime.tm_mon = 0; nowTime.tm_mday = 1; @@ -52,7 +57,8 @@ public: return calendar; } - bool IsVectorEqual(std::vector &vectorA, std::vector &vectorB) { + bool IsVectorEqual(std::vector &vectorA, std::vector &vectorB) + { if (vectorA.size() != vectorB.size()) { return false; } @@ -81,6 +87,9 @@ HWTEST_F(ReminderRequestCalendarTest, initDateTime_00100, Function | SmallTest | { struct tm nowTime; auto calendar = ReminderRequestCalendarTest::CreateCalendar(nowTime); + if (calendar == nullptr) { + EXPECT_TRUE(false) << "calendar is null"; + } int firstDesignateYear = calendar->GetActualTime(ReminderRequest::TimeTransferType::YEAR, nowTime.tm_year); EXPECT_TRUE(firstDesignateYear == calendar->GetFirstDesignateYear()) << "Set first designate year error."; } @@ -94,6 +103,9 @@ HWTEST_F(ReminderRequestCalendarTest, initDateTime_00200, Function | SmallTest | { struct tm nowTime; auto calendar = ReminderRequestCalendarTest::CreateCalendar(nowTime); + if (calendar == nullptr) { + EXPECT_TRUE(false) << "calendar is null"; + } int firstDesignateMonth = calendar->GetActualTime(ReminderRequest::TimeTransferType::MONTH, nowTime.tm_mon); EXPECT_TRUE(firstDesignateMonth == calendar->GetFirstDesignageMonth()) << "Set first designate month error."; } @@ -107,6 +119,9 @@ HWTEST_F(ReminderRequestCalendarTest, initDateTime_00300, Function | SmallTest | { struct tm nowTime; auto calendar = ReminderRequestCalendarTest::CreateCalendar(nowTime); + if (calendar == nullptr) { + EXPECT_TRUE(false) << "calendar is null"; + } int firstDesignateDay = nowTime.tm_mday; EXPECT_TRUE(firstDesignateDay == calendar->GetFirstDesignateDay()) << "Set first designate day error."; } @@ -120,7 +135,12 @@ HWTEST_F(ReminderRequestCalendarTest, initDateTime_00400, Function | SmallTest | { time_t now; time(&now); // unit is seconds. - struct tm nowTime = *(localtime(&now)); + tm *tmp = localtime(&now); + if (tmp == nullptr) { + EXPECT_TRUE(false) << "calendar is null"; + } + struct tm nowTime = *tmp; + std::vector repeatMonths; std::vector repeatDays; repeatMonths.push_back(1); @@ -156,7 +176,11 @@ HWTEST_F(ReminderRequestCalendarTest, initDateTime_00500, Function | SmallTest | { time_t now; time(&now); // unit is seconds. - struct tm nowTime = *(localtime(&now)); + tm *tmp = localtime(&now); + if (tmp == nullptr) { + EXPECT_TRUE(false) << "calendar is null"; + } + tm nowTime = *tmp; nowTime.tm_year += 1; std::vector repeatMonths; std::vector repeatDays; @@ -193,7 +217,11 @@ HWTEST_F(ReminderRequestCalendarTest, initDateTime_00600, Function | SmallTest | { time_t now; time(&now); // unit is seconds. - struct tm nowTime = *(localtime(&now)); + tm *tmp = localtime(&now); + if (tmp == nullptr) { + EXPECT_TRUE(false) << "calendar is null"; + } + tm nowTime = *tmp; std::vector repeatMonths; std::vector repeatDays; repeatMonths.push_back(1); @@ -229,7 +257,11 @@ HWTEST_F(ReminderRequestCalendarTest, initDateTime_00700, Function | SmallTest | { time_t now; time(&now); // unit is seconds. - struct tm nowTime = *(localtime(&now)); + tm *tmp = localtime(&now); + if (tmp == nullptr) { + EXPECT_TRUE(false) << "calendar is null"; + } + tm nowTime = *tmp; nowTime.tm_year += 1; std::vector repeatMonths; std::vector repeatDays; @@ -267,6 +299,9 @@ HWTEST_F(ReminderRequestCalendarTest, initDateTime_00800, Function | SmallTest | { struct tm nowTime; auto calendar = ReminderRequestCalendarTest::CreateCalendar(nowTime); + if (calendar == nullptr) { + EXPECT_TRUE(false) << "calendar is null"; + } EXPECT_TRUE(1 == calendar->GetHour()) << "Set hour error."; } @@ -279,6 +314,9 @@ HWTEST_F(ReminderRequestCalendarTest, initDateTime_00900, Function | SmallTest | { struct tm nowTime; auto calendar = ReminderRequestCalendarTest::CreateCalendar(nowTime); + if (calendar == nullptr) { + EXPECT_TRUE(false) << "calendar is null"; + } EXPECT_TRUE(1 == calendar->GetMinute()) << "Set minute error."; EXPECT_TRUE(0 == calendar->GetSecond()) << "Set seconds error."; } diff --git a/interfaces/innerkits/ans/native/include/reminder_request.h b/interfaces/innerkits/ans/native/include/reminder_request.h index 65b4ff193..3b06e3b07 100644 --- a/interfaces/innerkits/ans/native/include/reminder_request.h +++ b/interfaces/innerkits/ans/native/include/reminder_request.h @@ -87,6 +87,15 @@ public: WEEK }; + /** + * @brief Enumerates the Time format for print. + * + */ + enum class TimeFormat : uint8_t { + YMDHMS, + HM + }; + /** * @brief Attributes of action button. */ @@ -510,7 +519,8 @@ protected: ReminderRequest(); explicit ReminderRequest(ReminderType reminderType); std::string GetDateTimeInfo(const time_t &timeInSecond) const; - virtual uint64_t PreGetNextTriggerTimeIgnoreSnooze(bool ignoreRepeat, bool forceToGetNext) const { + virtual uint64_t PreGetNextTriggerTimeIgnoreSnooze(bool ignoreRepeat, bool forceToGetNext) const + { return INVALID_LONG_LONG_VALUE; } static const int BASE_YEAR; @@ -521,6 +531,7 @@ private: std::shared_ptr CreateWantAgent(AppExecFwk::ElementName &element) const; uint64_t GetNowInstantMilli() const; std::string GetShowTime(const uint64_t showTime) const; + std::string GetTimeInfoInner(const time_t &timeInSecond, const TimeFormat &format) const; std::string GetState(const uint8_t state) const; bool HandleSysTimeChange(uint64_t oriTriggerTime, uint64_t optTriggerTime); bool HandleTimeZoneChange(uint64_t oldZoneTriggerTime, uint64_t newZoneTriggerTime, uint64_t optTriggerTime); diff --git a/interfaces/innerkits/ans/native/include/reminder_request_calendar.h b/interfaces/innerkits/ans/native/include/reminder_request_calendar.h index a2b788cf7..bb7c25ae7 100644 --- a/interfaces/innerkits/ans/native/include/reminder_request_calendar.h +++ b/interfaces/innerkits/ans/native/include/reminder_request_calendar.h @@ -18,8 +18,6 @@ #include "reminder_request.h" -#include - namespace OHOS { namespace Notification { class ReminderRequestCalendar : public ReminderRequest { diff --git a/interfaces/kits/napi/ans/src/reminder/publish.cpp b/interfaces/kits/napi/ans/src/reminder/publish.cpp index 162dca0a3..16084497d 100644 --- a/interfaces/kits/napi/ans/src/reminder/publish.cpp +++ b/interfaces/kits/napi/ans/src/reminder/publish.cpp @@ -387,7 +387,6 @@ void ParseActionButtons(const napi_env &env, ReminderRequest &reminder, napi_val int index = 0; for (std::map::iterator it = actionButtonsMap.begin(); it != actionButtonsMap.end(); ++it) { - // create obj napi_value actionButton = nullptr; napi_create_object(env, &actionButton); diff --git a/services/ans/include/reminder_timer_info.h b/services/ans/include/reminder_timer_info.h index 043492369..0d8ddeb33 100644 --- a/services/ans/include/reminder_timer_info.h +++ b/services/ans/include/reminder_timer_info.h @@ -31,7 +31,8 @@ public: ReminderTimerInfo(ReminderTimerInfo &other) = delete; ReminderTimerInfo& operator = (const ReminderTimerInfo &other) = delete; - inline void SetAction(const std::string &action) { + inline void SetAction(const std::string &action) + { action_ = action; } diff --git a/services/ans/src/reminder_data_manager.cpp b/services/ans/src/reminder_data_manager.cpp index 584bb5dde..25c442475 100644 --- a/services/ans/src/reminder_data_manager.cpp +++ b/services/ans/src/reminder_data_manager.cpp @@ -501,8 +501,8 @@ void ReminderDataManager::ShowActiveReminderExtendLocked(sptr & void ReminderDataManager::ShowReminder(const sptr &reminder, const bool &isNeedToPlaySound, const bool &isNeedToStartNext, const bool &isSysTimeChanged, const bool &needScheduleTimeout) { - ANSR_LOGD("Show the reminder(Play sound: %{public}d), %{public}s" - , static_cast(isNeedToPlaySound), reminder->Dump().c_str()); + ANSR_LOGD("Show the reminder(Play sound: %{public}d), %{public}s", + static_cast(isNeedToPlaySound), reminder->Dump().c_str()); int32_t reminderId = reminder->GetReminderId(); sptr bundleOption = FindNotificationBundleOption(reminderId); sptr notificationRequest = reminder->GetNotificationRequest(); -- Gitee From 64021336b62c9f60fcf78dc9ea0c93f0b86ec423 Mon Sep 17 00:00:00 2001 From: derek Date: Tue, 25 Jan 2022 17:30:22 +0800 Subject: [PATCH 04/10] fix gn format Signed-off-by: derek Change-Id: Ie1e94ede88d2539b49d1ae409211b6c4ad54e8cc --- frameworks/ans/test/moduletest/BUILD.gn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/ans/test/moduletest/BUILD.gn b/frameworks/ans/test/moduletest/BUILD.gn index 2c117a4cf..02b2a944d 100644 --- a/frameworks/ans/test/moduletest/BUILD.gn +++ b/frameworks/ans/test/moduletest/BUILD.gn @@ -341,11 +341,11 @@ group("moduletest") { deps = [] deps += [ + ":ReminderAgentTest", ":ReminderAgentTest", ":ans_fw_module_test", ":ans_innerkits_module_publish_test", ":ans_innerkits_module_setting_test", ":ans_innerkits_module_slot_test", - ":ReminderAgentTest", ] } -- Gitee From 332dae069c5534f0b22ef6b695813d58177d74a3 Mon Sep 17 00:00:00 2001 From: derek Date: Tue, 25 Jan 2022 19:50:12 +0800 Subject: [PATCH 05/10] fix codeCheck Signed-off-by: derek Change-Id: If8b61587f63c0bf8fdf00352833793757f8ac5ef --- frameworks/ans/native/src/reminder_request.cpp | 7 +++---- frameworks/ans/native/src/reminder_request_calendar.cpp | 2 +- .../test/unittest/reminder_request_calendar_test.cpp | 8 ++++---- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/frameworks/ans/native/src/reminder_request.cpp b/frameworks/ans/native/src/reminder_request.cpp index f50bdc0a1..92b8a4bcb 100644 --- a/frameworks/ans/native/src/reminder_request.cpp +++ b/frameworks/ans/native/src/reminder_request.cpp @@ -246,7 +246,7 @@ bool ReminderRequest::HandleTimeZoneChange( } else { // case2. timezone change to larger time_t now; - time(&now); // unit is seconds. + (void)time(&now); // unit is seconds. if (static_cast(now) < 0) { ANSR_LOGE("Get now time error"); return false; @@ -864,7 +864,7 @@ std::string ReminderRequest::GetDateTimeInfo(const time_t &timeInSecond) const uint64_t ReminderRequest::GetNowInstantMilli() const { time_t now; - time(&now); // unit is seconds. + (void)time(&now); // unit is seconds. if (static_cast(now) < 0) { ANSR_LOGE("Get now time error"); return 0; @@ -886,8 +886,7 @@ std::string ReminderRequest::GetTimeInfoInner(const time_t &timeInSecond, const { uint8_t dateTimeLen = 80; char dateTimeBuffer[dateTimeLen]; - struct tm *timeInfo; - timeInfo = localtime(&timeInSecond); + struct tm *timeInfo = localtime(&timeInSecond); if (timeInfo == nullptr) { ANSR_LOGW("GetTimeInfoInner fail."); } else { diff --git a/frameworks/ans/native/src/reminder_request_calendar.cpp b/frameworks/ans/native/src/reminder_request_calendar.cpp index 7e60eec85..2fa11c53b 100644 --- a/frameworks/ans/native/src/reminder_request_calendar.cpp +++ b/frameworks/ans/native/src/reminder_request_calendar.cpp @@ -44,7 +44,7 @@ ReminderRequestCalendar::ReminderRequestCalendar(const tm &dateTime, uint64_t nextTriggerTime = INVALID_LONG_LONG_VALUE; if ((nextTriggerTime = GetNextTriggerTime()) != INVALID_LONG_LONG_VALUE) { time_t target = static_cast(nextTriggerTime / MILLI_SECONDS); - tm *tar =localtime(&target); + tm *tar = localtime(&target); if (tar == nullptr) { throw std::invalid_argument("Get localtime error"); } diff --git a/frameworks/ans/native/test/unittest/reminder_request_calendar_test.cpp b/frameworks/ans/native/test/unittest/reminder_request_calendar_test.cpp index 4396dc228..77c61bb7b 100644 --- a/frameworks/ans/native/test/unittest/reminder_request_calendar_test.cpp +++ b/frameworks/ans/native/test/unittest/reminder_request_calendar_test.cpp @@ -38,7 +38,7 @@ public: std::shared_ptr CreateCalendar(tm &nowTime) { time_t now; - time(&now); // unit is seconds. + (void)time(&now); // unit is seconds. tm *tmp = localtime(&now); if (tmp == nullptr) { return nullptr; @@ -134,7 +134,7 @@ HWTEST_F(ReminderRequestCalendarTest, initDateTime_00300, Function | SmallTest | HWTEST_F(ReminderRequestCalendarTest, initDateTime_00400, Function | SmallTest | Level1) { time_t now; - time(&now); // unit is seconds. + (void)time(&now); // unit is seconds. tm *tmp = localtime(&now); if (tmp == nullptr) { EXPECT_TRUE(false) << "calendar is null"; @@ -216,7 +216,7 @@ HWTEST_F(ReminderRequestCalendarTest, initDateTime_00500, Function | SmallTest | HWTEST_F(ReminderRequestCalendarTest, initDateTime_00600, Function | SmallTest | Level1) { time_t now; - time(&now); // unit is seconds. + (void)time(&now); // unit is seconds. tm *tmp = localtime(&now); if (tmp == nullptr) { EXPECT_TRUE(false) << "calendar is null"; @@ -256,7 +256,7 @@ HWTEST_F(ReminderRequestCalendarTest, initDateTime_00600, Function | SmallTest | HWTEST_F(ReminderRequestCalendarTest, initDateTime_00700, Function | SmallTest | Level1) { time_t now; - time(&now); // unit is seconds. + (void)time(&now); // unit is seconds. tm *tmp = localtime(&now); if (tmp == nullptr) { EXPECT_TRUE(false) << "calendar is null"; -- Gitee From a99ffb6af4aafc7ad928ee209527f999b20f755b Mon Sep 17 00:00:00 2001 From: derek Date: Wed, 26 Jan 2022 10:26:53 +0800 Subject: [PATCH 06/10] fix codeCheck Signed-off-by: derek Change-Id: Ifb5b3c7aee4c4a4e33a887799a24a616e0b56967 --- .../ans/native/src/reminder_request.cpp | 2 +- .../ans/native/include/reminder_request.h | 46 ++++++++++++++++--- .../native/include/reminder_request_alarm.h | 2 +- .../include/reminder_request_calendar.h | 2 +- .../native/include/reminder_request_timer.h | 2 +- 5 files changed, 44 insertions(+), 10 deletions(-) diff --git a/frameworks/ans/native/src/reminder_request.cpp b/frameworks/ans/native/src/reminder_request.cpp index 92b8a4bcb..3b27d3b01 100644 --- a/frameworks/ans/native/src/reminder_request.cpp +++ b/frameworks/ans/native/src/reminder_request.cpp @@ -82,7 +82,7 @@ ReminderRequest::ReminderRequest(ReminderType reminderType) maxScreenWantAgentInfo_ == nullptr ? std::make_shared() : maxScreenWantAgentInfo_; } -bool ReminderRequest::CanRemove() +bool ReminderRequest::CanRemove() const { if ((state_ & (REMINDER_STATUS_SHOWING | REMINDER_STATUS_ALERTING | REMINDER_STATUS_ACTIVE)) == 0) { return true; diff --git a/interfaces/innerkits/ans/native/include/reminder_request.h b/interfaces/innerkits/ans/native/include/reminder_request.h index 3b06e3b07..b67141415 100644 --- a/interfaces/innerkits/ans/native/include/reminder_request.h +++ b/interfaces/innerkits/ans/native/include/reminder_request.h @@ -89,7 +89,6 @@ public: /** * @brief Enumerates the Time format for print. - * */ enum class TimeFormat : uint8_t { YMDHMS, @@ -131,7 +130,7 @@ public: */ explicit ReminderRequest(const ReminderRequest &other); ReminderRequest& operator = (const ReminderRequest &other); - virtual ~ReminderRequest() {}; + virtual ~ReminderRequest() override {}; /** * @brief Marshal a NotificationRequest object into a Parcel. @@ -153,7 +152,7 @@ public: * * @return true if it can be removed automatically. */ - bool CanRemove(); + bool CanRemove() const; bool CanShow() const; @@ -292,7 +291,10 @@ public: bool IsShowing() const; /** - * @brief Close the reminder by manual. + * @brief Closes the reminder by manual. + * + * 1) Resets the state of "Alering/Showing/Snooze" + * 2) Resets snoozeTimesDynamic_ if update to next trigger time, otherwise set reminder to expired. * * @param updateNext Whether to update to next reminder. */ @@ -312,17 +314,50 @@ public: void OnSameNotificationIdCovered(); /** - * @brief Show the reminder on panel. TriggerTime will be updated to next. + * @brief Shows the reminder on panel. TriggerTime will be updated to next. * * @param isPlaySoundOrVibration true means it is play sound or vibration. * @param isSysTimeChanged true means it is called when the system time is changed by user, otherwise false. * @param allowToNotify true means that the notification will be shown as normal, otherwise false. */ void OnShow(bool isPlaySoundOrVibration, bool isSysTimeChanged, bool allowToNotify); + + /** + * @brief Reset the state of "Showing" when the reminder is shown failed. + */ void OnShowFail(); + + /** + * @brief Snooze the reminder by manual. + * + * 1) Updates the trigger time to the next one. + * 2) Updates the notification content for "Snooze". + * 3) Switchs the state from "Showing[, Alerting]" to "Snooze". + */ bool OnSnooze(); + + /** + * @brief Starts the reminder + * + * Sets the state from "Inactive" to "Active". + */ void OnStart(); + + /** + * @brief Stops the reminder. + * + * Sets the state from "Active" to "Inactive". + */ void OnStop(); + + /** + * @brief Terminate the alerting reminder, which is executed when the ring duration is over. + * + * 1) Disables the state of "Alerting". + * 2) Updates the notification content for "Alert". + * + * @return false if alerting state has already been set false before calling the method. + */ bool OnTerminate(); /** @@ -592,5 +627,4 @@ private: }; } // namespace Reminder } // namespace OHOS - #endif // BASE_NOTIFICATION_ANS_STANDARD_FRAMEWORKS_ANS_CORE_INCLUDE_REMINDER_REQUEST_H \ No newline at end of file diff --git a/interfaces/innerkits/ans/native/include/reminder_request_alarm.h b/interfaces/innerkits/ans/native/include/reminder_request_alarm.h index 5d7471eff..07239f1ea 100644 --- a/interfaces/innerkits/ans/native/include/reminder_request_alarm.h +++ b/interfaces/innerkits/ans/native/include/reminder_request_alarm.h @@ -47,7 +47,7 @@ public: */ explicit ReminderRequestAlarm(const ReminderRequestAlarm &other); ReminderRequestAlarm& operator = (const ReminderRequestAlarm &other); - ~ReminderRequestAlarm() {}; + ~ReminderRequestAlarm() override {}; /** * Obtains the repeat days vector. diff --git a/interfaces/innerkits/ans/native/include/reminder_request_calendar.h b/interfaces/innerkits/ans/native/include/reminder_request_calendar.h index bb7c25ae7..b315ad87f 100644 --- a/interfaces/innerkits/ans/native/include/reminder_request_calendar.h +++ b/interfaces/innerkits/ans/native/include/reminder_request_calendar.h @@ -54,7 +54,7 @@ public: explicit ReminderRequestCalendar(const ReminderRequestCalendar &other); ReminderRequestCalendar& operator = (const ReminderRequestCalendar &other); - ~ReminderRequestCalendar() {} + ~ReminderRequestCalendar() override {} inline uint16_t GetYear() const { diff --git a/interfaces/innerkits/ans/native/include/reminder_request_timer.h b/interfaces/innerkits/ans/native/include/reminder_request_timer.h index a33c0142e..9fc2362f2 100644 --- a/interfaces/innerkits/ans/native/include/reminder_request_timer.h +++ b/interfaces/innerkits/ans/native/include/reminder_request_timer.h @@ -40,7 +40,7 @@ public: */ explicit ReminderRequestTimer(const ReminderRequestTimer &other); ReminderRequestTimer& operator = (const ReminderRequestTimer &other); - ~ReminderRequestTimer() {}; + ~ReminderRequestTimer() override {}; uint64_t GetInitInfo() const; virtual bool OnDateTimeChange() override; -- Gitee From 2933f75494a297ce33b40d7c863855143b10411b Mon Sep 17 00:00:00 2001 From: derek Date: Wed, 26 Jan 2022 16:05:12 +0800 Subject: [PATCH 07/10] fix ringDuration stop sound Signed-off-by: derek Change-Id: If52fc465ca4f5bc2ee5afeb6bed00b6d13054f96 --- services/ans/include/reminder_event_manager.h | 2 +- services/ans/src/reminder_data_manager.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/services/ans/include/reminder_event_manager.h b/services/ans/include/reminder_event_manager.h index bfc72148d..09c908f49 100644 --- a/services/ans/include/reminder_event_manager.h +++ b/services/ans/include/reminder_event_manager.h @@ -44,7 +44,7 @@ private: void HandlePackageRemove(OHOS::EventFwk::Want &want) const; void HandleProcessDied(OHOS::EventFwk::Want &want) const; int32_t GetUid(const int userId, const std::string bundleName) const; - std::shared_ptr reminderDataManager_; + std::shared_ptr reminderDataManager_ = nullptr; }; }; } // namespace OHOS diff --git a/services/ans/src/reminder_data_manager.cpp b/services/ans/src/reminder_data_manager.cpp index 25c442475..8d73a2f03 100644 --- a/services/ans/src/reminder_data_manager.cpp +++ b/services/ans/src/reminder_data_manager.cpp @@ -874,6 +874,8 @@ void ReminderDataManager::StopSoundAndVibration(const sptr &rem } ANSR_LOGD("Stop sound and vibration, reminderId=%{public}d", reminder->GetReminderId()); soundPlayer_->Stop(); + soundPlayer_->Release(); + soundPlayer_ = nullptr; sptr nullReminder = nullptr; SetAlertingReminder(nullReminder); } -- Gitee From e81d8cb114623a0342584d58a30465155c0a9daf Mon Sep 17 00:00:00 2001 From: derek Date: Wed, 26 Jan 2022 16:35:30 +0800 Subject: [PATCH 08/10] add js test cases Signed-off-by: derek Change-Id: I9c1c30d853eb3e2d0700496cbf9b8296521f1179 --- frameworks/ans/test/moduletest/BUILD.gn | 5 +- ...lperTest.test.js => ReminderHelperTest.js} | 488 +++++++++++++----- frameworks/ans/test/moduletest/config.json | 2 +- 3 files changed, 369 insertions(+), 126 deletions(-) rename frameworks/ans/test/moduletest/{ReminderHelperTest.test.js => ReminderHelperTest.js} (54%) diff --git a/frameworks/ans/test/moduletest/BUILD.gn b/frameworks/ans/test/moduletest/BUILD.gn index 02b2a944d..83e278a9b 100644 --- a/frameworks/ans/test/moduletest/BUILD.gn +++ b/frameworks/ans/test/moduletest/BUILD.gn @@ -329,7 +329,7 @@ ohos_moduletest("ans_innerkits_module_setting_test") { part_name = "ans_standard" } -ohos_js_unittest("ReminderAgentTest") { +ohos_js_unittest("ReminderAgentJsTest") { module_out_path = module_output_path hap_profile = "./config.json" @@ -341,11 +341,10 @@ group("moduletest") { deps = [] deps += [ - ":ReminderAgentTest", - ":ReminderAgentTest", ":ans_fw_module_test", ":ans_innerkits_module_publish_test", ":ans_innerkits_module_setting_test", ":ans_innerkits_module_slot_test", + ":ReminderAgentJsTest", ] } diff --git a/frameworks/ans/test/moduletest/ReminderHelperTest.test.js b/frameworks/ans/test/moduletest/ReminderHelperTest.js similarity index 54% rename from frameworks/ans/test/moduletest/ReminderHelperTest.test.js rename to frameworks/ans/test/moduletest/ReminderHelperTest.js index d4b0c1895..c61a047ec 100644 --- a/frameworks/ans/test/moduletest/ReminderHelperTest.test.js +++ b/frameworks/ans/test/moduletest/ReminderHelperTest.js @@ -145,19 +145,13 @@ describe("ReminderHelperTest", function () { */ it("testReminderHelper005", 0, async function (done) { let mySlot = { - type: 3 + type: 2 } reminderAgent.addNotificationSlot(mySlot).then(() => { - expect(true).assertTrue(); - setTimeout(() => { - done(); - }, 500); - }, (error) => { - expect(false).assertTrue(); - setTimeout(() => { - done(); - }, 500); + let i = 0; + expect(i).assertEqual(0); }); + done(); }) /* @@ -167,36 +161,11 @@ describe("ReminderHelperTest", function () { * @tc.require: */ it("testReminderHelper006", 0, async function (done) { - let mySlot0 = { - type: 0 - } - let mySlot1 = { - type: 1 - } - let mySlot2 = { - type: 2 - } - let mySlot3 = { - type: 3 - } - let mySlot4 = { - type: 4 - } - function reminderCallback(err, data){ - if (err) { - expect(true).assertTrue(); - } else { - expect(false).assertTrue(); - } - setTimeout(() => { - done(); - }, 500); - } - reminderAgent.addNotificationSlot(mySlot0, reminderCallback); - reminderAgent.addNotificationSlot(mySlot1, reminderCallback); - reminderAgent.addNotificationSlot(mySlot2, reminderCallback); - reminderAgent.addNotificationSlot(mySlot3, reminderCallback); - reminderAgent.addNotificationSlot(mySlot4, reminderCallback); + reminderAgent.addNotificationSlot(3, (err, data) => { + let i = 0; + expect(i).assertEqual(0); + }); + done(); }) /* @@ -210,16 +179,25 @@ describe("ReminderHelperTest", function () { reminderType: reminderAgent.ReminderType.REMINDER_TYPE_TIMER, triggerTimeInSeconds: 100 } - reminderAgent.publishReminder(timer).then((reminderId) => { - reminderAgent.getValidReminders().then((reminders) => {}); - setTimeout(() => { - reminderAgent.cancelAllReminders().then(() => { - reminderAgent.getValidReminders().then((reminders) => { - expect(0).assertEqual(reminders.length); - }); + let calendar = { + reminderType: reminderAgent.ReminderType.REMINDER_TYPE_CALENDAR, + dateTime : { + year: 2025, + month: 10, + day: 10, + hour: 23, + minute: 30 + } + } + reminderAgent.publishReminder(timer).then((reminderId) => {}); + reminderAgent.publishReminder(calendar).then((reminderId) => {}); + setTimeout(() => { + reminderAgent.cancelAllReminders().then(() => { + reminderAgent.getValidReminders().then((reminders) => { + expect(reminders.length === 0).assertEqual(true); }); - }, 1000); - }); + }); + }, 5000); done(); }) @@ -234,16 +212,25 @@ describe("ReminderHelperTest", function () { reminderType: reminderAgent.ReminderType.REMINDER_TYPE_TIMER, triggerTimeInSeconds: 100 } - reminderAgent.publishReminder(timer, (error, reminderId) => { - reminderAgent.getValidReminders((err, reminders) => {}); - setTimeout(() => { - reminderAgent.cancelAllReminders((err, data) => { - reminderAgent.getValidReminders().then((reminders) => { - expect(0).assertEqual(reminders.length); - }); + let calendar = { + reminderType: reminderAgent.ReminderType.REMINDER_TYPE_CALENDAR, + dateTime : { + year: 2025, + month: 10, + day: 10, + hour: 23, + minute: 30 + } + } + reminderAgent.publishReminder(timer).then((reminderId) => {}); + reminderAgent.publishReminder(calendar).then((reminderId) => {}); + setTimeout(() => { + reminderAgent.cancelAllReminders((err, data) => { + reminderAgent.getValidReminders().then((reminders) => { + expect(reminders.length === 0).assertEqual(true); }); - }, 1000); - }); + }); + }, 5000); done(); }) @@ -256,7 +243,7 @@ describe("ReminderHelperTest", function () { it("testReminderHelper009", 0, async function (done) { let timer = { reminderType: reminderAgent.ReminderType.REMINDER_TYPE_TIMER, - triggerTimeInSeconds: 100 + triggerTimeInSeconds: 3 } let id = 1; let publishlength = -1; @@ -265,18 +252,14 @@ describe("ReminderHelperTest", function () { reminderAgent.publishReminder(timer).then(() => { reminderAgent.getValidReminders().then((reminders) => { publishlength=reminders.length - }); - setTimeout(() => { reminderAgent.cancelReminder(id).then(() => { reminderAgent.getValidReminders().then((reminders) => { cancellength = reminders.length - firstdiff = publishlength-cancellength; - if (firstdiff === 0) { - expect(0).assertEqual(firstdiff); - } + firstdiff = publishlength - cancellength; + expect(0).assertEqual(firstdiff); }); }); - }, 1000); + }); }); done(); }) @@ -290,33 +273,27 @@ describe("ReminderHelperTest", function () { it("testReminderHelper010", 0, async function (done) { let timer = { reminderType: reminderAgent.ReminderType.REMINDER_TYPE_TIMER, - triggerTimeInSeconds: 100 + triggerTimeInSeconds: 3 } - let id = 1; let publishlength = -1; let cancellength = -1; let firstdiff = -1; reminderAgent.publishReminder(timer).then(() => { reminderAgent.getValidReminders((err, reminders) => { publishlength = reminders.length; - }); - setTimeout(() => { - reminderAgent.cancelReminder(id,(err,data)=>{ + reminderAgent.cancelReminder(0, (err, data)=>{ reminderAgent.getValidReminders((err, reminders) => { cancellength = reminders.length; - firstdiff = publishlength-cancellength; - if (firstdiff === 0) { - expect(0).assertEqual(firstdiff); - } + firstdiff = publishlength - cancellength; + expect(0).assertEqual(firstdiff); }); }); - }, 1000); + }); }); done(); }) - - /* + /* * @tc.name: testReminderHelper011 * @tc.desc: test cancelReminder with exist reminder. * @tc.type: FUNC @@ -410,16 +387,15 @@ describe("ReminderHelperTest", function () { reminderType: reminderAgent.ReminderType.REMINDER_TYPE_TIMER, triggerTimeInSeconds: 100 } - reminderAgent.publishReminder(timer, (error, reminderId) => {}); - reminderAgent.publishReminder(alarm, (error, reminderId) => {}); - setTimeout(() => { - reminderAgent.getValidReminders().then((reminders) => { - if (reminders.length >= 2) { - let i = 0; - expect(0).assertEqual(i); - } - }); - }, 1000); + reminderAgent.cancelAllReminders((err, data) => { + reminderAgent.publishReminder(timer, (error, reminderId) => {}); + reminderAgent.publishReminder(alarm, (error, reminderId) => {}); + setTimeout(() => { + reminderAgent.getValidReminders().then((reminders) => { + expect(reminders.length).assertEqual(2); + }); + }, 1000); + }) done(); }) @@ -441,16 +417,15 @@ describe("ReminderHelperTest", function () { reminderType: reminderAgent.ReminderType.REMINDER_TYPE_TIMER, triggerTimeInSeconds: 100 } - reminderAgent.publishReminder(timer, (error, reminderId) => {}); - reminderAgent.publishReminder(alarm, (error, reminderId) => {}); - setTimeout(() => { - reminderAgent.getValidReminders((err, reminders) => { - if (reminders.length >= 2) { - let i = 0; - expect(0).assertEqual(i); - } - }); - }, 1000); + reminderAgent.cancelAllReminders((err, data) => { + reminderAgent.publishReminder(timer, (error, reminderId) => {}); + reminderAgent.publishReminder(alarm, (error, reminderId) => {}); + setTimeout(() => { + reminderAgent.getValidReminders((err, reminders) => { + expect(reminders.length).assertEqual(2); + }); + }, 1000); + }) done(); }) @@ -461,12 +436,12 @@ describe("ReminderHelperTest", function () { * @tc.require: */ it("testReminderHelper015", 0, function (done) { - function reminderCallback(err, data){ - let i = 0; - expect(0).assertEqual(i); - } - reminderAgent.removeNotificationSlot(0, reminderCallback); - done(); + function reminderCallback(err, data){ + let i = 0; + expect(0).assertEqual(i); + } + reminderAgent.removeNotificationSlot(0, reminderCallback); + done(); }) /* @@ -502,7 +477,7 @@ describe("ReminderHelperTest", function () { } reminderAgent.addNotificationSlot(tarRemoveSlot.type, (err, data) => { reminderAgent.removeNotificationSlot(tarRemoveSlot.type, (err, data) => { - expect(0).assertEqual(err.code); + expect(0).assertEqual(err.code); }); }); done(); @@ -520,7 +495,8 @@ describe("ReminderHelperTest", function () { } reminderAgent.addNotificationSlot(tarRemoveSlot.type, (err, data) => { reminderAgent.removeNotificationSlot(tarRemoveSlot.type).then(() => { - expect(0).assertEqual(err.code); + let i = 0; + expect(0).assertEqual(i); }); }); done(); @@ -537,10 +513,10 @@ describe("ReminderHelperTest", function () { reminderType: reminderAgent.ReminderType.REMINDER_TYPE_TIMER, triggerTimeInSeconds: 3 } - reminderAgent.publishReminder(timer).then((reminderId) => {}); + reminderAgent.publishReminder(timer).then((reminderId) => { }); setTimeout(() => { reminderAgent.getValidReminders().then((reminders) => { - expect(0).assertEqual(reminders.length); + expect(reminders.length === 0).assertEqual(true); }); }, 5000); done(); @@ -557,10 +533,10 @@ describe("ReminderHelperTest", function () { reminderType: reminderAgent.ReminderType.REMINDER_TYPE_TIMER, triggerTimeInSeconds: 3 } - reminderAgent.publishReminder(timer).then((reminderId) => {}); + reminderAgent.publishReminder(timer, (err, data) => { }); setTimeout(() => { reminderAgent.getValidReminders((err, reminders) => { - expect(0).assertEqual(reminders.length); + expect(reminders.length === 0).assertEqual(true); }); }, 5000); done(); @@ -576,13 +552,13 @@ describe("ReminderHelperTest", function () { let alarm = { reminderType: reminderAgent.ReminderType.REMINDER_TYPE_ALARM, hour: 21, - minute: 14 + minute: 14, + title: "this is title", + content: "this is content" } reminderAgent.publishReminder(alarm).then((reminderId) => { - if (reminderId) { - let i = 0; - expect(0).assertEqual(i); - } + let i = 0; + expect(i).assertEqual(0); }); done(); }) @@ -597,13 +573,13 @@ describe("ReminderHelperTest", function () { let alarm = { reminderType: reminderAgent.ReminderType.REMINDER_TYPE_ALARM, hour: 21, - minute: 14 + minute: 14, + title: "this is title", + content: "this is content" } function reminderCallback (err, reminderId) { - if (reminderId) { - let i = 0; - expect(0).assertEqual(i); - } + let i = 0; + expect(i).assertEqual(0); } reminderAgent.publishReminder(alarm, reminderCallback); done(); @@ -611,11 +587,277 @@ describe("ReminderHelperTest", function () { /* * @tc.name: testReminderHelper023 + * @tc.desc: test publishReminder + * @tc.type: FUNC + * @tc.require: + */ + it("testReminderHelper023", 0, function (done) { + let calendar = { + reminderType: reminderAgent.ReminderType.REMINDER_TYPE_CALENDAR, + dateTime : { + year: 2025, + month: 10, + day: 10, + hour: 23, + minute: 30 + }, + repeatMonths:[2], + repeatDays:[2], + actionButton:[ + { + title:"close", + type:0 + }, + { + title:"snooze", + type:1 + } + ], + wantAgent:{ + pkgName:"com.huawei.phone", + abilityName:"com.huawei.phone.MainAbility" + }, + maxScreenWantAgent:{ + pkgName:"com.huawei.phone", + abilityName:"com.huawei.phone.MainAbility" + }, + ringDuration:5, + snoozeTimes:2, + timeInterval:5, + title:"this is title", + content:"this is content", + expiredContent:"this reminder has expired", + snoozeContent:"remind later", + notificationId:100, + slotType:3 + } + reminderAgent.publishReminder(calendar).then((reminderId) => { + reminderAgent.getValidReminders().then((reminders) => { + for (let i = 0; i < reminders.length; i++) { + console.log("getValidReminders = " + JSON.stringify(reminders[i])); + console.log("getValidReminders, reminderType = " + reminders[i].reminderType); + for (let j = 0; j < reminders[i].actionButton.length; j++) { + console.log("getValidReminders, actionButton.title = " + reminders[i].actionButton[j].title); + console.log("getValidReminders, actionButton.type = " + reminders[i].actionButton[j].type); + } + console.log("getValidReminders, wantAgent.pkgName = " + reminders[i].wantAgent.pkgName); + console.log("getValidReminders, wantAgent.abilityName = " + reminders[i].wantAgent.abilityName); + console.log("getValidReminders, maxScreenWantAgent.pkgName = " + reminders[i].maxScreenWantAgent.pkgName); + console.log("getValidReminders, maxScreenWantAgent.abilityName = " + reminders[i].maxScreenWantAgent.abilityName); + expect(reminders[i].ringDuration).assertEqual(5); + console.log("getValidReminders, ringDuration = " + reminders[i].ringDuration); + expect(reminders[i].snoozeTimes).assertEqual(2); + console.log("getValidReminders, snoozeTimes = " + reminders[i].snoozeTimes); + console.log("getValidReminders, timeInterval = " + reminders[i].timeInterval); + expect(reminders[i].title).assertEqual("this is title"); + console.log("getValidReminders, title = " + reminders[i].title); + expect(reminders[i].content).assertEqual("this is content"); + console.log("getValidReminders, content = " + reminders[i].content); + expect(reminders[i].expiredContent).assertEqual("this reminder has expired"); + console.log("getValidReminders, expiredContent = " + reminders[i].expiredContent); + expect(reminders[i].snoozeContent).assertEqual("remind later"); + console.log("getValidReminders, snoozeContent = " + reminders[i].snoozeContent); + expect(reminders[i].notificationId).assertEqual(100); + console.log("getValidReminders, notificationId = " + reminders[i].notificationId); + console.log("getValidReminders, slotType = " + reminders[i].slotType); + } + }) + }); + done(); + }) + + /* + * @tc.name: testReminderHelper024 + * @tc.desc: test publishReminder + * @tc.type: FUNC + * @tc.require: + */ + it("testReminderHelper024", 0, async function (done) { + let calendar = { + reminderType: reminderAgent.ReminderType.REMINDER_TYPE_CALENDAR, + dateTime : { + year: 2025, + month: 10, + day: 10, + hour: 23, + minute: 30 + }, + repeatMonths:[2], + repeatDays:[2], + actionButton:[ + { + title:"close", + type:0 + }, + { + title:"snooze", + type:1 + } + ], + wantAgent:{ + pkgName:"com.huawei.phone", + abilityName:"com.huawei.phone.MainAbility" + }, + maxScreenWantAgent:{ + pkgName:"com.huawei.phone", + abilityName:"com.huawei.phone.MainAbility" + }, + ringDuration:5, + snoozeTimes:2, + timeInterval:5, + title:"this is title", + content:"this is content", + expiredContent:"this reminder has expired", + snoozeContent:"remind later", + notificationId:100, + slotType:3 + } + reminderAgent.publishReminder(calendar, (err,reminderId) => { + reminderAgent.getValidReminders().then((reminders) => { + for (let i = 0; i < reminders.length; i++) { + console.log("getValidReminders = " + JSON.stringify(reminders[i])); + console.log("getValidReminders, reminderType = " + reminders[i].reminderType); + for (let j = 0; j < reminders[i].actionButton.length; j++) { + console.log("getValidReminders, actionButton.title = " + reminders[i].actionButton[j].title); + console.log("getValidReminders, actionButton.type = " + reminders[i].actionButton[j].type); + } + console.log("getValidReminders, wantAgent.pkgName = " + reminders[i].wantAgent.pkgName); + console.log("getValidReminders, wantAgent.abilityName = " + reminders[i].wantAgent.abilityName); + console.log("getValidReminders, maxScreenWantAgent.pkgName = " + reminders[i].maxScreenWantAgent.pkgName); + console.log("getValidReminders, maxScreenWantAgent.abilityName = " + reminders[i].maxScreenWantAgent.abilityName); + expect(reminders[i].ringDuration).assertEqual(5); + console.log("getValidReminders, ringDuration = " + reminders[i].ringDuration); + expect(reminders[i].snoozeTimes).assertEqual(2); + console.log("getValidReminders, snoozeTimes = " + reminders[i].snoozeTimes); + console.log("getValidReminders, timeInterval = " + reminders[i].timeInterval); + expect(reminders[i].title).assertEqual("this is title"); + console.log("getValidReminders, title = " + reminders[i].title); + expect(reminders[i].content).assertEqual("this is content"); + console.log("getValidReminders, content = " + reminders[i].content); + expect(reminders[i].expiredContent).assertEqual("this reminder has expired"); + console.log("getValidReminders, expiredContent = " + reminders[i].expiredContent); + expect(reminders[i].snoozeContent).assertEqual("remind later"); + console.log("getValidReminders, snoozeContent = " + reminders[i].snoozeContent); + expect(reminders[i].notificationId).assertEqual(100); + console.log("getValidReminders, notificationId = " + reminders[i].notificationId); + console.log("getValidReminders, slotType = " + reminders[i].slotType); + } + }) + }); + done(); + }) + + /* + * @tc.name: testReminderHelper025 + * @tc.desc: test publishReminder + * @tc.type: FUNC + * @tc.require: + */ + it("testReminderHelper025", 0, async function (done) { + let calendar = { + reminderType: reminderAgent.ReminderType.REMINDER_TYPE_CALENDAR, + dateTime : { + year: 2025, + month: 10, + day: 10, + hour: 23, + minute: 30 + }, + repeatMonths:[2], + repeatDays:[2], + actionButton:[ + { + title:"close", + type:0 + }, + { + title:"snooze", + type:1 + } + ], + wantAgent:{ + pkgName:"com.huawei.phone", + abilityName:"com.huawei.phone.MainAbility" + }, + maxScreenWantAgent:{ + pkgName:"com.huawei.phone", + abilityName:"com.huawei.phone.MainAbility" + }, + ringDuration:5, + snoozeTimes:2, + timeInterval:5, + title:"this is title", + content:"this is content", + expiredContent:"this reminder has expired", + snoozeContent:"remind later", + notificationId:100, + slotType:3 + } + reminderAgent.publishReminder(calendar, (err, reminderId) => { + expect(typeof(reminderId) === 'number').assertEqual(true); + }); + done(); + }) + + /* + * @tc.name: testReminderHelper026 + * @tc.desc: test publishReminder + * @tc.type: FUNC + * @tc.require: + */ + it("testReminderHelper026", 0, async function (done) { + let calendar = { + reminderType: reminderAgent.ReminderType.REMINDER_TYPE_CALENDAR, + dateTime : { + year: 2025, + month: 10, + day: 10, + hour: 23, + minute: 30 + }, + repeatMonths:[2], + repeatDays:[2], + actionButton:[ + { + title:"close", + type:0 + }, + { + title:"snooze", + type:1 + } + ], + wantAgent:{ + pkgName:"com.huawei.phone", + abilityName:"com.huawei.phone.MainAbility" + }, + maxScreenWantAgent:{ + pkgName:"com.huawei.phone", + abilityName:"com.huawei.phone.MainAbility" + }, + ringDuration:5, + snoozeTimes:2, + timeInterval:5, + title:"this is title", + content:"this is content", + expiredContent:"this reminder has expired", + snoozeContent:"remind later", + notificationId:100, + slotType:3 + } + reminderAgent.publishReminder(calendar).then((reminderId) => { + expect(typeof(reminderId)).assertEqual('number'); + }); + done(); + }) + + /* + * @tc.name: testReminderHelper027 * @tc.desc: test publishReminder (max number limit of each application) * @tc.type: FUNC * @tc.require: */ - it("testReminderHelper023", 0, async function (done) { + it("testReminderHelper027", 0, async function (done) { let timer = { reminderType: reminderAgent.ReminderType.REMINDER_TYPE_TIMER, triggerTimeInSeconds: 100 @@ -623,9 +865,10 @@ describe("ReminderHelperTest", function () { let maxLimitNumsOfApp = 30; let firstId = 0; let secondId = 0; - let diffId = 0 + let diffId = 0; for (let i = 0; i < maxLimitNumsOfApp; i++) { (function (i) { + var i = i; setTimeout(function () { reminderAgent.publishReminder(timer).then((reminderId) => { if (i === 0) { @@ -635,6 +878,7 @@ describe("ReminderHelperTest", function () { secondId = reminderId diffId = secondId - firstId expect(29).assertEqual(diffId); + i = null } }); }, 500 * i); diff --git a/frameworks/ans/test/moduletest/config.json b/frameworks/ans/test/moduletest/config.json index d779db80d..7d3bb1663 100644 --- a/frameworks/ans/test/moduletest/config.json +++ b/frameworks/ans/test/moduletest/config.json @@ -8,7 +8,7 @@ }, "apiVersion": { "compatible": 4, - "target": 5 + "target": 8 } }, "deviceConfig": {}, -- Gitee From a873ab991dc75dbdd73b48b4673b934589382720 Mon Sep 17 00:00:00 2001 From: derek Date: Fri, 28 Jan 2022 09:50:38 +0800 Subject: [PATCH 09/10] fix codeCheck Signed-off-by: derek Change-Id: I6341fc8c2850df4593b67e347ddddba0c35aec8c --- .../ans/native/src/reminder_request_calendar.cpp | 2 +- .../ans/native/include/reminder_request_calendar.h | 2 +- services/ans/include/reminder_data_manager.h | 2 +- services/ans/src/reminder_data_manager.cpp | 12 ++++++------ 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/frameworks/ans/native/src/reminder_request_calendar.cpp b/frameworks/ans/native/src/reminder_request_calendar.cpp index 2fa11c53b..115c6fa0d 100644 --- a/frameworks/ans/native/src/reminder_request_calendar.cpp +++ b/frameworks/ans/native/src/reminder_request_calendar.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/interfaces/innerkits/ans/native/include/reminder_request_calendar.h b/interfaces/innerkits/ans/native/include/reminder_request_calendar.h index b315ad87f..8c6868e98 100644 --- a/interfaces/innerkits/ans/native/include/reminder_request_calendar.h +++ b/interfaces/innerkits/ans/native/include/reminder_request_calendar.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/services/ans/include/reminder_data_manager.h b/services/ans/include/reminder_data_manager.h index 531060b79..c1167f1ba 100644 --- a/services/ans/include/reminder_data_manager.h +++ b/services/ans/include/reminder_data_manager.h @@ -407,7 +407,7 @@ private: /** * Vector used to record all the reminders which has been shown on panel. */ - std::vector> shownReminderVector_; + std::vector> showedReminderVector_; /** * Map used to record all the bundle information of the reminders in system. diff --git a/services/ans/src/reminder_data_manager.cpp b/services/ans/src/reminder_data_manager.cpp index 8d73a2f03..18f09d8b6 100644 --- a/services/ans/src/reminder_data_manager.cpp +++ b/services/ans/src/reminder_data_manager.cpp @@ -176,14 +176,14 @@ void ReminderDataManager::GetValidReminders( void ReminderDataManager::AddToShowedReminders(const sptr &reminder) { std::lock_guard lock(ReminderDataManager::SHOW_MUTEX); - for (auto it = shownReminderVector_.begin(); it != shownReminderVector_.end(); ++it) { + for (auto it = showedReminderVector_.begin(); it != showedReminderVector_.end(); ++it) { if (reminder->GetReminderId() == (*it)->GetReminderId()) { ANSR_LOGD("Showed reminder is already exist"); return; } } ANSR_LOGD("Containers(shownVector) add. reminderId=%{public}d", reminder->GetReminderId()); - shownReminderVector_.push_back(reminder); + showedReminderVector_.push_back(reminder); } void ReminderDataManager::OnProcessDiedLocked(const sptr bundleOption) @@ -192,7 +192,7 @@ void ReminderDataManager::OnProcessDiedLocked(const sptrGetUid(); ANSR_LOGI("OnProcessDiedLocked, bundleName=%{public}s, uid=%{public}d", bundleName.c_str(), uid); std::lock_guard lock(ReminderDataManager::SHOW_MUTEX); - for (auto it = shownReminderVector_.begin(); it != shownReminderVector_.end(); ++it) { + for (auto it = showedReminderVector_.begin(); it != showedReminderVector_.end(); ++it) { int32_t reminderId = (*it)->GetReminderId(); auto mit = notificationBundleOptionMap_.find(reminderId); if (mit == notificationBundleOptionMap_.end()) { @@ -208,7 +208,7 @@ void ReminderDataManager::OnProcessDiedLocked(const sptrOnClose(false); ANSR_LOGD("Containers(shownVector) remove. reminderId=%{public}d", reminderId); - shownReminderVector_.erase(it); + showedReminderVector_.erase(it); --it; } } @@ -883,10 +883,10 @@ void ReminderDataManager::StopSoundAndVibration(const sptr &rem void ReminderDataManager::RemoveFromShowedReminders(const sptr &reminder) { std::lock_guard lock(ReminderDataManager::SHOW_MUTEX); - for (auto it = shownReminderVector_.begin(); it != shownReminderVector_.end(); ++it) { + for (auto it = showedReminderVector_.begin(); it != showedReminderVector_.end(); ++it) { if ((*it)->GetReminderId() == reminder->GetReminderId()) { ANSR_LOGD("Containers(shownVector) remove. reminderId=%{public}d", reminder->GetReminderId()); - shownReminderVector_.erase(it); + showedReminderVector_.erase(it); break; } } -- Gitee From 0509681c2e45c386b5bc3fb627f0f2d3987919e0 Mon Sep 17 00:00:00 2001 From: derek Date: Fri, 28 Jan 2022 11:03:32 +0800 Subject: [PATCH 10/10] fix gn format Signed-off-by: derek Change-Id: Id85bfbd120a574c0d0874d76e5612a706a5df5e0 --- frameworks/ans/test/moduletest/BUILD.gn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/ans/test/moduletest/BUILD.gn b/frameworks/ans/test/moduletest/BUILD.gn index 83e278a9b..1015a6845 100644 --- a/frameworks/ans/test/moduletest/BUILD.gn +++ b/frameworks/ans/test/moduletest/BUILD.gn @@ -341,10 +341,10 @@ group("moduletest") { deps = [] deps += [ + ":ReminderAgentJsTest", ":ans_fw_module_test", ":ans_innerkits_module_publish_test", ":ans_innerkits_module_setting_test", ":ans_innerkits_module_slot_test", - ":ReminderAgentJsTest", ] } -- Gitee