From 3533852b0a8ebf2b877ef6b0eef1419e760a639f Mon Sep 17 00:00:00 2001 From: derek Date: Mon, 28 Feb 2022 15:21:54 +0800 Subject: [PATCH] add database feature Signed-off-by: derek Change-Id: I7c68d6040a567b85d7f8b9dbea03fbbd332b615f --- frameworks/ans/core/BUILD.gn | 2 + frameworks/ans/native/BUILD.gn | 1 + .../ans/native/src/reminder_request.cpp | 339 ++++++++++++- .../ans/native/src/reminder_request_alarm.cpp | 60 +++ .../native/src/reminder_request_calendar.cpp | 116 +++++ frameworks/ans/native/src/reminder_store.cpp | 453 ++++++++++++++++++ frameworks/ans/native/test/unittest/BUILD.gn | 1 + .../ans/native/include/reminder_request.h | 88 ++++ .../native/include/reminder_request_alarm.h | 25 + .../include/reminder_request_calendar.h | 38 ++ .../native/include/reminder_request_timer.h | 8 + .../ans/native/include/reminder_store.h | 99 ++++ interfaces/kits/napi/ans/BUILD.gn | 1 + .../kits/napi/ans/src/reminder/BUILD.gn | 1 + .../advanced_notification_service_ability.h | 2 + services/ans/include/reminder_data_manager.h | 30 +- services/ans/include/reminder_event_manager.h | 11 + .../ans/src/advanced_notification_service.cpp | 4 - .../advanced_notification_service_ability.cpp | 3 + services/ans/src/reminder_data_manager.cpp | 91 +++- services/ans/src/reminder_event_manager.cpp | 39 ++ 21 files changed, 1394 insertions(+), 18 deletions(-) create mode 100644 frameworks/ans/native/src/reminder_store.cpp create mode 100644 interfaces/innerkits/ans/native/include/reminder_store.h diff --git a/frameworks/ans/core/BUILD.gn b/frameworks/ans/core/BUILD.gn index fdca50b6d..3294e9ac2 100644 --- a/frameworks/ans/core/BUILD.gn +++ b/frameworks/ans/core/BUILD.gn @@ -78,6 +78,7 @@ ohos_shared_library("ans_core") { "${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", + "${frameworks_path}/ans/native/src/reminder_store.cpp", ] configs = [ ":private_config" ] @@ -98,6 +99,7 @@ ohos_shared_library("ans_core") { "hiviewdfx_hilog_native:libhilog", "ipc:ipc_core", "multimedia_image_standard:image_native", + "native_appdatamgr:native_rdb", "os_account_standard:os_account_innerkits", "samgr_standard:samgr_proxy", "time_native:time_service", diff --git a/frameworks/ans/native/BUILD.gn b/frameworks/ans/native/BUILD.gn index a0aa9d6cc..74f56a311 100644 --- a/frameworks/ans/native/BUILD.gn +++ b/frameworks/ans/native/BUILD.gn @@ -90,6 +90,7 @@ ohos_shared_library("ans_innerkits") { "hiviewdfx_hilog_native:libhilog", "ipc:ipc_core", "multimedia_image_standard:image_native", + "native_appdatamgr:native_rdb", "samgr_standard:samgr_proxy", ] diff --git a/frameworks/ans/native/src/reminder_request.cpp b/frameworks/ans/native/src/reminder_request.cpp index 8c71b7f82..addf79e15 100644 --- a/frameworks/ans/native/src/reminder_request.cpp +++ b/frameworks/ans/native/src/reminder_request.cpp @@ -22,6 +22,7 @@ #include "want_agent_helper.h" #include "reminder_request.h" +#include "reminder_store.h" namespace OHOS { namespace Notification { @@ -37,6 +38,7 @@ 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 int ReminderRequest::BASE_YEAR = 1900; 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"; @@ -45,13 +47,13 @@ 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; +const std::string ReminderRequest::SEP_BUTTON_SINGLE = ""; +const std::string ReminderRequest::SEP_BUTTON_MULTI = ""; +const std::string ReminderRequest::SEP_WANT_AGENT = ""; ReminderRequest::ReminderRequest() { - wantAgentInfo_ = wantAgentInfo_ == nullptr ? std::make_shared() : wantAgentInfo_; - maxScreenWantAgentInfo_ = - maxScreenWantAgentInfo_ == nullptr ? std::make_shared() : maxScreenWantAgentInfo_; + InitServerObj(); } ReminderRequest::ReminderRequest(const ReminderRequest &other) @@ -79,12 +81,16 @@ ReminderRequest::ReminderRequest(const ReminderRequest &other) this->actionButtonMap_ = other.actionButtonMap_; } +ReminderRequest::ReminderRequest(int32_t reminderId) +{ + reminderId_ = reminderId; + InitServerObj(); +} + ReminderRequest::ReminderRequest(ReminderType reminderType) { reminderType_ = reminderType; - wantAgentInfo_ = wantAgentInfo_ == nullptr ? std::make_shared() : wantAgentInfo_; - maxScreenWantAgentInfo_ = - maxScreenWantAgentInfo_ == nullptr ? std::make_shared() : maxScreenWantAgentInfo_; + InitServerObj(); } bool ReminderRequest::CanRemove() const @@ -169,6 +175,10 @@ void ReminderRequest::InitUserId(const int &userId) userId_ = userId; } +void ReminderRequest::InitUid(const int32_t &uid) +{ + uid_ = uid; +} bool ReminderRequest::IsExpired() const { return isExpired_; @@ -372,6 +382,163 @@ bool ReminderRequest::OnTimeZoneChange() triggerTimeInMilli_, GetDurationSinceEpochInMilli(newZoneTriggerTime), nextTriggerTime); } +int64_t ReminderRequest::RecoveryInt64FromDb(const std::shared_ptr &resultSet, + const std::string &columnName, const DbRecoveryType &columnType) +{ + if (columnType == DbRecoveryType::INT) { + int value; + resultSet->GetInt(ReminderStore::GetColumnIndex(columnName), value); + return static_cast(value); + } + if (columnType == DbRecoveryType::LONG) { + int64_t value; + resultSet->GetLong(ReminderStore::GetColumnIndex(columnName), value); + return value; + } + ANSR_LOGE("Recovery data error"); + return 0; +} + +void ReminderRequest::RecoveryFromDb(const std::shared_ptr &resultSet) +{ + // reminderId + resultSet->GetInt(ReminderStore::GetColumnIndex(Instance::REMINDER_ID), reminderId_); + + // userId + resultSet->GetInt(ReminderStore::GetColumnIndex(Instance::USER_ID), userId_); + + // uid + resultSet->GetInt(ReminderStore::GetColumnIndex(Instance::UID), uid_); + + // reminderType + int reminderType; + resultSet->GetInt(ReminderStore::GetColumnIndex(Instance::REMINDER_TYPE), reminderType); + reminderType_ = ReminderType(reminderType); + + // reminderTime + reminderTimeInMilli_ = + static_cast(RecoveryInt64FromDb(resultSet, Instance::REMINDER_TIME, DbRecoveryType::LONG)); + + // triggerTime + triggerTimeInMilli_ = + static_cast(RecoveryInt64FromDb(resultSet, Instance::TRIGGER_TIME, DbRecoveryType::LONG)); + ANSR_LOGD("~~~~triggerTimeInMilli_=%{public}llu", triggerTimeInMilli_); + + // timeInterval + uint64_t timeIntervalInSecond = + static_cast(RecoveryInt64FromDb(resultSet, Instance::TIME_INTERVAL, DbRecoveryType::LONG)); + SetTimeInterval(timeIntervalInSecond); + + // snoozeTimes + snoozeTimes_ = static_cast(RecoveryInt64FromDb(resultSet, Instance::SNOOZE_TIMES, DbRecoveryType::INT)); + + // dynamicSnoozeTimes + snoozeTimesDynamic_ = + static_cast(RecoveryInt64FromDb(resultSet, Instance::DYNAMIC_SNOOZE_TIMES, DbRecoveryType::INT)); + + // ringDuration + uint64_t ringDurationInSecond = + static_cast(RecoveryInt64FromDb(resultSet, Instance::RING_DURATION, DbRecoveryType::LONG)); + SetRingDuration(ringDurationInSecond); + + // isExpired + std::string isExpired; + resultSet->GetString(ReminderStore::GetColumnIndex(Instance::IS_EXPIRED), isExpired); + isExpired_ = isExpired == "true" ? true : false; + + // state + // RecoveryUint8FromDb(resultSet, Instance::STATE, DbRecoveryType::INT, state_); + state_ = static_cast(RecoveryInt64FromDb(resultSet, Instance::STATE, DbRecoveryType::INT)); + + // action buttons + RecoveryActionButton(resultSet); + + // slotType + int slotType; + resultSet->GetInt(ReminderStore::GetColumnIndex(Instance::SLOT_ID), slotType); + slotType_ = NotificationConstant::SlotType(slotType); + + // notification id + resultSet->GetInt(ReminderStore::GetColumnIndex(Instance::NOTIFICATION_ID), notificationId_); + + // title + resultSet->GetString(ReminderStore::GetColumnIndex(Instance::TITLE), title_); + + // content + resultSet->GetString(ReminderStore::GetColumnIndex(Instance::CONTENT), content_); + + // snoozeContent + resultSet->GetString(ReminderStore::GetColumnIndex(Instance::SNOOZE_CONTENT), snoozeContent_); + + // expiredContent + resultSet->GetString(ReminderStore::GetColumnIndex(Instance::EXPIRED_CONTENT), expiredContent_); + + InitNotificationRequest(); // must set before wantAgent & maxScreenWantAgent + + // wantAgent + std::string wantAgent; + resultSet->GetString(ReminderStore::GetColumnIndex(Instance::AGENT), wantAgent); + RecoveryWantAgent(wantAgent, 0); + + // maxScreenWantAgent + std::string maxScreenWantAgent; + resultSet->GetString(ReminderStore::GetColumnIndex(Instance::MAX_SCREEN_AGENT), maxScreenWantAgent); + RecoveryWantAgent(wantAgent, 1); +} + +void ReminderRequest::RecoveryActionButton(const std::shared_ptr &resultSet) +{ + std::string actionButtonInfo; + resultSet->GetString(ReminderStore::GetColumnIndex(Instance::ACTION_BUTTON_INFO), actionButtonInfo); + std::vector multiButton = StringSplit(actionButtonInfo, SEP_BUTTON_MULTI); + for (auto it = multiButton.begin(); it != multiButton.end(); ++it) { + std::vector singleButton = StringSplit(*it, SEP_BUTTON_SINGLE); + SetActionButton(singleButton.at(1), ActionButtonType(std::stoi(singleButton.at(0), nullptr))); + } +} + +std::vector ReminderRequest::StringSplit(std::string source, const std::string &split) const +{ + size_t pos = 0; + std::vector result; + while ((pos = source.find(split)) != std::string::npos) { + std::string token = source.substr(0, pos); + if (!token.empty()) { + result.push_back(token); + } + source.erase(0, pos + split.length()); + } + if (!source.empty()) { + result.push_back(source); + } + return result; +} + +void ReminderRequest::RecoveryWantAgent(std::string wantAgentInfo, const uint8_t &type) +{ + std::vector info = StringSplit(wantAgentInfo, ReminderRequest::SEP_WANT_AGENT); + uint8_t minLen = 2; + if (info.size() < minLen) { + ANSR_LOGW("RecoveryWantAgent fail"); + return; + } + // AppExecFwk::ElementName wantAgent("", info.at(0), info.at(1)); + ANSR_LOGD("pkg=%{public}s, ability=%{public}s", info.at(0).c_str(), info.at(1).c_str()); + if (type == 0) { + auto wantAgentInfo = std::make_shared(); + wantAgentInfo->pkgName = info.at(0); + wantAgentInfo->abilityName = info.at(1); + SetWantAgentInfo(wantAgentInfo); + } else if (type == 1) { + auto maxScreenWantAgentInfo = std::make_shared(); + maxScreenWantAgentInfo->pkgName = info.at(0); + maxScreenWantAgentInfo->abilityName = info.at(1); + SetMaxScreenWantAgentInfo(maxScreenWantAgentInfo); + } else { + ANSR_LOGW("RecoveryWantAgent type not support"); + } +} + ReminderRequest& ReminderRequest::SetMaxScreenWantAgentInfo( const std::shared_ptr &maxScreenWantAgentInfo) { @@ -458,6 +625,11 @@ bool ReminderRequest::ShouldShowImmediately() const return true; } +uint8_t ReminderRequest::GetConstStateInactive() +{ + return REMINDER_STATUS_INACTIVE; +} + std::map ReminderRequest::GetActionButtons( ) const { @@ -560,6 +732,16 @@ uint64_t ReminderRequest::GetTriggerTimeInMilli() const return triggerTimeInMilli_; } +int ReminderRequest::GetUserId() const +{ + return userId_; +} + +int32_t ReminderRequest::GetUid() const +{ + return uid_; +} + std::shared_ptr ReminderRequest::GetWantAgentInfo() const { return wantAgentInfo_; @@ -866,10 +1048,16 @@ bool ReminderRequest::InitNotificationRequest() return false; } displayContent_ = content_; - AddActionButtons(true); return true; } +void ReminderRequest::InitServerObj() +{ + wantAgentInfo_ = wantAgentInfo_ == nullptr ? std::make_shared() : wantAgentInfo_; + maxScreenWantAgentInfo_ = + maxScreenWantAgentInfo_ == nullptr ? std::make_shared() : maxScreenWantAgentInfo_; +} + bool ReminderRequest::IsAlerting() const { return (state_ & REMINDER_STATUS_ALERTING) != 0; @@ -892,6 +1080,21 @@ std::string ReminderRequest::GetDateTimeInfo(const time_t &timeInSecond) const return GetTimeInfoInner(timeInSecond, TimeFormat::YMDHMS); } +std::string ReminderRequest::GetButtonInfo() const +{ + std::string info = ""; + bool isFirst = true; + for (auto it = actionButtonMap_.begin(); it != actionButtonMap_.end(); ++it) { + if (!isFirst) { + info += SEP_BUTTON_MULTI; + } + ActionButtonInfo buttonInfo = it->second; + info += std::to_string(static_cast(it->first)) + SEP_BUTTON_SINGLE + buttonInfo.title; + isFirst = false; + } + return info; +} + uint64_t ReminderRequest::GetNowInstantMilli() const { time_t now; @@ -1153,6 +1356,7 @@ void ReminderRequest::UpdateNotificationContent(const bool &setSnooze) // snooze the reminder by manual extendContent = GetShowTime(triggerTimeInMilli_) + snoozeContent_ == "" ? "" : (" (" + snoozeContent_ + ")"); + notificationRequest_->SetTapDismissed(false); } else { // the reminder is expired now, when timeInterval is 0 extendContent = GetShowTime(reminderTimeInMilli_) + @@ -1247,5 +1451,124 @@ int ReminderRequest::GetUserId(const int &uid) AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(uid, userId); return userId; } + +void ReminderRequest::AppendValuesBucket(const sptr &reminder, + const sptr &bundleOption, NativeRdb::ValuesBucket &values) +{ + values.PutInt(Instance::REMINDER_ID, reminder->GetReminderId()); + values.PutString(Instance::PKG_NAME, bundleOption->GetBundleName()); + values.PutInt(Instance::USER_ID, reminder->GetUserId()); + values.PutInt(Instance::UID, reminder->GetUid()); + values.PutString(Instance::APP_LABEL, ""); // no use + values.PutInt(Instance::REMINDER_TYPE, static_cast(reminder->GetReminderType())); + values.PutLong(Instance::REMINDER_TIME, reminder->GetReminderTimeInMilli()); + values.PutLong(Instance::TRIGGER_TIME, reminder->GetTriggerTimeInMilli()); + values.PutLong(Instance::RTC_TRIGGER_TIME, reminder->GetTriggerTimeInMilli()); // no use + values.PutLong(Instance::TIME_INTERVAL, reminder->GetTimeInterval()); + values.PutInt(Instance::SNOOZE_TIMES, reminder->GetSnoozeTimes()); + values.PutInt(Instance::DYNAMIC_SNOOZE_TIMES, reminder->GetSnoozeTimesDynamic()); + values.PutLong(Instance::RING_DURATION, reminder->GetRingDuration()); + values.PutString(Instance::IS_EXPIRED, reminder->IsExpired() ? "true" : "false"); + values.PutString(Instance::IS_ACTIVE, ""); // no use + values.PutInt(Instance::STATE, reminder->GetState()); + values.PutString(Instance::ZONE_ID, ""); // no use + values.PutString(Instance::HAS_SCHEDULED_TIMEOUT, ""); // no use + values.PutString(Instance::ACTION_BUTTON_INFO, reminder->GetButtonInfo()); + values.PutInt(Instance::SLOT_ID, reminder->GetSlotType()); + values.PutInt(Instance::NOTIFICATION_ID, reminder->GetNotificationId()); + values.PutString(Instance::TITLE, reminder->GetTitle()); + values.PutString(Instance::CONTENT, reminder->GetContent()); + values.PutString(Instance::SNOOZE_CONTENT, reminder->GetSnoozeContent()); + values.PutString(Instance::EXPIRED_CONTENT, reminder->GetExpiredContent()); + auto wantAgentInfo = reminder->GetWantAgentInfo(); + if (wantAgentInfo == nullptr) { + std::string info = "null" + ReminderRequest::SEP_WANT_AGENT + "null"; + values.PutString(Instance::AGENT, info); + } else { + values.PutString(Instance::AGENT, wantAgentInfo->pkgName + + ReminderRequest::SEP_WANT_AGENT + wantAgentInfo->abilityName); + } + auto maxScreenWantAgentInfo = reminder->GetMaxScreenWantAgentInfo(); + if (maxScreenWantAgentInfo == nullptr) { + std::string info = "null" + ReminderRequest::SEP_WANT_AGENT + "null"; + values.PutString(Instance::MAX_SCREEN_AGENT, info); + } else { + values.PutString(Instance::MAX_SCREEN_AGENT, maxScreenWantAgentInfo->pkgName + + ReminderRequest::SEP_WANT_AGENT + maxScreenWantAgentInfo->abilityName); + } +} + +const std::string ReminderRequest::Instance::REMINDER_ID = "reminder_id"; +const std::string ReminderRequest::Instance::PKG_NAME = "package_name"; +const std::string ReminderRequest::Instance::USER_ID = "user_id"; +const std::string ReminderRequest::Instance::UID = "uid"; +const std::string ReminderRequest::Instance::APP_LABEL = "app_label"; +const std::string ReminderRequest::Instance::REMINDER_TYPE = "reminder_type"; +const std::string ReminderRequest::Instance::REMINDER_TIME = "reminder_time"; +const std::string ReminderRequest::Instance::TRIGGER_TIME = "trigger_time"; +const std::string ReminderRequest::Instance::RTC_TRIGGER_TIME = "rtc_trigger_time"; +const std::string ReminderRequest::Instance::TIME_INTERVAL = "time_interval"; +const std::string ReminderRequest::Instance::SNOOZE_TIMES = "snooze_times"; +const std::string ReminderRequest::Instance::DYNAMIC_SNOOZE_TIMES = "dynamic_snooze_times"; +const std::string ReminderRequest::Instance::RING_DURATION = "ring_duration"; +const std::string ReminderRequest::Instance::IS_EXPIRED = "is_expired"; +const std::string ReminderRequest::Instance::IS_ACTIVE = "is_active"; +const std::string ReminderRequest::Instance::STATE = "state"; +const std::string ReminderRequest::Instance::ZONE_ID = "zone_id"; +const std::string ReminderRequest::Instance::HAS_SCHEDULED_TIMEOUT = "has_ScheduledTimeout"; +const std::string ReminderRequest::Instance::ACTION_BUTTON_INFO = "button_info"; +const std::string ReminderRequest::Instance::SLOT_ID = "slot_id"; +const std::string ReminderRequest::Instance::NOTIFICATION_ID = "notification_id"; +const std::string ReminderRequest::Instance::TITLE = "title"; +const std::string ReminderRequest::Instance::CONTENT = "content"; +const std::string ReminderRequest::Instance::SNOOZE_CONTENT = "snooze_content"; +const std::string ReminderRequest::Instance::EXPIRED_CONTENT = "expired_content"; +const std::string ReminderRequest::Instance::AGENT = "agent"; +const std::string ReminderRequest::Instance::MAX_SCREEN_AGENT = "maxScreen_agent"; + +std::string ReminderRequest::Instance::SQL_ADD_COLUMNS = ""; +std::vector ReminderRequest::Instance::COLUMNS; + +void ReminderRequest::Instance::Init() +{ + AddColumn(REMINDER_ID, "INTEGER PRIMARY KEY", false); + AddColumn(PKG_NAME, "TEXT NOT NULL", false); + AddColumn(USER_ID, "INT NOT NULL", false); + AddColumn(UID, "INT NOT NULL", false); + AddColumn(APP_LABEL, "TEXT", false); + AddColumn(REMINDER_TYPE, "INT NOT NULL", false); + AddColumn(REMINDER_TIME, "BIGINT NOT NULL", false); + AddColumn(TRIGGER_TIME, "BIGINT NOT NULL", false); + AddColumn(RTC_TRIGGER_TIME, "BIGINT NOT NULL", false); + AddColumn(TIME_INTERVAL, "BIGINT NOT NULL", false); + AddColumn(SNOOZE_TIMES, "INT NOT NULL", false); + AddColumn(DYNAMIC_SNOOZE_TIMES, "INT NOT NULL", false); + AddColumn(RING_DURATION, "BIGINT NOT NULL", false); + AddColumn(IS_EXPIRED, "TEXT NOT NULL", false); + AddColumn(IS_ACTIVE, "TEXT NOT NULL", false); + AddColumn(STATE, "INT NOT NULL", false); + AddColumn(ZONE_ID, "TEXT", false); + AddColumn(HAS_SCHEDULED_TIMEOUT, "TEXT", false); + AddColumn(ACTION_BUTTON_INFO, "TEXT", false); + AddColumn(SLOT_ID, "INT", false); + AddColumn(NOTIFICATION_ID, "INT NOT NULL", false); + AddColumn(TITLE, "TEXT", false); + AddColumn(CONTENT, "TEXT", false); + AddColumn(SNOOZE_CONTENT, "TEXT", false); + AddColumn(EXPIRED_CONTENT, "TEXT", false); + AddColumn(AGENT, "TEXT", false); + AddColumn(MAX_SCREEN_AGENT, "TEXT", false); +} + +void ReminderRequest::Instance::AddColumn( + const std::string &name, const std::string &type, const bool &isEnd) +{ + COLUMNS.push_back(name); + if (!isEnd) { + SQL_ADD_COLUMNS += name + " " + type + ", "; + } else { + SQL_ADD_COLUMNS += name + " " + type; + } +} } } diff --git a/frameworks/ans/native/src/reminder_request_alarm.cpp b/frameworks/ans/native/src/reminder_request_alarm.cpp index f5a549729..da672199a 100644 --- a/frameworks/ans/native/src/reminder_request_alarm.cpp +++ b/frameworks/ans/native/src/reminder_request_alarm.cpp @@ -16,6 +16,7 @@ #include "ans_log_wrapper.h" #include "reminder_request_alarm.h" +#include "reminder_store.h" namespace OHOS { namespace Notification { @@ -296,5 +297,64 @@ bool ReminderRequestAlarm::ReadFromParcel(Parcel &parcel) ANSR_LOGD("hour_=%{public}d, minute_=%{public}d, repeatDays_=%{public}d", hour_, minute_, repeatDays_); return true; } + +void ReminderRequestAlarm::RecoveryFromDb(const std::shared_ptr &resultSet) +{ + ReminderRequest::RecoveryFromDb(resultSet); + + // repeatDays + repeatDays_ = + static_cast(RecoveryInt64FromDb(resultSet, Instance::REPEAT_DAYS_OF_WEEK, DbRecoveryType::INT)); + + // hour + hour_ = + static_cast(RecoveryInt64FromDb(resultSet, Instance::ALARM_HOUR, DbRecoveryType::INT)); + + // minute + minute_ = + static_cast(RecoveryInt64FromDb(resultSet, Instance::ALARM_MINUTE, DbRecoveryType::INT)); +} + +void ReminderRequestAlarm::AppendValuesBucket(const sptr &reminder, + const sptr &bundleOption, NativeRdb::ValuesBucket &values) +{ + uint8_t repeatDays = 0; + uint8_t hour = 0; + uint8_t minute = 0; + if (reminder->GetReminderType() == ReminderRequest::ReminderType::ALARM) { + ReminderRequestAlarm* alarm = static_cast(reminder.GetRefPtr()); + repeatDays = alarm->GetRepeatDay(); + hour = alarm->GetHour(); + minute = alarm->GetMinute(); + } + values.PutInt(Instance::REPEAT_DAYS_OF_WEEK, repeatDays); + values.PutInt(Instance::ALARM_HOUR, hour); + values.PutInt(Instance::ALARM_MINUTE, minute); +} + +const std::string ReminderRequestAlarm::Instance::REPEAT_DAYS_OF_WEEK = "repeat_days_of_week"; +const std::string ReminderRequestAlarm::Instance::ALARM_HOUR = "alarm_hour"; +const std::string ReminderRequestAlarm::Instance::ALARM_MINUTE = "alarm_minute"; + +std::string ReminderRequestAlarm::Instance::SQL_ADD_COLUMNS = ""; +std::vector ReminderRequestAlarm::Instance::COLUMNS; + +void ReminderRequestAlarm::Instance::Init() +{ + AddColumn(REPEAT_DAYS_OF_WEEK, "INT", false); + AddColumn(ALARM_HOUR, "INT", false); + AddColumn(ALARM_MINUTE, "INT", true); +} + +void ReminderRequestAlarm::Instance::AddColumn( + const std::string &name, const std::string &type, const bool &isEnd) +{ + COLUMNS.push_back(name); + if (!isEnd) { + SQL_ADD_COLUMNS += name + " " + type + ", "; + } else { + SQL_ADD_COLUMNS += name + " " + type; + } +} } } \ No newline at end of file diff --git a/frameworks/ans/native/src/reminder_request_calendar.cpp b/frameworks/ans/native/src/reminder_request_calendar.cpp index 0809af129..7a715ee44 100644 --- a/frameworks/ans/native/src/reminder_request_calendar.cpp +++ b/frameworks/ans/native/src/reminder_request_calendar.cpp @@ -498,5 +498,121 @@ bool ReminderRequestCalendar::ReadFromParcel(Parcel &parcel) } return true; } + +void ReminderRequestCalendar::RecoveryFromDb(const std::shared_ptr &resultSet) +{ + ReminderRequest::RecoveryFromDb(resultSet); + + // repeatDay + repeatDay_ = static_cast(RecoveryInt64FromDb(resultSet, Instance::REPEAT_DAYS, DbRecoveryType::INT)); + + // repeatMonth + repeatMonth_ = + static_cast(RecoveryInt64FromDb(resultSet, Instance::REPEAT_MONTHS, DbRecoveryType::INT)); + + // firstDesignateYear + firstDesignateYear_ = + static_cast(RecoveryInt64FromDb(resultSet, Instance::FIRST_DESIGNATE_YEAR, DbRecoveryType::INT)); + + // firstDesignateMonth + firstDesignateMonth_ = + static_cast(RecoveryInt64FromDb(resultSet, Instance::FIRST_DESIGNATE_MONTH, DbRecoveryType::INT)); + + // firstDesignateDay + firstDesignateDay_ = + static_cast(RecoveryInt64FromDb(resultSet, Instance::FIRST_DESIGNATE_DAY, DbRecoveryType::INT)); + + // year + year_ = static_cast(RecoveryInt64FromDb(resultSet, Instance::CALENDAR_YEAR, DbRecoveryType::INT)); + + // month + month_ = static_cast(RecoveryInt64FromDb(resultSet, Instance::CALENDAR_MONTH, DbRecoveryType::INT)); + + // day + day_ = static_cast(RecoveryInt64FromDb(resultSet, Instance::CALENDAR_DAY, DbRecoveryType::INT)); + + // hour + hour_ = static_cast(RecoveryInt64FromDb(resultSet, Instance::CALENDAR_HOUR, DbRecoveryType::INT)); + + // minute + minute_ = static_cast(RecoveryInt64FromDb(resultSet, Instance::CALENDAR_MINUTE, DbRecoveryType::INT)); +} + +void ReminderRequestCalendar::AppendValuesBucket(const sptr &reminder, + const sptr &bundleOption, NativeRdb::ValuesBucket &values) +{ + uint32_t repeatDay = 0; + uint16_t repeatMonth = 0; + uint16_t firstDesignateYear = 0; + uint8_t firstDesignateMonth = 0; + uint8_t firstDesignateDay = 0; + uint16_t year = 0; + uint8_t month = 0; + uint8_t day = 0; + uint8_t hour = 0; + uint8_t minute = 0; + if (reminder->GetReminderType() == ReminderRequest::ReminderType::CALENDAR) { + ReminderRequestCalendar* calendar = static_cast(reminder.GetRefPtr()); + repeatDay = calendar->GetRepeatDay(); + repeatMonth = calendar->GetRepeatMonth(); + firstDesignateYear = calendar->GetFirstDesignateYear(); + firstDesignateMonth = calendar->GetFirstDesignageMonth(); + firstDesignateDay = calendar->GetFirstDesignateDay(); + year = calendar->GetYear(); + month = calendar->GetMonth(); + day = calendar->GetDay(); + hour = calendar->GetHour(); + minute = calendar->GetMinute(); + } + values.PutInt(Instance::REPEAT_DAYS, repeatDay); + values.PutInt(Instance::REPEAT_MONTHS, repeatMonth); + values.PutInt(Instance::FIRST_DESIGNATE_YEAR, firstDesignateYear); + values.PutInt(Instance::FIRST_DESIGNATE_MONTH, firstDesignateMonth); + values.PutInt(Instance::FIRST_DESIGNATE_DAY, firstDesignateDay); + values.PutInt(Instance::CALENDAR_YEAR, year); + values.PutInt(Instance::CALENDAR_MONTH, month); + values.PutInt(Instance::CALENDAR_DAY, day); + values.PutInt(Instance::CALENDAR_HOUR, hour); + values.PutInt(Instance::CALENDAR_MINUTE, minute); +} + +const std::string ReminderRequestCalendar::Instance::REPEAT_DAYS = "repeat_days"; +const std::string ReminderRequestCalendar::Instance::REPEAT_MONTHS = "repeat_months"; +const std::string ReminderRequestCalendar::Instance::FIRST_DESIGNATE_YEAR = "first_designate_year"; +const std::string ReminderRequestCalendar::Instance::FIRST_DESIGNATE_MONTH = "first_designate_month"; +const std::string ReminderRequestCalendar::Instance::FIRST_DESIGNATE_DAY = "first_designate_day"; +const std::string ReminderRequestCalendar::Instance::CALENDAR_YEAR = "calendar_year"; +const std::string ReminderRequestCalendar::Instance::CALENDAR_MONTH = "calendar_month"; +const std::string ReminderRequestCalendar::Instance::CALENDAR_DAY = "calendar_day"; +const std::string ReminderRequestCalendar::Instance::CALENDAR_HOUR = "calendar_hour"; +const std::string ReminderRequestCalendar::Instance::CALENDAR_MINUTE = "calendar_minute"; + +std::string ReminderRequestCalendar::Instance::SQL_ADD_COLUMNS = ""; +std::vector ReminderRequestCalendar::Instance::COLUMNS; + +void ReminderRequestCalendar::Instance::Init() +{ + AddColumn(REPEAT_DAYS, "INT", false); + AddColumn(REPEAT_MONTHS, "INT", false); + AddColumn(FIRST_DESIGNATE_YEAR, "INT", false); + AddColumn(FIRST_DESIGNATE_MONTH, "INT", false); + AddColumn(FIRST_DESIGNATE_DAY, "INT", false); + AddColumn(CALENDAR_YEAR, "INT", false); + AddColumn(CALENDAR_MONTH, "INT", false); + AddColumn(CALENDAR_DAY, "INT", false); + AddColumn(CALENDAR_HOUR, "INT", false); + AddColumn(CALENDAR_MINUTE, "INT", false); +} + +void ReminderRequestCalendar::Instance::AddColumn( + const std::string &name, const std::string &type, const bool &isEnd) +{ + COLUMNS.push_back(name); + if (!isEnd) { + SQL_ADD_COLUMNS += name + " " + type + ", "; + } else { + SQL_ADD_COLUMNS += name + " " + type; + } +} } } \ No newline at end of file diff --git a/frameworks/ans/native/src/reminder_store.cpp b/frameworks/ans/native/src/reminder_store.cpp new file mode 100644 index 000000000..0fc67557d --- /dev/null +++ b/frameworks/ans/native/src/reminder_store.cpp @@ -0,0 +1,453 @@ +/* + * 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 + +#include "ability_context.h" +#include "ans_log_wrapper.h" +#include "reminder_request_alarm.h" +#include "reminder_request_calendar.h" +#include "reminder_request_timer.h" + +#include "reminder_store.h" + +namespace OHOS { +namespace Notification { +const std::string ReminderStore::REMINDER_DB_DIR = "/data/user/0/reminder/"; // todo replace path +const std::string ReminderStore::REMINDER_DB_NAME = "reminder.db"; +const uint32_t ReminderStore::REMINDER_RDB_VERSION = 1; +std::vector ReminderStore::COLUMNS; + +const int32_t ReminderStore::STATE_FAIL = -1; +const int32_t ReminderStore::STATE_OK = 0; +const uint16_t ReminderStore::TIME_INTERVAL_FOR_DELETE = 1800; +const uint16_t ReminderStore::MILLI_SECONDS = 1000; +const std::string ReminderStore::REMINDER_DB_TABLE = "reminder"; + +int32_t ReminderStore::ReminderStoreDataCallBack::OnCreate(NativeRdb::RdbStore &store) +{ + ANSR_LOGD("Create table."); + std::string CREATE_REMINDER_TABLE = "CREATE TABLE IF NOT EXISTS " + REMINDER_DB_TABLE + " (" + + ReminderRequest::Instance::SQL_ADD_COLUMNS + + ReminderRequestCalendar::Instance::SQL_ADD_COLUMNS + + ReminderRequestAlarm::Instance::SQL_ADD_COLUMNS + ")"; + ANSR_LOGD("~~~createTable:%{public}s", CREATE_REMINDER_TABLE.c_str()); + return store.ExecuteSql(CREATE_REMINDER_TABLE); +} + +int32_t ReminderStore::ReminderStoreDataCallBack::OnUpgrade(NativeRdb::RdbStore &store, int32_t oldVersion, int32_t newVersion) +{ + return NativeRdb::E_OK; +} + +int32_t ReminderStore::Init() +{ + ANSR_LOGD("Reminder store init."); + + /* std::filesystem::path databaseDir(REMINDER_DB_DIR); + ANSR_LOGD("ReminderStore::%{public}s databaseDir.", __func__); + if (!std::filesystem::exists(databaseDir)) { + bool createDir = std::filesystem::create_directories(REMINDER_DB_DIR); + ANSR_LOGD("ReminderStore::%{public}s createDir.", __func__); + if (!createDir) { + ANSR_LOGE("ReminderStore::%{public}s failed to create directory %{public}s", __func__, REMINDER_DB_DIR.c_str()); + } + } */ + + ReminderRequest::Instance::Init(); + ReminderRequestCalendar::Instance::Init(); + ReminderRequestAlarm::Instance::Init(); + ReminderStore::COLUMNS.insert(ReminderStore::COLUMNS.begin() + , ReminderRequestAlarm::Instance::COLUMNS.begin(), ReminderRequestAlarm::Instance::COLUMNS.end()); + ReminderStore::COLUMNS.insert(ReminderStore::COLUMNS.begin() + , ReminderRequestCalendar::Instance::COLUMNS.begin(), ReminderRequestCalendar::Instance::COLUMNS.end()); + ReminderStore::COLUMNS.insert(ReminderStore::COLUMNS.begin() + , ReminderRequest::Instance::COLUMNS.begin(), ReminderRequest::Instance::COLUMNS.end()); + + int32_t errCode(STATE_FAIL); + std::string dbConfig = ReminderStore::REMINDER_DB_DIR + ReminderStore::REMINDER_DB_NAME; + NativeRdb::RdbStoreConfig config_(dbConfig); + ReminderStoreDataCallBack rdbDataCallBack_; + rdbStore_ = NativeRdb::RdbHelper::GetRdbStore(config_, REMINDER_RDB_VERSION, rdbDataCallBack_, errCode); + if (rdbStore_ == nullptr) { + ANSR_LOGE("ReminderStore init fail, errCode %{public}d.", errCode); + return errCode; + } + + // std::string databaseDir = AppExecFwk::AbilityContext::GetDatabaseDir() + "/" + REMINDER_DB_DIR; + // ANSR_LOGD("~~~~databaseDir=%{public}s", databaseDir); + + return ReminderStore::InitData(); +} + +int32_t ReminderStore::InitData() +{ + ANSR_LOGD("Reminder data init."); + + struct timeb now; + ftime(&now); + time_t nowTime = now.time; + int64_t overDueRtcTime = (static_cast(nowTime) - TIME_INTERVAL_FOR_DELETE) * MILLI_SECONDS; + ANSR_LOGD("OverDueRtcTime: %{public}lld.", overDueRtcTime); + ReminderStore::DeleteRtcTime(overDueRtcTime); // todo check(cannot delete if it is a repeat reminder) + + std::string deleteCondition = ReminderRequest::Instance::IS_EXPIRED + " is true"; + ReminderStore::Delete(deleteCondition); + + int32_t statusChangedRows = STATE_FAIL; + NativeRdb::ValuesBucket statusValues; + statusValues.PutInt(ReminderRequest::Instance::STATE, ReminderRequest::GetConstStateInactive()); + int32_t statusResult = rdbStore_->Update(statusChangedRows, REMINDER_DB_TABLE, statusValues); + ANSR_LOGD("Change status to inactive, changed rows: %{public}d.", statusChangedRows); + + int32_t activeChangedRows = STATE_FAIL; + NativeRdb::ValuesBucket activeValues; + activeValues.PutString(ReminderRequest::Instance::IS_ACTIVE, "false"); + std::string activeUpdateCondition = ReminderRequest::Instance::IS_ACTIVE + " is true"; + std::vector activeWhereArgs; + int32_t activeResult = rdbStore_->Update( + activeChangedRows, REMINDER_DB_TABLE, activeValues, activeUpdateCondition, activeWhereArgs); + ANSR_LOGD("Change status isActive to false, changed rows: %{public}d.", activeChangedRows); + + int32_t scheduledChangedRows = STATE_FAIL; + NativeRdb::ValuesBucket scheduledValues; + scheduledValues.PutString(ReminderRequest::Instance::HAS_SCHEDULED_TIMEOUT, "false"); + std::string scheduledUpdateCondition = ReminderRequest::Instance::HAS_SCHEDULED_TIMEOUT + " is true"; + std::vector scheduledWhereArgs; + int32_t scheduledResult = rdbStore_->Update( + scheduledChangedRows, REMINDER_DB_TABLE, scheduledValues, scheduledUpdateCondition, scheduledWhereArgs); + ANSR_LOGD("Change status has_ScheduledTimeout to false, changed rows: %{public}d.", scheduledChangedRows); + + if (statusResult != NativeRdb::E_OK || activeResult != NativeRdb::E_OK + || scheduledResult != NativeRdb::E_OK) { + ANSR_LOGE("Init data failed."); + return STATE_FAIL; + } + return STATE_OK; +} + +int32_t ReminderStore::Delete(int32_t reminderId) +{ + std::string deleteCondition = ReminderRequest::Instance::REMINDER_ID + + " = " + std::to_string(reminderId); + return ReminderStore::Delete(deleteCondition); +} + +int32_t ReminderStore::DeleteUser(int32_t userId) +{ + std::string deleteCondition = ReminderRequest::Instance::USER_ID + " = " + std::to_string(userId); + return ReminderStore::Delete(deleteCondition); +} + +int32_t ReminderStore::Delete(const std::string &pkg, int32_t userId) +{ + std::string deleteCondition = ReminderRequest::Instance::PKG_NAME + " = " + pkg + " and " + + ReminderRequest::Instance::USER_ID + " = " + std::to_string(userId); + return ReminderStore::Delete(deleteCondition); +} + +int32_t ReminderStore::DeleteRtcTime(int64_t rtcTime) +{ + std::string deleteCondition = ReminderRequest::Instance::RTC_TRIGGER_TIME + + " < " + std::to_string(rtcTime); // todo + return ReminderStore::Delete(deleteCondition); +} + +int32_t ReminderStore::Delete(const std::string &deleteCondition) +{ + if (rdbStore_ == nullptr) { + ANSR_LOGE("Rdb store is not initialized."); + return STATE_FAIL; + } + int32_t deletedRows = STATE_FAIL; + std::vector whereArgs; + int32_t result = rdbStore_->Delete(deletedRows, REMINDER_DB_TABLE, deleteCondition, whereArgs); + if (result != NativeRdb::E_OK) { + ANSR_LOGE("Delete operation failed, deleteConditon: %{public}s," \ + "result: %{public}d.", deleteCondition.c_str(), result); + } + ANSR_LOGD("Delete operation done, deleteConditon: %{public}s," \ + "deleted rows: %{public}d.", deleteCondition.c_str(), deletedRows); + return deletedRows; +} + +int64_t ReminderStore::UpdateOrInsert( + const sptr &reminder, const sptr &bundleOption) +{ + if (reminder->GetReminderType() == ReminderRequest::ReminderType::TIMER) { + ANSR_LOGI("Countdown not support persist."); + return STATE_FAIL; + } + int64_t isSuccess = STATE_FAIL; + if (IsReminderExist(reminder)) { + isSuccess = ReminderStore::Update(reminder, bundleOption); + } else { + isSuccess = ReminderStore::Insert(reminder, bundleOption); + } + return isSuccess; +} + +int64_t ReminderStore::Insert( + const sptr &reminder, const sptr &bundleOption) +{ + if (rdbStore_ == nullptr) { + ANSR_LOGE("Rdb store is not initialized."); + return STATE_FAIL; + } + if (bundleOption == nullptr) { + ANSR_LOGE("BundleOption is null."); + return STATE_FAIL; + } + int64_t rowId = STATE_FAIL; + NativeRdb::ValuesBucket values; + ReminderStore::GenerateData(reminder, bundleOption, values); + int32_t result = rdbStore_->Insert(rowId, REMINDER_DB_TABLE, values); + if (result != NativeRdb::E_OK) { + ANSR_LOGE("Insert operation failed, result: %{public}d, reminderId=%{public}d." + , result, reminder->GetReminderId()); + return result; + } + ANSR_LOGD("Insert successfully, reminderId=%{public}d.", reminder->GetReminderId()); + return result; +} + +int64_t ReminderStore::Update( + const sptr &reminder, const sptr &bundleOption) +{ + if (rdbStore_ == nullptr) { + ANSR_LOGE("Rdb store is not initialized."); + return STATE_FAIL; + } + int32_t changedRows = STATE_FAIL; + NativeRdb::ValuesBucket values; + ReminderStore::GenerateData(reminder, bundleOption, values); + std::string updateCondition = ReminderRequest::Instance::REMINDER_ID + + " = " + std::to_string(reminder->GetReminderId()); + std::vector whereArgs; + int32_t result = rdbStore_->Update(changedRows, REMINDER_DB_TABLE, values, updateCondition, whereArgs); + if ((result != NativeRdb::E_OK) || (changedRows <= 0)) { + ANSR_LOGE("Update operation failed, result: %{public}d, updated rows: %{public}d, reminderId=%{public}d." + , result, changedRows, reminder->GetReminderId()); + return result; + } + ANSR_LOGD("Update successfully, updated rows: %{public}d, reminderId=%{public}d." + , changedRows, reminder->GetReminderId()); + return result; +} + +bool ReminderStore::IsReminderExist(const sptr &reminder) +{ + if (rdbStore_ == nullptr) { + ANSR_LOGE("Rdb store is not initialized."); + return false; + } + std::string queryCondition = "select " + ReminderRequest::Instance::REMINDER_ID + + " from " + REMINDER_DB_TABLE + " where " + + ReminderRequest::Instance::REMINDER_ID + " = " + std::to_string(reminder->GetReminderId()); + std::vector whereArgs; + std::unique_ptr queryResultSet = rdbStore_->QuerySql(queryCondition, whereArgs); + if (queryResultSet == nullptr) { + ANSR_LOGE("QueryResultSet is null."); + return false; + } + int32_t resultNum; + queryResultSet->GetRowCount(resultNum); + if (resultNum == 0) { + return false; + } + return true; +} + +std::shared_ptr ReminderStore::Query(const std::string &queryCondition) const +{ + std::unique_ptr queryResultSet; + if (rdbStore_ == nullptr) { + ANSR_LOGE("Rdb store is not initialized."); + return queryResultSet; + } + std::vector whereArgs; + queryResultSet = rdbStore_->QuerySql(queryCondition, whereArgs); + return queryResultSet; +} + +std::vector ReminderStore::GetRepeatInfo(int64_t repeatData, int32_t maxRepeatVal) +{ + std::vector repeatInfo; + for (int i = 1; i <= maxRepeatVal; i++) { + if ((repeatData & (1 << (i - 1))) > 0) { + repeatInfo.push_back(i); + } + } + return repeatInfo; +} + +uint8_t ReminderStore::GetColumnIndex(const std::string& name) +{ + uint8_t index = 0; + for (auto it = ReminderStore::COLUMNS.begin(); it != ReminderStore::COLUMNS.end(); ++it) { + if (name == (*it)) { + break; + } + index++; + } + return index; +} + +int32_t ReminderStore::GetMaxId() +{ + if (rdbStore_ == nullptr) { + ANSR_LOGE("Rdb store is not initialized."); + return STATE_FAIL; + } + std::string queryCondition = "select * from " + REMINDER_DB_TABLE + " order by " + + ReminderRequest::Instance::REMINDER_ID + " desc"; // todo * + std::shared_ptr queryResultSet = ReminderStore::Query(queryCondition); + if (queryResultSet == nullptr) { + ANSR_LOGE("QueryResultSet is null."); + return STATE_FAIL; + } + int32_t resultNum; + queryResultSet->GetRowCount(resultNum); + if (resultNum == 0) { + ANSR_LOGI("QueryResultSet is zero."); + return STATE_FAIL; + } + queryResultSet->GoToNextRow(); + int32_t maxId = STATE_FAIL; + int32_t result = queryResultSet->GetInt(0, maxId); + if (result != NativeRdb::E_OK) { + ANSR_LOGE("Query operation failed, result %{public}d.", result); + } + ANSR_LOGD("MaxId: %{public}d.", maxId); + return maxId; +} + +std::vector> ReminderStore::GetAllValidReminders() +{ + std::string queryCondition = "select * from " + REMINDER_DB_TABLE + " where " + + ReminderRequest::Instance::IS_EXPIRED + " is false order by " + + ReminderRequest::Instance::TRIGGER_TIME + " asc"; + return GetReminders(queryCondition); +} + +std::vector> ReminderStore::GetReminders(const std::string &queryCondition) +{ + std::vector> reminders; + if (rdbStore_ == nullptr) { + ANSR_LOGE("Rdb store is not initialized."); + return reminders; + } + std::shared_ptr queryResultSet = Query(queryCondition); + if (queryResultSet == nullptr) { + return reminders; + } + bool isAtLastRow = false; + queryResultSet->IsAtLastRow(isAtLastRow); + while(!isAtLastRow) { + queryResultSet->GoToNextRow(); + sptr reminder; + reminder = BuildReminder(queryResultSet); + reminders.push_back(reminder); + queryResultSet->IsAtLastRow(isAtLastRow); + } + ANSR_LOGD("~~~~size=%{public}d", reminders.size()); + return reminders; +} + +sptr ReminderStore::BuildReminder(const std::shared_ptr &resultSet) +{ + int32_t reminderType; + int32_t reminderId; + resultSet->GetInt(ReminderStore::GetColumnIndex(ReminderRequest::Instance::REMINDER_TYPE), reminderType); + resultSet->GetInt(ReminderStore::GetColumnIndex(ReminderRequest::Instance::REMINDER_ID), reminderId); + + sptr reminder = nullptr; + switch (reminderType) { + case (static_cast(ReminderRequest::ReminderType::TIMER)): { + reminder = new ReminderRequestTimer(reminderId); + break; + } + case (static_cast(ReminderRequest::ReminderType::CALENDAR)): { + reminder = new ReminderRequestCalendar(reminderId); + break; + } + case (static_cast(ReminderRequest::ReminderType::ALARM)): { + reminder = new ReminderRequestAlarm(reminderId); + break; + } + default: { + ANSR_LOGE("ReminderType from database is error, reminderType %{public}d.", reminderType); + } + } + if (reminder != nullptr) { + reminder->RecoveryFromDb(resultSet); + ANSR_LOGI("BuildReminder success."); + } else { + ANSR_LOGW("BuildReminder fail."); + } + return reminder; +} + +bool ReminderStore::GetBundleOption(const int32_t &reminderId, sptr &bundleOption) const +{ + std::string queryCondition = "select " + ReminderRequest::Instance::PKG_NAME + ", " + + ReminderRequest::Instance::UID + " from " + REMINDER_DB_TABLE + " where " + + ReminderRequest::Instance::REMINDER_ID + "=" + std::to_string(reminderId); + std::shared_ptr queryResultSet = Query(queryCondition); + if (queryResultSet == nullptr) { + return false; + } + bool isAtLastRow = false; + queryResultSet->IsAtLastRow(isAtLastRow); + if (isAtLastRow) { + return false; + } + ANSR_LOGD("~~~~1"); + queryResultSet->GoToNextRow(); + std::string pkgName; + GetStringVal(queryResultSet, ReminderRequest::Instance::PKG_NAME, pkgName); + int32_t uid; + GetInt32Val(queryResultSet, ReminderRequest::Instance::UID, uid); + bundleOption->SetBundleName(pkgName); + bundleOption->SetUid(uid); + return true; +} + +void ReminderStore::GetInt32Val(std::shared_ptr &resultSet + , const std::string &name, int32_t &value) const +{ + int32_t columnIndex; + resultSet->GetColumnIndex(name, columnIndex); + resultSet->GetInt(columnIndex, value); // todo check outOf size +} + +void ReminderStore::GetStringVal(std::shared_ptr &resultSet + , const std::string &name, std::string &value) const +{ + int32_t columnIndex; + resultSet->GetColumnIndex(name, columnIndex); + resultSet->GetString(columnIndex, value); +} + +void ReminderStore::GenerateData(const sptr &reminder, + const sptr &bundleOption, NativeRdb::ValuesBucket &values) const +{ + ReminderRequest::AppendValuesBucket(reminder, bundleOption, values); + ReminderRequestCalendar::AppendValuesBucket(reminder, bundleOption, values); + ReminderRequestAlarm::AppendValuesBucket(reminder, bundleOption, values); +} +} // namespace Notification +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/ans/native/test/unittest/BUILD.gn b/frameworks/ans/native/test/unittest/BUILD.gn index c0eedd516..15eecb3a8 100644 --- a/frameworks/ans/native/test/unittest/BUILD.gn +++ b/frameworks/ans/native/test/unittest/BUILD.gn @@ -58,6 +58,7 @@ ohos_unittest("ans_reminder_unit_test") { "hiviewdfx_hilog_native:libhilog", "ipc:ipc_core", "multimedia_image_standard:image_native", + "native_appdatamgr:native_rdb", "safwk:system_ability_fwk", "samgr_standard:samgr_proxy", ] diff --git a/interfaces/innerkits/ans/native/include/reminder_request.h b/interfaces/innerkits/ans/native/include/reminder_request.h index 14fb032d6..9c1e935ac 100644 --- a/interfaces/innerkits/ans/native/include/reminder_request.h +++ b/interfaces/innerkits/ans/native/include/reminder_request.h @@ -19,8 +19,11 @@ #include #include +#include "abs_shared_result_set.h" +#include "notification_bundle_option.h" #include "notification_constant.h" #include "notification_request.h" +#include "values_bucket.h" namespace OHOS { namespace Notification { @@ -129,6 +132,14 @@ public: * @param Indicates the exist reminder. */ explicit ReminderRequest(const ReminderRequest &other); + + /** + * @brief This constructor should only be used in background proxy service process + * when reminder instance recovery from database. + * + * @param reminderId Indicates reminder id. + */ + explicit ReminderRequest(int32_t reminderId); ReminderRequest& operator = (const ReminderRequest &other); virtual ~ReminderRequest() override {}; @@ -256,6 +267,9 @@ public: */ uint64_t GetTriggerTimeInMilli() const; + int GetUserId() const; + int32_t GetUid() const; + /** * @brief Obtains want agent information. * @@ -280,6 +294,16 @@ public: */ void InitUserId(const int &userId); + /** + * @brief Inites reminder uid when publish reminder success. + * + * When system reboot and recovery from database, we cannot get the uid according user id as BMS has not be + * ready. So we need to record the uid in order to create correct bundleOption. + * + * @param uid Indicates the uid which the reminder belong to. + */ + void InitUid(const int32_t &uid); + /** * @brief Check the reminder is alerting or not. * @@ -378,6 +402,15 @@ public: */ virtual bool OnTimeZoneChange(); + /** + * @brief Recovery reminder instance from database record. + * + * @param resultSet Indicates the resultSet with pointer to the row of record data. + */ + virtual void RecoveryFromDb(const std::shared_ptr &resultSet); + void RecoveryActionButton(const std::shared_ptr &resultSet); + void RecoveryWantAgent(std::string wantAgentInfo, const uint8_t &type); + /** * @brief Sets action button. * @@ -525,6 +558,8 @@ public: */ void UpdateNotificationRequest(UpdateNotificationType type, std::string extra); + static uint8_t GetConstStateInactive(); + static int32_t GLOBAL_ID; static const uint64_t INVALID_LONG_LONG_VALUE; static const uint16_t INVALID_U16_VALUE; @@ -563,8 +598,52 @@ public: static uint64_t GetDurationSinceEpochInMilli(const time_t target); static int32_t GetUid(const int &userId, const std::string &bundleName); static int GetUserId(const int &uid); + static void AppendValuesBucket(const sptr &reminder, + const sptr &bundleOption, NativeRdb::ValuesBucket &values); + +class Instance { +public: + const static std::string REMINDER_ID; + const static std::string PKG_NAME; + const static std::string USER_ID; + const static std::string UID; + const static std::string APP_LABEL; + const static std::string REMINDER_TYPE; + const static std::string REMINDER_TIME; + const static std::string TRIGGER_TIME; + const static std::string RTC_TRIGGER_TIME; + const static std::string TIME_INTERVAL; + const static std::string SNOOZE_TIMES; + const static std::string DYNAMIC_SNOOZE_TIMES; + const static std::string RING_DURATION; + const static std::string IS_EXPIRED; + const static std::string IS_ACTIVE; + const static std::string STATE; + const static std::string ZONE_ID; + const static std::string HAS_SCHEDULED_TIMEOUT; + const static std::string ACTION_BUTTON_INFO; + const static std::string SLOT_ID; + const static std::string NOTIFICATION_ID; + const static std::string TITLE; + const static std::string CONTENT; + const static std::string SNOOZE_CONTENT; + const static std::string EXPIRED_CONTENT; + const static std::string AGENT; + const static std::string MAX_SCREEN_AGENT; + + static std::string SQL_ADD_COLUMNS; + static std::vector COLUMNS; + static void Init(); + +private: + static void AddColumn(const std::string &name, const std::string &type, const bool &isEnd); +}; protected: + enum class DbRecoveryType : uint8_t { + INT, + LONG + }; ReminderRequest(); explicit ReminderRequest(ReminderType reminderType); std::string GetDateTimeInfo(const time_t &timeInSecond) const; @@ -572,12 +651,15 @@ protected: { return INVALID_LONG_LONG_VALUE; } + int64_t RecoveryInt64FromDb(const std::shared_ptr &resultSet, + const std::string &columnName, const DbRecoveryType &columnType); static const int BASE_YEAR; private: void AddActionButtons(const bool includeSnooze); void AddRemovalWantAgent(); std::shared_ptr CreateWantAgent(AppExecFwk::ElementName &element) const; + std::string GetButtonInfo() const; uint64_t GetNowInstantMilli() const; std::string GetShowTime(const uint64_t showTime) const; std::string GetTimeInfoInner(const time_t &timeInSecond, const TimeFormat &format) const; @@ -585,9 +667,11 @@ private: bool HandleSysTimeChange(uint64_t oriTriggerTime, uint64_t optTriggerTime); bool HandleTimeZoneChange(uint64_t oldZoneTriggerTime, uint64_t newZoneTriggerTime, uint64_t optTriggerTime); bool InitNotificationRequest(); + void InitServerObj(); void SetMaxScreenWantAgent(AppExecFwk::ElementName &element); void SetState(bool deSet, const uint8_t newState, std::string function); void SetWantAgent(AppExecFwk::ElementName &element); + std::vector StringSplit(std::string source, const std::string &split) const; void UpdateActionButtons(const bool &setSnooze); bool UpdateNextReminder(const bool &force); void UpdateNotificationContent(const bool &setSnooze); @@ -613,6 +697,9 @@ private: static const uint8_t REMINDER_STATUS_SHOWING; static const uint8_t REMINDER_STATUS_SNOOZE; static const uint32_t MIN_TIME_INTERVAL_IN_MILLI; + static const std::string SEP_BUTTON_SINGLE; + static const std::string SEP_BUTTON_MULTI; + static const std::string SEP_WANT_AGENT; std::string content_ {}; std::string expiredContent_ {}; @@ -626,6 +713,7 @@ private: int32_t notificationId_ {0}; int32_t reminderId_ {-1}; int userId_ {-1}; + int32_t uid_ {-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. diff --git a/interfaces/innerkits/ans/native/include/reminder_request_alarm.h b/interfaces/innerkits/ans/native/include/reminder_request_alarm.h index 07239f1ea..d0fd6f4df 100644 --- a/interfaces/innerkits/ans/native/include/reminder_request_alarm.h +++ b/interfaces/innerkits/ans/native/include/reminder_request_alarm.h @@ -40,6 +40,14 @@ public: */ ReminderRequestAlarm(uint8_t hour, uint8_t minute, std::vector daysOfWeek); + /** + * @brief This constructor should only be used in background proxy service process + * when reminder instance recovery from database. + * + * @param reminderId Indicates reminder id. + */ + ReminderRequestAlarm(int32_t reminderId) : ReminderRequest(reminderId) {}; + /** * @brief Copy construct from an exist reminder. * @@ -96,6 +104,23 @@ public: * @return true if read parcel success. */ bool ReadFromParcel(Parcel &parcel) override; + virtual void RecoveryFromDb(const std::shared_ptr &resultSet) override; + static void AppendValuesBucket(const sptr &reminder, + const sptr &bundleOption, NativeRdb::ValuesBucket &values); + +class Instance { +public: + const static std::string REPEAT_DAYS_OF_WEEK; + const static std::string ALARM_HOUR; + const static std::string ALARM_MINUTE; + + static std::string SQL_ADD_COLUMNS; + static std::vector COLUMNS; + static void Init(); + +private: + static void AddColumn(const std::string &name, const std::string &type, const bool &isEnd); +}; protected: virtual uint64_t PreGetNextTriggerTimeIgnoreSnooze(bool ignoreRepeat, bool forceToGetNext) const override; diff --git a/interfaces/innerkits/ans/native/include/reminder_request_calendar.h b/interfaces/innerkits/ans/native/include/reminder_request_calendar.h index b675abed7..1cd398621 100644 --- a/interfaces/innerkits/ans/native/include/reminder_request_calendar.h +++ b/interfaces/innerkits/ans/native/include/reminder_request_calendar.h @@ -52,6 +52,14 @@ public: ReminderRequestCalendar(const tm &dateTime, const std::vector &repeatMonths, const std::vector &repeatDays); + /** + * @brief This constructor should only be used in background proxy service process + * when reminder instance recovery from database. + * + * @param reminderId Indicates reminder id. + */ + ReminderRequestCalendar(int32_t reminderId) : ReminderRequest(reminderId) {}; + explicit ReminderRequestCalendar(const ReminderRequestCalendar &other); ReminderRequestCalendar& operator = (const ReminderRequestCalendar &other); ~ReminderRequestCalendar() override {} @@ -133,8 +141,32 @@ public: static const uint8_t MAX_MONTHS_OF_YEAR; static const uint8_t MAX_DAYS_OF_MONTH; + virtual void RecoveryFromDb(const std::shared_ptr &resultSet) override; + static void AppendValuesBucket(const sptr &reminder, + const sptr &bundleOption, NativeRdb::ValuesBucket &values); static uint8_t GetDaysOfMonth(const uint16_t &year, const uint8_t &month); +class Instance { +public: + const static std::string REPEAT_DAYS; + const static std::string REPEAT_MONTHS; + const static std::string FIRST_DESIGNATE_YEAR; + const static std::string FIRST_DESIGNATE_MONTH; + const static std::string FIRST_DESIGNATE_DAY; + const static std::string CALENDAR_YEAR; + const static std::string CALENDAR_MONTH; + const static std::string CALENDAR_DAY; + const static std::string CALENDAR_HOUR; + const static std::string CALENDAR_MINUTE; + + static std::string SQL_ADD_COLUMNS; + static std::vector COLUMNS; + static void Init(); + +private: + static void AddColumn(const std::string &name, const std::string &type, const bool &isEnd); +}; + protected: virtual uint64_t PreGetNextTriggerTimeIgnoreSnooze(bool ignoreRepeat, bool forceToGetNext) const override; @@ -144,6 +176,12 @@ private: 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; + uint32_t GetRepeatDay() const { + return repeatDay_; + } + uint16_t GetRepeatMonth() const { + return repeatMonth_; + } uint64_t GetTimeInstantMilli( uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second) const; diff --git a/interfaces/innerkits/ans/native/include/reminder_request_timer.h b/interfaces/innerkits/ans/native/include/reminder_request_timer.h index 9fc2362f2..46bf1a28c 100644 --- a/interfaces/innerkits/ans/native/include/reminder_request_timer.h +++ b/interfaces/innerkits/ans/native/include/reminder_request_timer.h @@ -33,6 +33,14 @@ public: */ ReminderRequestTimer(uint64_t countDownTimeInSeconds); + /** + * @brief This constructor should only be used in background proxy service process + * when reminder instance recovery from database. + * + * @param reminderId Indicates reminder id. + */ + ReminderRequestTimer(int32_t reminderId) : ReminderRequest(reminderId) {}; + /** * @brief Copy construct from an exist reminder. * diff --git a/interfaces/innerkits/ans/native/include/reminder_store.h b/interfaces/innerkits/ans/native/include/reminder_store.h new file mode 100644 index 000000000..d553c8235 --- /dev/null +++ b/interfaces/innerkits/ans/native/include/reminder_store.h @@ -0,0 +1,99 @@ +/* + * 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_INTERFACES_INNERKITS_ANS_NATIVE_INCLUDE_REMINDER_STORE_H +#define BASE_NOTIFICATION_ANS_STANDARD_INTERFACES_INNERKITS_ANS_NATIVE_INCLUDE_REMINDER_STORE_H + +#include + +#include "notification_bundle_option.h" +#include "pixel_map.h" +#include "reminder_request.h" +#include "rdb_errno.h" +#include "rdb_helper.h" +#include "rdb_open_callback.h" +#include "rdb_store_config.h" + +namespace OHOS { +namespace Notification { +class ReminderStore { +public: + ReminderStore() {}; + virtual ~ReminderStore() {}; + int32_t Init(); + int32_t Delete(int32_t reminderId); + int32_t Delete(const std::string &pkg, int32_t userId); + int32_t DeleteUser(int32_t userId); + std::vector> GetAllValidReminders(); + bool GetBundleOption(const int32_t &reminderId, sptr &bundleOption) const; + int32_t GetMaxId(); + int64_t UpdateOrInsert(const sptr &reminder, const sptr &bundleOption); + static std::vector GetRepeatInfo(int64_t repeatData, int32_t maxRepeatVal); + static uint8_t GetColumnIndex(const std::string& name); + + static std::vector COLUMNS; + static const int32_t STATE_FAIL; + static const int32_t STATE_OK; + +private: + /** + * @brief Inits the data in database when system boot on or proxy process reboot on. + * + * 1. Deletes all the reminders which TRIGGER_TIME is less than now-30min. + * 2. Deletes all the reminders which IS_EXPIRED is true. + * 3. Sets all the value of STATE to ReminderRequest::REMINDER_STATUS_INACTIVE + * 4. Sets all the value of IS_ACTIVE to false. + * 5. Sets all the value of HAS_SCHEDULED_TIMEOUT to false. + * + * @return int32_t + */ + int32_t InitData(); + sptr BuildReminder(const std::shared_ptr &resultSet); + int32_t Delete(const std::string &deleteCondition); + int32_t DeleteRtcTime(int64_t rtcTime); + void GetInt32Val(std::shared_ptr &resultSet + , const std::string &name, int32_t &value) const; + void GetStringVal(std::shared_ptr &resultSet + , const std::string &name, std::string &value) const; + std::vector> GetReminders(const std::string &queryCondition); + void GenerateData(const sptr &remindert, + const sptr &bundleOption, NativeRdb::ValuesBucket &values) const; + bool IsReminderExist(const sptr &reminder); + int64_t Insert(const sptr &reminder, const sptr &bundleOption); + std::shared_ptr Query(const std::string &queryCondition) const; + int64_t Update(const sptr &reminder, const sptr &bundleOption); + +private: + static const std::string REMINDER_DB_DIR; + static const std::string REMINDER_DB_NAME; + static const uint32_t REMINDER_RDB_VERSION; + static const uint16_t TIME_INTERVAL_FOR_DELETE; + static const uint16_t MILLI_SECONDS; + static const std::string REMINDER_DB_TABLE; + +private: +class ReminderStoreDataCallBack : public NativeRdb::RdbOpenCallback { +public: + int32_t OnCreate(NativeRdb::RdbStore &rdbStore) override; + int32_t OnUpgrade(NativeRdb::RdbStore &rdbStore, int32_t oldVersion, int32_t newVersion) override; +}; + +private: + std::shared_ptr rdbStore_; +}; + +} // namespace Notification +} // namespace OHOS +#endif // BASE_NOTIFICATION_ANS_STANDARD_INTERFACES_INNERKITS_ANS_NATIVE_INCLUDE_REMINDER_STORE_H \ No newline at end of file diff --git a/interfaces/kits/napi/ans/BUILD.gn b/interfaces/kits/napi/ans/BUILD.gn index 74ee9b535..eed0bf82c 100644 --- a/interfaces/kits/napi/ans/BUILD.gn +++ b/interfaces/kits/napi/ans/BUILD.gn @@ -83,6 +83,7 @@ ohos_shared_library("notification") { "hiviewdfx_hilog_native:libhilog", "ipc:ipc_core", "napi:ace_napi", + "native_appdatamgr:native_rdb", ] relative_install_dir = "module" diff --git a/interfaces/kits/napi/ans/src/reminder/BUILD.gn b/interfaces/kits/napi/ans/src/reminder/BUILD.gn index 0cabca867..a8654b15f 100644 --- a/interfaces/kits/napi/ans/src/reminder/BUILD.gn +++ b/interfaces/kits/napi/ans/src/reminder/BUILD.gn @@ -71,6 +71,7 @@ ohos_shared_library("reminderagent") { "hiviewdfx_hilog_native:libhilog", "ipc:ipc_core", "napi:ace_napi", + "native_appdatamgr:native_rdb", ] relative_install_dir = "module" diff --git a/services/ans/include/advanced_notification_service_ability.h b/services/ans/include/advanced_notification_service_ability.h index ec5c866d8..5ebdf2f02 100644 --- a/services/ans/include/advanced_notification_service_ability.h +++ b/services/ans/include/advanced_notification_service_ability.h @@ -20,6 +20,7 @@ #include "advanced_notification_service.h" #include "system_ability_definition.h" +#include "reminder_data_manager.h" namespace OHOS { namespace Notification { @@ -36,6 +37,7 @@ private: private: sptr service_; + std::shared_ptr reminderAgent_; }; } // namespace Notification } // namespace OHOS diff --git a/services/ans/include/reminder_data_manager.h b/services/ans/include/reminder_data_manager.h index b1d22285a..b0bbf485e 100644 --- a/services/ans/include/reminder_data_manager.h +++ b/services/ans/include/reminder_data_manager.h @@ -22,6 +22,7 @@ #include "advanced_notification_service.h" #include "player.h" #include "reminder_request.h" +#include "reminder_store.h" #include "reminder_timer_info.h" namespace OHOS { @@ -82,6 +83,15 @@ public: void GetValidReminders( const sptr bundleOption, std::vector> &reminders); + /** + * @brief Inits and recovery data from database. + * + * @param isFromBootComplete Indicates the init is called when boot completed. + */ + void Init(bool isFromBootComplete); + + void OnServiceStart(); + /** * @brief Triggered when third party application died. * @@ -129,6 +139,11 @@ public: */ void SnoozeReminder(const OHOS::EventFwk::Want &want); + /** + * Starts the recent reminder timing. + */ + void StartRecentReminder(); + /** * @brief Terminate the alerting reminder. * @@ -178,6 +193,7 @@ private: * @return true if number limit is exceeded. */ bool CheckReminderLimitExceededLocked(const std::string &bundleName) const; + void CloseReminder(const sptr &reminder, bool cancelNotification); /** @@ -188,6 +204,8 @@ private: */ std::shared_ptr CreateTimerInfo(TimerType type) const; + void GetImmediatelyShowRemindersLocked(std::vector> &reminders) const; + std::string GetSoundUri(const sptr &reminder); /** @@ -254,6 +272,8 @@ private: bool HandleSysTimeChange(const sptr reminder) const; + bool IsReminderAgentReady() const; + /** * Judge the two reminders is belong to the same application or not. * @@ -265,6 +285,8 @@ private: bool IsBelongToSameApp( const sptr reminder, const std::string otherPkgName, const int otherUserId); + void LoadReminderFromDb(); + void PlaySoundAndVibrationLocked(const sptr &reminder); void PlaySoundAndVibration(const sptr &reminder); void StopSoundAndVibrationLocked(const sptr &reminder); @@ -321,11 +343,6 @@ private: void SnoozeReminderImpl(sptr &reminder); - /** - * Starts the recent reminder timing. - */ - void StartRecentReminder(); - /** * Starts timing actually. * @@ -403,6 +420,8 @@ private: */ static const int16_t MAX_NUM_REMINDER_LIMIT_APP; + bool isReminderAgentReady_ = false; + /** * Vector used to record all the reminders in system. */ @@ -447,6 +466,7 @@ private: */ int16_t totalCount_ {0}; AdvancedNotificationService *advancedNotificationService_; + std::shared_ptr store_ = nullptr; }; } // namespace OHOS } // namespace Nofitifcation diff --git a/services/ans/include/reminder_event_manager.h b/services/ans/include/reminder_event_manager.h index 35f46ba0e..fec6bfb72 100644 --- a/services/ans/include/reminder_event_manager.h +++ b/services/ans/include/reminder_event_manager.h @@ -18,6 +18,7 @@ #include "common_event_subscriber.h" #include "reminder_data_manager.h" +#include "system_ability_status_change_stub.h" #include @@ -45,6 +46,16 @@ private: void HandleProcessDied(OHOS::EventFwk::Want &want) const; std::shared_ptr reminderDataManager_ = nullptr; }; + +class SystemAbilityStatusChangeListener : public OHOS::SystemAbilityStatusChangeStub { +public: + SystemAbilityStatusChangeListener(std::shared_ptr &reminderDataManager); + ~SystemAbilityStatusChangeListener() {}; + virtual void OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId) override; + virtual void OnRemoveSystemAbility(int32_t systemAbilityId, const std::string& deviceId) override; +private: + std::shared_ptr reminderDataManager_ = nullptr; +}; }; } // namespace OHOS } // namespace Notification diff --git a/services/ans/src/advanced_notification_service.cpp b/services/ans/src/advanced_notification_service.cpp index c9c4b4853..f2dbc169b 100644 --- a/services/ans/src/advanced_notification_service.cpp +++ b/services/ans/src/advanced_notification_service.cpp @@ -1714,7 +1714,6 @@ ErrCode AdvancedNotificationService::PublishReminder(sptr &remi return result; } - ReminderDataManager::GetInstance()->SetService(this); sptr notificationRequest = reminder->GetNotificationRequest(); sptr bundleOption = nullptr; result = PrepareNotificationInfo(notificationRequest, bundleOption); @@ -1729,7 +1728,6 @@ ErrCode AdvancedNotificationService::PublishReminder(sptr &remi ErrCode AdvancedNotificationService::CancelReminder(const int32_t reminderId) { ANSR_LOGI("Cancel Reminder"); - ReminderDataManager::GetInstance()->SetService(this); sptr bundleOption = GenerateBundleOption(); if (bundleOption == nullptr) { return ERR_ANS_INVALID_BUNDLE; @@ -1741,7 +1739,6 @@ ErrCode AdvancedNotificationService::CancelReminder(const int32_t reminderId) ErrCode AdvancedNotificationService::CancelAllReminders() { ANSR_LOGI("Cancel all reminders"); - ReminderDataManager::GetInstance()->SetService(this); sptr bundleOption = GenerateBundleOption(); if (bundleOption == nullptr) { return ERR_ANS_INVALID_BUNDLE; @@ -1755,7 +1752,6 @@ ErrCode AdvancedNotificationService::CancelAllReminders() ErrCode AdvancedNotificationService::GetValidReminders(std::vector> &reminders) { ANSR_LOGI("GetValidReminders"); - ReminderDataManager::GetInstance()->SetService(this); reminders.clear(); sptr bundleOption = GenerateBundleOption(); if (bundleOption == nullptr) { diff --git a/services/ans/src/advanced_notification_service_ability.cpp b/services/ans/src/advanced_notification_service_ability.cpp index 56f052fb8..c96691618 100644 --- a/services/ans/src/advanced_notification_service_ability.cpp +++ b/services/ans/src/advanced_notification_service_ability.cpp @@ -38,11 +38,14 @@ void AdvancedNotificationServiceAbility::OnStart() if (!Publish(service_)) { return; } + reminderAgent_ = ReminderDataManager::GetInstance(); + reminderAgent_->SetService(static_cast(service_.GetRefPtr())); } void AdvancedNotificationServiceAbility::OnStop() { service_ = nullptr; + reminderAgent_ = nullptr; } } // namespace Notification } // namespace OHOS \ No newline at end of file diff --git a/services/ans/src/reminder_data_manager.cpp b/services/ans/src/reminder_data_manager.cpp index 52adfccde..a0228f4c9 100644 --- a/services/ans/src/reminder_data_manager.cpp +++ b/services/ans/src/reminder_data_manager.cpp @@ -149,6 +149,7 @@ void ReminderDataManager::CancelAllReminders(const sptrDelete(reminderId); continue; } ++vit; @@ -190,6 +191,15 @@ void ReminderDataManager::AddToShowedReminders(const sptr &remi showedReminderVector_.push_back(reminder); } +void ReminderDataManager::OnServiceStart() +{ + std::vector> immediatelyShowReminders; + GetImmediatelyShowRemindersLocked(immediatelyShowReminders); + ANSR_LOGD("immediatelyShowReminders size=%{public}d", immediatelyShowReminders.size()); + HandleImmediatelyShow(immediatelyShowReminders, false); + StartRecentReminder(); +} + void ReminderDataManager::OnProcessDiedLocked(const sptr bundleOption) { std::string bundleName = bundleOption->GetBundleName(); @@ -219,6 +229,7 @@ void ReminderDataManager::OnProcessDiedLocked(const sptrUpdateOrInsert((*it), bundleOption); } } @@ -340,7 +351,8 @@ void ReminderDataManager::CloseReminder(const sptr &reminder, b } reminder->OnClose(true); RemoveFromShowedReminders(reminder); - if (cancelNotification) { + store_->UpdateOrInsert(reminder, FindNotificationBundleOption(reminder->GetReminderId())); + if (cancelNotification) { // todo no need to judge CancelNotification(reminder); } } @@ -350,6 +362,7 @@ std::shared_ptr ReminderDataManager::GetInstance() if (REMINDER_DATA_MANAGER == nullptr) { REMINDER_DATA_MANAGER = std::make_shared(); ReminderEventManager reminderEventManager(REMINDER_DATA_MANAGER); + REMINDER_DATA_MANAGER->Init(false); } return REMINDER_DATA_MANAGER; } @@ -411,6 +424,7 @@ void ReminderDataManager::TerminateAlerting(const sptr &reminde ANSR_LOGD("publish(update) notification.(reminderId=%{public}d)", reminder->GetReminderId()); UpdateNotification(reminder); advancedNotificationService_->PublishPreparedNotification(notificationRequest, bundleOption); + store_->UpdateOrInsert(reminder, FindNotificationBundleOption(reminder->GetReminderId())); } void ReminderDataManager::UpdateAndSaveReminderLocked( @@ -419,6 +433,7 @@ void ReminderDataManager::UpdateAndSaveReminderLocked( std::lock_guard lock(ReminderDataManager::MUTEX); reminder->InitReminderId(); reminder->InitUserId(ReminderRequest::GetUserId(bundleOption->GetUid())); + reminder->InitUid(bundleOption->GetUid()); int32_t reminderId = reminder->GetReminderId(); ANSR_LOGD("Containers(map) add. reminderId=%{public}d", reminderId); auto ret = notificationBundleOptionMap_.insert( @@ -430,6 +445,7 @@ void ReminderDataManager::UpdateAndSaveReminderLocked( ANSR_LOGD("Containers(vector) add. reminderId=%{public}d", reminderId); reminderVector_.push_back(reminder); totalCount_++; + store_->UpdateOrInsert(reminder, bundleOption); } void ReminderDataManager::SetService(AdvancedNotificationService *advancedNotificationService) @@ -552,6 +568,8 @@ void ReminderDataManager::ShowReminder(const sptr &reminder, co } else { HandleSameNotificationIdShowing(reminder); } + store_->UpdateOrInsert(reminder, FindNotificationBundleOption(reminder->GetReminderId())); + if (isNeedToStartNext) { StartRecentReminder(); } @@ -592,6 +610,7 @@ void ReminderDataManager::SnoozeReminderImpl(sptr &reminder) StopTimerLocked(TimerType::ALERTING_TIMER); } reminder->OnSnooze(); + store_->UpdateOrInsert(reminder, FindNotificationBundleOption(reminder->GetReminderId())); // 2) Show the notification dialog in the systemUI sptr bundleOption = FindNotificationBundleOption(reminderId); @@ -622,11 +641,13 @@ void ReminderDataManager::StartRecentReminder() } if (activeReminderId_ != -1) { activeReminder_->OnStop(); + store_->UpdateOrInsert(activeReminder_, FindNotificationBundleOption(activeReminderId_)); StopTimerLocked(TimerType::TRIGGER_TIMER); } ANSR_LOGI("Start recent reminder"); StartTimerLocked(reminder, TimerType::TRIGGER_TIMER); reminder->OnStart(); + store_->UpdateOrInsert(reminder, FindNotificationBundleOption(reminder->GetReminderId())); SetActiveReminder(reminder); } @@ -727,6 +748,7 @@ sptr ReminderDataManager::GetRecentReminderLocked() } it = reminderVector_.erase(it); totalCount_--; + store_->Delete(reminderId); } return nullptr; } @@ -779,8 +801,10 @@ sptr ReminderDataManager::HandleRefreshReminder(uint8_t &type, if (triggerTimeBefore != triggerTimeAfter || reminder->GetReminderId() == alertingReminderId_) { CloseReminder(reminder, true); } + store_->UpdateOrInsert(reminder, FindNotificationBundleOption(reminder->GetReminderId())); return nullptr; } + store_->UpdateOrInsert(reminder, FindNotificationBundleOption(reminder->GetReminderId())); return reminder; } @@ -810,10 +834,50 @@ void ReminderDataManager::HandleSameNotificationIdShowing(const sptrOnSameNotificationIdCovered(); RemoveFromShowedReminders(*it); + store_->UpdateOrInsert((*it), FindNotificationBundleOption((*it)->GetReminderId())); } } } +void ReminderDataManager::Init(bool isFromBootComplete) +{ + ANSR_LOGD("ReminderDataManager Init, isFromBootComplete:%{public}d", isFromBootComplete); + if (IsReminderAgentReady()) { + return; + } + if (store_ == nullptr) { + store_ = std::make_shared(); + } + if (store_->Init() != ReminderStore::STATE_OK) { + ANSR_LOGW("Db init fail."); + return; + } + LoadReminderFromDb(); + ANSR_LOGD("~~~~#dump:%{public}s", Dump().c_str()); + isReminderAgentReady_ = true; + ANSR_LOGD("ReminderAgent is ready."); +} + +void ReminderDataManager::GetImmediatelyShowRemindersLocked(std::vector> &reminders) const +{ + std::lock_guard lock(ReminderDataManager::MUTEX); + for (auto it = reminderVector_.begin(); it != reminderVector_.end(); ++it) { + if ((*it)->ShouldShowImmediately()) { + if ((*it)->GetReminderType() != ReminderRequest::ReminderType::TIMER) { + (*it)->SetSnoozeTimesDynamic(0); + } + reminders.push_back(*it); + } else { + break; + } + } +} + +bool ReminderDataManager::IsReminderAgentReady() const +{ + return isReminderAgentReady_; +} + bool ReminderDataManager::IsBelongToSameApp( const sptr reminder, const std::string otherPkgName, const int otherUserId) { @@ -830,6 +894,30 @@ bool ReminderDataManager::IsBelongToSameApp( return false; } +void ReminderDataManager::LoadReminderFromDb() +{ + std::lock_guard lock(ReminderDataManager::MUTEX); + std::vector> existReminders = store_->GetAllValidReminders(); + reminderVector_ = existReminders; + ANSR_LOGD("LoadReminderFromDb, reminder size=%{public}d", reminderVector_.size()); + for (auto it = reminderVector_.begin(); it != reminderVector_.end(); ++it) { + sptr bundleOption = new NotificationBundleOption(); + int32_t reminderId = (*it)->GetReminderId(); + if (!(store_->GetBundleOption(reminderId, bundleOption))) { + ANSR_LOGE("Get bundle option fail, reminderId=%{public}d", reminderId); + continue; + } + auto ret = notificationBundleOptionMap_.insert( + std::pair>(reminderId, bundleOption)); + if (!ret.second) { + ANSR_LOGE("Containers add to map error"); + continue; + } + } + totalCount_ = reminderVector_.size(); + ReminderRequest::GLOBAL_ID = store_->GetMaxId() + 1; +} + void ReminderDataManager::PlaySoundAndVibrationLocked(const sptr &reminder) { std::lock_guard lock(ReminderDataManager::ALERT_MUTEX); // todo check died lock @@ -935,6 +1023,7 @@ void ReminderDataManager::RemoveReminderLocked(const int32_t &reminderId) ANSR_LOGD("Containers(vector) remove. reminderId=%{public}d", reminderId); it = reminderVector_.erase(it); totalCount_--; + store_->Delete(reminderId); break; } else { ++it; diff --git a/services/ans/src/reminder_event_manager.cpp b/services/ans/src/reminder_event_manager.cpp index 852d43672..98394a3e7 100644 --- a/services/ans/src/reminder_event_manager.cpp +++ b/services/ans/src/reminder_event_manager.cpp @@ -19,7 +19,10 @@ #include "bundle_mgr_interface.h" #include "common_event_manager.h" #include "common_event_support.h" +#include "if_system_ability_manager.h" #include "ipc_skeleton.h" +#include "iservice_registry.h" +#include "system_ability_definition.h" #include "reminder_event_manager.h" @@ -38,6 +41,7 @@ void ReminderEventManager::init(std::shared_ptr &reminderDa 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_BOOT_COMPLETED); matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED); matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_PACKAGE_DATA_CLEARED); matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_PACKAGE_RESTARTED); @@ -53,6 +57,18 @@ void ReminderEventManager::init(std::shared_ptr &reminderDa ANSR_LOGD("SubscribeCommonEvent fail"); } IPCSkeleton::SetCallingIdentity(identity); + + sptr statusChangeListener + = new SystemAbilityStatusChangeListener(reminderDataManager); + sptr samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (samgrProxy == nullptr) { + ANSR_LOGD("samgrProxy is null"); + return; + } + int32_t ret = samgrProxy->SubscribeSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID, statusChangeListener); + if (ret != ERR_OK) { + ANSR_LOGE("subscribe system ability id: %{public}d failed", BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); + } } ReminderEventManager::ReminderEventSubscriber::ReminderEventSubscriber( @@ -87,6 +103,10 @@ void ReminderEventManager::ReminderEventSubscriber::OnReceiveEvent(const EventFw reminderDataManager_->CloseReminder(want, false); return; } + if (action == CommonEventSupport::COMMON_EVENT_BOOT_COMPLETED) { + reminderDataManager_->Init(true); + return; + } if (action == CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED) { HandlePackageRemove(want); return; @@ -146,5 +166,24 @@ sptr ReminderEventManager::ReminderEventSubscriber::Ge } return bundleOption; } + +ReminderEventManager::SystemAbilityStatusChangeListener::SystemAbilityStatusChangeListener( + std::shared_ptr &reminderDataManager) +{ + reminderDataManager_ = reminderDataManager; +} + +void ReminderEventManager::SystemAbilityStatusChangeListener::OnAddSystemAbility( + int32_t systemAbilityId, const std::string& deviceId) +{ + ANSR_LOGD("OnAddSystemAbilityInner"); + reminderDataManager_->OnServiceStart(); +} + +void ReminderEventManager::SystemAbilityStatusChangeListener::OnRemoveSystemAbility( + int32_t systemAbilityId, const std::string& deviceId) +{ + ANSR_LOGD("OnRemoveSystemAbilityInner"); +} } // namespace OHOS } // namespace Notification -- Gitee