diff --git a/frameworks/reminder/src/reminder_request.cpp b/frameworks/reminder/src/reminder_request.cpp
index 4b3bdf456758521545090902c0b21b6e200833ec..814c21ca90db324c69c17d213ae293ccf29fb723 100644
--- a/frameworks/reminder/src/reminder_request.cpp
+++ b/frameworks/reminder/src/reminder_request.cpp
@@ -72,6 +72,7 @@ const std::string ReminderRequest::REMINDER_EVENT_REMOVE_NOTIFICATION =
"ohos.event.notification.reminder.REMOVE_NOTIFICATION";
const std::string ReminderRequest::REMINDER_EVENT_LOAD_REMINDER = "ohos.event.notification.reminder.LOAD_REMINDER";
const std::string ReminderRequest::PARAM_REMINDER_ID = "REMINDER_ID";
+const std::string ReminderRequest::PARAM_REMINDER_SHARE = "REMINDER_SHARE_FLAG";
const std::string ReminderRequest::SEP_BUTTON_SINGLE = "";
const std::string ReminderRequest::SEP_BUTTON_MULTI = "";
const std::string ReminderRequest::SEP_WANT_AGENT = "";
@@ -87,16 +88,20 @@ const uint16_t ReminderRequest::SECONDS_PER_HOUR = 3600;
template
void GetJsonValue(const nlohmann::json& root, const std::string& name, T& value)
{
+ value = T();
+ if (!root.contains(name)) {
+ return;
+ }
using ValueType = std::remove_cv_t>;
if constexpr (std::is_same_v) {
- if (!root.contains(name) || !root[name].is_string()) {
- value = T();
- return;
+ if (root[name].is_string()) {
+ value = root[name].get();
+ }
+ } else if constexpr (std::is_same_v) {
+ if (root[name].is_number()) {
+ value = root[name].get();
}
- value = root[name].get();
- return;
}
- value = T();
}
inline static bool IsVaildButtonType(const std::string& type)
@@ -377,8 +382,8 @@ bool ReminderRequest::HandleTimeZoneChange(
void ReminderRequest::OnSameNotificationIdCovered()
{
- SetState(false, REMINDER_STATUS_ALERTING | REMINDER_STATUS_SHOWING | REMINDER_STATUS_SNOOZE,
- "OnSameNotificationIdCovered");
+ ANSR_LOGI("Reminder[%{public}d] same notification id covered.", reminderId_);
+ OnClose(true);
}
void ReminderRequest::OnShow(bool isPlaySoundOrVibration, bool isSysTimeChanged, bool allowToNotify)
@@ -514,6 +519,52 @@ void ReminderRequest::RecoverActionButtonJsonMode(const std::string &jsonString)
resource, buttonWantAgent, buttonDataShareUpdate);
}
+void ReminderRequest::DeserializeButtonInfoFromJson(const std::string& jsonString)
+{
+ if (jsonString.empty()) {
+ return;
+ }
+ if (!nlohmann::json::accept(jsonString)) {
+ ANSR_LOGW("Not a json string.");
+ return;
+ }
+ nlohmann::json root = nlohmann::json::parse(jsonString, nullptr, false);
+ if (root.is_discarded()) {
+ ANSR_LOGW("Parse json data failed.");
+ return;
+ }
+ if (!root.is_array()) {
+ return;
+ }
+ for (auto& button : root) {
+ int32_t type = static_cast(ActionButtonType::INVALID);
+ GetJsonValue(button, "type", type);
+ std::string title;
+ GetJsonValue(button, "title", title);
+ std::string resource;
+ GetJsonValue(button, "titleResource", resource);
+ std::string uri;
+ auto buttonWantAgent = std::make_shared();
+ if (button.contains("wantAgent") && !button["wantAgent"].empty()) {
+ nlohmann::json wantAgent = button["wantAgent"];
+ GetJsonValue(wantAgent, "pkgName", buttonWantAgent->pkgName);
+ GetJsonValue(wantAgent, "abilityName", buttonWantAgent->abilityName);
+ GetJsonValue(wantAgent, "uri", uri);
+ }
+ auto buttonDataShareUpdate = std::make_shared();
+ if (button.contains("dataShareUpdate") && !button["dataShareUpdate"].empty()) {
+ nlohmann::json dataShareUpdate = button["dataShareUpdate"];
+ GetJsonValue(dataShareUpdate, "uri", buttonDataShareUpdate->uri);
+ GetJsonValue(dataShareUpdate, "equalTo", buttonDataShareUpdate->equalTo);
+ GetJsonValue(dataShareUpdate, "valuesBucket", buttonDataShareUpdate->valuesBucket);
+ }
+ if (type == ActionButtonType::CUSTOM) {
+ customButtonUri_ = uri;
+ }
+ SetActionButton(title, ActionButtonType(type), resource, buttonWantAgent, buttonDataShareUpdate);
+ }
+}
+
void ReminderRequest::DeserializeButtonInfo(const std::string& buttonInfoStr)
{
std::vector multiButton = StringSplit(buttonInfoStr, SEP_BUTTON_MULTI);
@@ -576,31 +627,23 @@ void ReminderRequest::RecoverWantAgentByJson(const std::string& wantAgentInfo, c
ANSR_LOGW("parse json data failed");
return;
}
- if (!root.contains("pkgName") || !root["pkgName"].is_string() ||
- !root.contains("abilityName") || !root["abilityName"].is_string() ||
- !root.contains("uri") || !root["uri"].is_string() ||
- !root.contains("parameters") || !root["parameters"].is_string()) {
- return;
- }
- std::string pkgName = root.at("pkgName").get();
- std::string abilityName = root.at("abilityName").get();
- std::string uri = root.at("uri").get();
- std::string parameters = root.at("parameters").get();
switch (type) {
case WANT_AGENT_FLAG: {
auto wai = std::make_shared();
- wai->pkgName = pkgName;
- wai->abilityName = abilityName;
- wai->uri = uri;
+ GetJsonValue(root, "pkgName", wai->pkgName);
+ GetJsonValue(root, "abilityName", wai->abilityName);
+ GetJsonValue(root, "uri", wai->uri);
+ std::string parameters;
+ GetJsonValue(root, "parameters", parameters);
wai->parameters = AAFwk::WantParamWrapper::ParseWantParams(parameters);
SetWantAgentInfo(wai);
break;
}
case MAX_WANT_AGENT_FLAG: {
auto maxScreenWantAgentInfo = std::make_shared();
- maxScreenWantAgentInfo->pkgName = pkgName;
- maxScreenWantAgentInfo->abilityName = abilityName;
+ GetJsonValue(root, "pkgName", maxScreenWantAgentInfo->pkgName);
+ GetJsonValue(root, "abilityName", maxScreenWantAgentInfo->abilityName);
SetMaxScreenWantAgentInfo(maxScreenWantAgentInfo);
break;
}
@@ -755,6 +798,11 @@ std::map R
return actionButtonMap_;
}
+void ReminderRequest::SetActionButtons(const std::map& buttons)
+{
+ actionButtonMap_ = buttons;
+}
+
std::string ReminderRequest::GetCreatorBundleName() const
{
return creatorBundleName_;
@@ -932,6 +980,16 @@ std::string ReminderRequest::GetCustomButtonUri() const
return customButtonUri_;
}
+bool ReminderRequest::IsShare() const
+{
+ return isShare_;
+}
+
+void ReminderRequest::SetShare(const bool isShare)
+{
+ isShare_ = isShare;
+}
+
void ReminderRequest::SetCustomRingUri(const std::string &uri)
{
customRingUri_ = uri;
@@ -1450,6 +1508,7 @@ void ReminderRequest::AddActionButtons(NotificationRequest& notificationRequest,
break;
}
want->SetParam(PARAM_REMINDER_ID, reminderId_);
+ want->SetParam(PARAM_REMINDER_SHARE, isShare_);
std::vector> wants;
wants.push_back(want);
auto title = static_cast(button.second.title);
@@ -1481,6 +1540,7 @@ void ReminderRequest::UpdateNotificationAddRemovalWantAgent(NotificationRequest&
auto want = std::make_shared();
want->SetAction(REMINDER_EVENT_REMOVE_NOTIFICATION);
want->SetParam(PARAM_REMINDER_ID, reminderId_);
+ want->SetParam(PARAM_REMINDER_SHARE, isShare_);
std::vector> wants;
wants.push_back(want);
AbilityRuntime::WantAgent::WantAgentInfo wantAgentInfo(
@@ -1508,6 +1568,7 @@ std::shared_ptr ReminderRequest::CreateWan
auto want = std::make_shared();
want->SetAction(REMINDER_EVENT_CLICK_ALERT);
want->SetParam(PARAM_REMINDER_ID, reminderId_);
+ want->SetParam(PARAM_REMINDER_SHARE, isShare_);
std::vector> wantes;
wantes.push_back(want);
AbilityRuntime::WantAgent::WantAgentInfo wantInfo(
diff --git a/frameworks/reminder/src/reminder_request_calendar.cpp b/frameworks/reminder/src/reminder_request_calendar.cpp
index 00418b5f27c9484fd946e5f344956246170b0307..e32e2c7d6e4c820df86df14709c03799cb2c1f3e 100644
--- a/frameworks/reminder/src/reminder_request_calendar.cpp
+++ b/frameworks/reminder/src/reminder_request_calendar.cpp
@@ -796,6 +796,31 @@ uint64_t ReminderRequestCalendar::GetLastStartDateTime() const
return lastStartDateTime_;
}
+void ReminderRequestCalendar::Copy(const sptr& other)
+{
+ if (other == nullptr || other->GetReminderType() != ReminderType::CALENDAR) {
+ return;
+ }
+ if (!IsShare() || !other->IsShare()) {
+ return;
+ }
+ SetNotificationId(other->GetNotificationId());
+ SetTriggerTimeInMilli(other->GetTriggerTimeInMilli());
+ SetSlotType(other->GetSlotType());
+ SetCustomButtonUri(other->GetCustomButtonUri());
+ SetTitle(other->GetTitle());
+ SetContent(other->GetContent());
+ SetActionButtons(other->GetActionButtons());
+ SetWantAgentInfo(other->GetWantAgentInfo());
+ SetAutoDeletedTime(other->GetAutoDeletedTime());
+ ReminderRequestCalendar* calendar = static_cast(other.GetRefPtr());
+ SetDateTime(calendar->GetDateTime());
+ SetEndDateTime(calendar->GetEndDateTime());
+ SetFirstDesignateYear(calendar->GetFirstDesignateYear());
+ SetFirstDesignageMonth(calendar->GetFirstDesignageMonth());
+ SetFirstDesignateDay(calendar->GetFirstDesignateDay());
+}
+
std::string ReminderRequestCalendar::SerializationRRule()
{
constexpr int32_t INDENT = -1;
diff --git a/frameworks/reminder/test/unittest/reminder_request_calendar_test.cpp b/frameworks/reminder/test/unittest/reminder_request_calendar_test.cpp
index 5cfdbf893de04b6bea0af2f25df83bd90a70421f..33a3216d7ba3af6e0d22d3e05936b489f709f494 100644
--- a/frameworks/reminder/test/unittest/reminder_request_calendar_test.cpp
+++ b/frameworks/reminder/test/unittest/reminder_request_calendar_test.cpp
@@ -1699,5 +1699,31 @@ HWTEST_F(ReminderRequestCalendarTest, InitTriggerTime_001, Function | SmallTest
calendar.repeatDaysOfWeek_ = 1;
EXPECT_EQ(calendar.InitTriggerTime(), true);
}
+
+/**
+ * @tc.name: Copy_001
+ * @tc.desc: Test Copy parameters.
+ * @tc.type: FUNC
+ * @tc.require:I9BM6I
+ */
+HWTEST_F(ReminderRequestCalendarTest, Copy_001, Function | SmallTest | Level1)
+{
+ sptr reminder1 = new ReminderRequestCalendar(1);
+ reminder1->SetTitle("test_reminder1");
+ sptr reminder2 = new ReminderRequestCalendar(1);
+ reminder2->SetTitle("test_reminder2");
+
+ ReminderRequestCalendar* calendar = static_cast(reminder1.GetRefPtr());
+ calendar->Copy(nullptr);
+ EXPECT_EQ(reminder1->GetTitle(), "test_reminder1");
+ calendar->Copy(reminder2);
+ EXPECT_EQ(reminder1->GetTitle(), "test_reminder1");
+ reminder1->SetShare(true);
+ calendar->Copy(reminder2);
+ EXPECT_EQ(reminder1->GetTitle(), "test_reminder1");
+ reminder2->SetShare(true);
+ calendar->Copy(reminder2);
+ EXPECT_EQ(reminder1->GetTitle(), "test_reminder2");
+}
}
}
\ No newline at end of file
diff --git a/frameworks/reminder/test/unittest/reminder_request_test.cpp b/frameworks/reminder/test/unittest/reminder_request_test.cpp
index 41753019258c2107552820bc6cf3ed59a949ec31..19339c74871dd9ca4b67794610c60cbdac17569a 100644
--- a/frameworks/reminder/test/unittest/reminder_request_test.cpp
+++ b/frameworks/reminder/test/unittest/reminder_request_test.cpp
@@ -1853,19 +1853,19 @@ HWTEST_F(ReminderRequestTest, RecoverWantAgentByJson_00001, Function | SmallTest
jsonValue = R"({"pkgName":"com.example.myapplication","abilityName":"MainAbility"})";
rrc->RecoverWantAgentByJson(jsonValue, 0);
- EXPECT_EQ(rrc->GetWantAgentInfo()->abilityName, "");
+ EXPECT_EQ(rrc->GetWantAgentInfo()->abilityName, "MainAbility");
jsonValue = R"({"pkgName":"com.example.myapplication","abilityName":"MainAbility","uri":1})";
rrc->RecoverWantAgentByJson(jsonValue, 0);
- EXPECT_EQ(rrc->GetWantAgentInfo()->abilityName, "");
+ EXPECT_EQ(rrc->GetWantAgentInfo()->abilityName, "MainAbility");
jsonValue = R"({"pkgName":"com.example.myapplication","abilityName":"MainAbility","uri":""})";
rrc->RecoverWantAgentByJson(jsonValue, 0);
- EXPECT_EQ(rrc->GetWantAgentInfo()->abilityName, "");
+ EXPECT_EQ(rrc->GetWantAgentInfo()->abilityName, "MainAbility");
jsonValue = R"({"pkgName":"com.example.myapplication","abilityName":"MainAbility","uri":"","parameters":1})";
rrc->RecoverWantAgentByJson(jsonValue, 0);
- EXPECT_EQ(rrc->GetWantAgentInfo()->abilityName, "");
+ EXPECT_EQ(rrc->GetWantAgentInfo()->abilityName, "MainAbility");
jsonValue = R"({"pkgName":"com.example.myapplication","abilityName":"MainAbility","uri":"","parameters":""})";
rrc->RecoverWantAgentByJson(jsonValue, 0);
@@ -2240,5 +2240,30 @@ HWTEST_F(ReminderRequestTest, SetMaxWantAgentStr_001, Function | SmallTest | Lev
rrc->SetMaxWantAgentStr("@#$^%&*)(&&*^(@!#%$#$))");
EXPECT_EQ(rrc->GetMaxWantAgentStr(), "@#$^%&*)(&&*^(@!#%$#$))");
}
+
+/**
+ * @tc.name: DeserializeButtonInfoFromJson_001
+ * @tc.desc: Test DeserializeButtonInfoFromJson parameters.
+ * @tc.type: FUNC
+ * @tc.require: issueI8CDH3
+ */
+HWTEST_F(ReminderRequestTest, DeserializeButtonInfoFromJson_001, Function | SmallTest | Level1)
+{
+ ReminderRequest request(1);
+ request.DeserializeButtonInfoFromJson("");
+ EXPECT_EQ(request.GetActionButtons().size(), 0);
+ request.DeserializeButtonInfoFromJson("{11");
+ EXPECT_EQ(request.GetActionButtons().size(), 0);
+ request.DeserializeButtonInfoFromJson("{}");
+ EXPECT_EQ(request.GetActionButtons().size(), 0);
+ request.DeserializeButtonInfoFromJson("[]");
+ EXPECT_EQ(request.GetActionButtons().size(), 0);
+ request.DeserializeButtonInfoFromJson(
+ R"([{"titleResource":"join","title":"test","type":0,"wantAgent":{"pkgName":"","abilityName":"","uri":""}}])");
+ EXPECT_EQ(request.GetActionButtons().size(), 1);
+ request.DeserializeButtonInfoFromJson(
+ R"([{"titleResource":"join","title":"test","type":2,"wantAgent":{"pkgName":"","abilityName":"","uri":""}}])");
+ EXPECT_EQ(request.GetActionButtons().size(), 2);
+}
}
}
diff --git a/interfaces/inner_api/reminder_request.h b/interfaces/inner_api/reminder_request.h
index 5374d67f5bd70a62baeb039f3771ec2b8799d38e..d295c303f547f9248df4d7184ab5daa96cc284d5 100644
--- a/interfaces/inner_api/reminder_request.h
+++ b/interfaces/inner_api/reminder_request.h
@@ -310,6 +310,11 @@ public:
*/
std::map GetActionButtons() const;
+ /**
+ * @brief Set the reminder action buttons.
+ */
+ void SetActionButtons(const std::map& buttons);
+
/**
* @brief Obtains creator bundle name
*
@@ -848,6 +853,16 @@ public:
*/
std::string GetCustomButtonUri() const;
+ /**
+ * @brief Is the reminder from datashare.
+ */
+ bool IsShare() const;
+
+ /**
+ * @brief Set the reminder from datashare.
+ */
+ void SetShare(const bool isShare);
+
/**
* @brief Gets custom ring uri.
*
@@ -917,6 +932,7 @@ public:
* Recover from the rdb.
*/
void DeserializeButtonInfo(const std::string& buttonInfoStr);
+ void DeserializeButtonInfoFromJson(const std::string& jsonString);
static int32_t GetActualTime(const TimeTransferType &type, int32_t cTime);
static int32_t GetCTime(const TimeTransferType &type, int32_t actualTime);
@@ -971,6 +987,7 @@ public:
static const std::string REMINDER_EVENT_REMOVE_NOTIFICATION;
static const std::string REMINDER_EVENT_LOAD_REMINDER;
static const std::string PARAM_REMINDER_ID;
+ static const std::string PARAM_REMINDER_SHARE;
static const uint8_t REMINDER_STATUS_INACTIVE;
static const uint8_t REMINDER_STATUS_ACTIVE;
static const uint8_t REMINDER_STATUS_ALERTING;
@@ -1088,6 +1105,7 @@ private:
std::string title_ {};
std::string bundleName_ {};
bool isExpired_ {false};
+ bool isShare_ {false};
uint8_t snoozeTimes_ {0};
uint8_t snoozeTimesDynamic_ {0};
uint8_t state_ {0};
diff --git a/interfaces/inner_api/reminder_request_calendar.h b/interfaces/inner_api/reminder_request_calendar.h
index f117f14daafd420ae1edc2670ae425cf39de0d66..3dc1fb58eb36eac76ad684cee8116367874c73a8 100644
--- a/interfaces/inner_api/reminder_request_calendar.h
+++ b/interfaces/inner_api/reminder_request_calendar.h
@@ -319,6 +319,11 @@ public:
ReminderRequestCalendar() : ReminderRequest(ReminderType::CALENDAR) {};
+ /**
+ * @brief Copy datashare reminder
+ */
+ void Copy(const sptr& other);
+
public:
static constexpr uint8_t MAX_MONTHS_OF_YEAR = 12;
static constexpr uint8_t MAX_DAYS_OF_MONTH = 31;
diff --git a/services/ans/src/advanced_notification_reminder_service.cpp b/services/ans/src/advanced_notification_reminder_service.cpp
index b20d405af40af1bdec504245fe691d7971f53f6f..be5ccf0c49bed20d846fe1f483a0e085c549271d 100644
--- a/services/ans/src/advanced_notification_reminder_service.cpp
+++ b/services/ans/src/advanced_notification_reminder_service.cpp
@@ -120,6 +120,7 @@ ErrCode AdvancedNotificationService::SetNotificationRemindType(sptr
+
+namespace OHOS::Notification {
+class ReminderCalendarShareTable {
+public:
+ static constexpr const char* ID = "_id";
+ static constexpr const char* EVENT_ID = "event_id";
+ static constexpr const char* BEGIN = "begin";
+ static constexpr const char* END = "end";
+ static constexpr const char* ALARM_TIME = "alarmTime";
+ static constexpr const char* STATE = "state";
+ static constexpr const char* MINUTES = "minutes";
+ static constexpr const char* TITLE = "title";
+ static constexpr const char* CONTENT = "content";
+ static constexpr const char* WANT_AGENT = "wantAgent";
+ static constexpr const char* BUTTONS = "buttons";
+ static constexpr const char* SLOT_TYPE = "slotType";
+ static constexpr const char* KEEP_HEADSUP = "keepHeadsUp";
+
+ static constexpr const char* PROXY = "datashareproxy://com.huawei.hmos.calendardata/CalendarAlerts";
+ static constexpr const char* NAME = "com.huawei.hmos.calendar";
+ static constexpr const char* DATA_NAME = "com.huawei.hmos.calendardata";
+ static constexpr const char* ENTRY = "ReminderCallbackExtAbility";
+
+ static constexpr const char* PARAM_CALLBACK_TYPE = "CallbackType";
+
+ /**
+ * @brief An alert begins in this state when it is first created.
+ */
+ static constexpr int8_t STATE_SCHEDULED = 0;
+ /**
+ * @brief After a notification for an alert has been created it should be updated to fired.
+ */
+ static constexpr int8_t STATE_FIRED = 1;
+ /**
+ * @brief Once the user has dismissed the notification the alert's state should be set to
+ * dismissed so it is not fired again.
+ */
+ static constexpr int8_t STATE_DISMISSED = 2;
+
+ /**
+ * @brief Start calendardata reason: Device start or restart complete.
+ */
+ static constexpr int8_t START_BY_BOOT_COMPLETE = 0;
+ /**
+ * @brief Start calendardata reason: Time chage.
+ */
+ static constexpr int8_t START_BY_TIME_CHANGE = 1;
+ /**
+ * @brief Start calendardata reason: Time zone chage.
+ */
+ static constexpr int8_t START_BY_TIMEZONE_CHANGE = 2;
+ /**
+ * @brief Start calendardata reason: Timer.
+ */
+ static constexpr int8_t START_BY_NORMAL = 3;
+ /**
+ * @brief Start calendardata reason: Language change.
+ */
+ static constexpr int8_t START_BY_LANGUAGE_CHANGE = 4;
+};
+} // namespace OHOS::Notification
+#endif // BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_REMINDER_INCLUDE_REMINDER_CALENDAR_SHARE_TABLE_H
\ No newline at end of file
diff --git a/services/reminder/include/reminder_data_manager.h b/services/reminder/include/reminder_data_manager.h
index c919530981281a2316b7c3a0be16daec0804fc23..a0023f94693d83935850f21f2d63ef2a19b9278f 100644
--- a/services/reminder/include/reminder_data_manager.h
+++ b/services/reminder/include/reminder_data_manager.h
@@ -222,6 +222,26 @@ public:
*/
void ClickReminder(const OHOS::EventFwk::Want &want);
+ /**
+ * @brief Load reminder event.
+ */
+ void OnLoadReminderEvent(const EventFwk::Want& want);
+
+ /**
+ * @brief datashare notify, share reminder insert.
+ */
+ void OnDataShareInsert();
+
+ /**
+ * @brief datashare notify, share reminder update.
+ */
+ void OnDataShareUpdate(const std::map>& reminders);
+
+ /**
+ * @brief datashare notify, share reminder delete.
+ */
+ void OnDataShareDelete();
+
/**
* Handle auto delete time
*/
@@ -263,9 +283,7 @@ public:
int32_t QueryActiveReminderCount();
- void ReceiveLoadReminderEvent();
-
- void StartReminderLoadTimer();
+ void StartLoadTimer();
static constexpr uint8_t TIME_ZONE_CHANGE = 0;
static constexpr uint8_t DATE_TIME_CHANGE = 1;
@@ -401,9 +419,10 @@ private:
* Find the reminder from reminderVector_ by reminder id.
*
* @param reminderId Indicates the reminder id.
+ * @param isShare Indicates the reminder datashare flag.
* @return pointer of reminder request or nullptr.
*/
- sptr FindReminderRequestLocked(const int32_t &reminderId);
+ sptr FindReminderRequestLocked(const int32_t reminderId, const bool isShare);
/**
* Obtains the recent reminder which is not expired from reminder vector.
@@ -502,8 +521,9 @@ private:
* 2. cancels the notification.
*
* @param reminderId Indicates the reminder id.
+ * @param isShare Indicates the reminder datashare flag.
*/
- void RemoveReminderLocked(const int32_t &reminderId);
+ void RemoveReminderLocked(const int32_t reminderId, const bool isShare);
/**
* Resets timer status.
@@ -639,7 +659,20 @@ private:
*/
void ReportSysEvent(const sptr& reminder);
- int64_t CreateReminderLoadTimer(const sptr timer);
+ /**
+ * @brief Create load reminder timer.
+ */
+ uint64_t CreateTimer(const sptr& timer);
+
+ /**
+ * @brief Load reminder from datashare.
+ */
+ void LoadShareReminders();
+
+ /**
+ * @brief Load reminder from datashare.
+ */
+ void UpdateShareReminders(const std::map>& reminders);
/**
* Single instance.
@@ -737,7 +770,10 @@ private:
std::atomic saReadyFlag_{ 0 };
std::mutex timeLoadMutex_;
- int32_t reminderLoadtimerId_ {0};
+ uint64_t reminderLoadtimerId_ {0};
+
+ // Last time the calendardata was launched.
+ std::atomic lastStartTime_ {0};
};
} // namespace OHOS
} // namespace Notification
diff --git a/services/reminder/include/reminder_datashare_helper.h b/services/reminder/include/reminder_datashare_helper.h
new file mode 100644
index 0000000000000000000000000000000000000000..94023da07ef2ceba2eafa3f933881a1244f65657
--- /dev/null
+++ b/services/reminder/include/reminder_datashare_helper.h
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2024 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_DISTRIBUTED_NOTIFICATION_SERVICE_REMINDER_INCLUDE_REMINDER_DATASHARE_HELPER_H
+#define BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_REMINDER_INCLUDE_REMINDER_DATASHARE_HELPER_H
+
+#include "ffrt.h"
+#include "reminder_request.h"
+#include "datashare_helper.h"
+#include "data_ability_observer_stub.h"
+
+#include
+#include
+
+namespace OHOS::Notification {
+class ReminderDataShareHelper {
+public:
+ static ReminderDataShareHelper& GetInstance();
+
+ /**
+ * @brief Register datashare observer.
+ */
+ bool RegisterObserver();
+
+ /**
+ * @brief UnRegister datashare observer.
+ */
+ bool UnRegisterObserver();
+
+public:
+ /**
+ * @brief Search for reminders from the current time to X minutes.
+ */
+ bool Query(std::map>& reminders);
+
+ /**
+ * @brief Update the reminder state.
+ * state is ReminderCalendarShareTable::STATE_*
+ */
+ bool Update(const int32_t reminderId, const int32_t state);
+
+ /**
+ * @brief Start calendar data extension.
+ * reason is ReminderCalendarShareTable::START_*
+ */
+ void StartDataExtension(const int32_t reason);
+
+public:
+ /**
+ * @brief Set current user id.
+ */
+ void SetUserId(const int32_t userId)
+ {
+ curUserId_ = userId;
+ }
+
+ /**
+ * @brief Update calendar uid and calendar data uid.
+ */
+ void UpdateCalendarUid();
+
+public:
+ /**
+ * @brief When datashare notify OnChange, the change type is insert.
+ */
+ void OnDataInsert(const DataShare::DataShareObserver::ChangeInfo& info);
+
+ /**
+ * @brief When datashare notify OnChange, the change type is update.
+ */
+ void OnDataUpdate(const DataShare::DataShareObserver::ChangeInfo& info);
+
+ /**
+ * @brief When datashare notify OnChange, the change type is delete.
+ */
+ void OnDataDelete(const DataShare::DataShareObserver::ChangeInfo& info);
+
+private:
+ /**
+ * @brief Build datasharehelper, need to release it after use,
+ * call ReleaseDataShareHelper.
+ */
+ std::shared_ptr CreateDataShareHelper();
+ bool ReleaseDataShareHelper(const std::shared_ptr& helper);
+
+ /**
+ * @brief Get share table columns.
+ */
+ std::vector GetColumns() const;
+
+private:
+ /**
+ * @brief Build ReminderRequest from DataShareResultSet.
+ */
+ sptr CreateReminder(const std::shared_ptr& result);
+
+ /**
+ * @brief Build ReminderRequest from ChangeInfo.
+ */
+ std::map> CreateReminder(
+ const DataShare::DataShareObserver::ChangeInfo& info);
+
+ /**
+ * @brief
+ */
+ void InitBaseInfo(sptr& reminder);
+
+private:
+ // Singleton
+ ReminderDataShareHelper();
+ ~ReminderDataShareHelper() = default;
+
+ ReminderDataShareHelper(const ReminderDataShareHelper&) = delete;
+ ReminderDataShareHelper& operator=(const ReminderDataShareHelper&) = delete;
+ ReminderDataShareHelper(ReminderDataShareHelper&&) = delete;
+ ReminderDataShareHelper& operator=(ReminderDataShareHelper&&) = delete;
+
+private:
+ int32_t curUserId_ {0};
+ int32_t uid_ {0}; // calendar
+ int32_t dataUid_ {0}; // calendardata
+ std::atomic insertTask_ {false};
+ std::atomic deleteTask_ {false};
+ std::atomic insertTime_ {0};
+ std::atomic deleteTime_ {0};
+
+ std::mutex mutex_; // for observer_
+ std::shared_ptr observer_;
+
+ std::shared_ptr queue_; // for OnChange
+
+private:
+class ReminderDataObserver : public DataShare::DataShareObserver {
+public:
+ ReminderDataObserver() = default;
+ ~ReminderDataObserver() = default;
+
+ /**
+ * @brief Notification of data changes.
+ */
+ void OnChange(const ChangeInfo& info) override;
+};
+};
+} // namespace OHOS::Notification
+#endif // BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_REMINDER_INCLUDE_REMINDER_DATASHARE_HELPER_H
\ No newline at end of file
diff --git a/services/reminder/src/reminder_data_manager.cpp b/services/reminder/src/reminder_data_manager.cpp
index e66e30309300ab6e7e2ab17a85e399e9f9a552fc..f2441d6d0a304e945199de42ee8d689ed9e61ab2 100644
--- a/services/reminder/src/reminder_data_manager.cpp
+++ b/services/reminder/src/reminder_data_manager.cpp
@@ -51,6 +51,8 @@
#endif
#include "reminder_utils.h"
#include "notification_helper.h"
+#include "reminder_datashare_helper.h"
+#include "reminder_calendar_share_table.h"
namespace OHOS {
namespace Notification {
@@ -81,6 +83,13 @@ std::mutex ReminderDataManager::TIMER_MUTEX;
std::mutex ReminderDataManager::ACTIVE_MUTEX;
constexpr int32_t CONNECT_EXTENSION_INTERVAL = 100;
constexpr int32_t CONNECT_EXTENSION_MAX_RETRY_TIMES = 3;
+constexpr int64_t ONE_DAY_TIME = 24 * 60 * 60 * 1000;
+
+inline int64_t TimeDistance(int64_t first, int64_t last)
+{
+ return first > last ? first - last : last - first;
+}
+
std::shared_ptr ReminderDataManager::serviceQueue_ = nullptr;
ReminderDataManager::ReminderDataManager() = default;
ReminderDataManager::~ReminderDataManager() = default;
@@ -114,7 +123,7 @@ ErrCode ReminderDataManager::CancelReminder(
{
HITRACE_METER_NAME(HITRACE_TAG_OHOS, __PRETTY_FUNCTION__);
ANSR_LOGI("cancel reminder id: %{public}d", reminderId);
- sptr reminder = FindReminderRequestLocked(reminderId);
+ sptr reminder = FindReminderRequestLocked(reminderId, false);
if (reminder == nullptr) {
ANSR_LOGW("Cancel reminder, not find the reminder");
return ERR_REMINDER_NOT_EXIST;
@@ -136,7 +145,7 @@ ErrCode ReminderDataManager::CancelReminder(
StopTimerLocked(TimerType::ALERTING_TIMER);
}
CancelNotification(reminder);
- RemoveReminderLocked(reminderId);
+ RemoveReminderLocked(reminderId, false);
StartRecentReminder();
return ERR_OK;
}
@@ -153,7 +162,7 @@ ErrCode ReminderDataManager::CancelAllReminders(const std::string& bundleName,
sptr ReminderDataManager::CheckExcludeDateParam(const int32_t reminderId,
const int32_t callingUid)
{
- sptr reminder = FindReminderRequestLocked(reminderId);
+ sptr reminder = FindReminderRequestLocked(reminderId, false);
if (reminder == nullptr) {
ANSR_LOGW("Check reminder failed, not find the reminder");
return nullptr;
@@ -264,8 +273,12 @@ void ReminderDataManager::CancelRemindersImplLocked(const std::string& packageNa
}
CancelNotification(*vit);
RemoveFromShowedReminders(*vit);
- vit = reminderVector_.erase(vit);
- totalCount_--;
+ if (!(*vit)->IsShare()) {
+ vit = reminderVector_.erase(vit);
+ totalCount_--;
+ } else {
+ ++vit;
+ }
continue;
}
++vit;
@@ -355,7 +368,8 @@ void ReminderDataManager::AddToShowedReminders(const sptr &remi
{
std::lock_guard lock(ReminderDataManager::SHOW_MUTEX);
for (auto it = showedReminderVector_.begin(); it != showedReminderVector_.end(); ++it) {
- if (reminder->GetReminderId() == (*it)->GetReminderId()) {
+ if (reminder->GetReminderId() == (*it)->GetReminderId() &&
+ reminder->IsShare() == (*it)->IsShare()) {
ANSR_LOGD("Showed reminder is already exist");
return;
}
@@ -438,6 +452,7 @@ std::shared_ptr ReminderDataManager::CreateTimerInfo(TimerTyp
want->SetAction(ReminderRequest::REMINDER_EVENT_ALARM_ALERT);
sharedTimerInfo->SetAction(ReminderRequest::REMINDER_EVENT_ALARM_ALERT);
want->SetParam(ReminderRequest::PARAM_REMINDER_ID, activeReminderId_);
+ want->SetParam(ReminderRequest::PARAM_REMINDER_SHARE, reminderRequest->IsShare());
break;
}
case (TimerType::ALERTING_TIMER): {
@@ -448,6 +463,7 @@ std::shared_ptr ReminderDataManager::CreateTimerInfo(TimerTyp
want->SetAction(ReminderRequest::REMINDER_EVENT_ALERT_TIMEOUT);
sharedTimerInfo->SetAction(ReminderRequest::REMINDER_EVENT_ALERT_TIMEOUT);
want->SetParam(ReminderRequest::PARAM_REMINDER_ID, alertingReminderId_);
+ want->SetParam(ReminderRequest::PARAM_REMINDER_SHARE, reminderRequest->IsShare());
break;
}
default:
@@ -470,11 +486,11 @@ std::shared_ptr ReminderDataManager::CreateTimerInfo(TimerTyp
return sharedTimerInfo;
}
-sptr ReminderDataManager::FindReminderRequestLocked(const int32_t &reminderId)
+sptr ReminderDataManager::FindReminderRequestLocked(const int32_t reminderId, const bool isShare)
{
std::lock_guard lock(ReminderDataManager::MUTEX);
for (auto it = reminderVector_.begin(); it != reminderVector_.end(); ++it) {
- if (reminderId == (*it)->GetReminderId()) {
+ if (reminderId == (*it)->GetReminderId() && isShare == (*it)->IsShare()) {
return *it;
}
}
@@ -490,7 +506,8 @@ bool ReminderDataManager::cmp(sptr &reminderRequest, sptr(want.GetIntParam(ReminderRequest::PARAM_REMINDER_ID, -1));
- sptr reminder = FindReminderRequestLocked(reminderId);
+ bool isShare = want.GetBoolParam(ReminderRequest::PARAM_REMINDER_SHARE, false);
+ sptr reminder = FindReminderRequestLocked(reminderId, isShare);
if (reminder == nullptr) {
ANSR_LOGW("Invalid reminder id: %{public}d", reminderId);
return;
@@ -553,12 +570,16 @@ void ReminderDataManager::CloseReminder(const sptr &reminder, b
StopSoundAndVibrationLocked(reminder);
StopTimerLocked(TimerType::ALERTING_TIMER);
}
- reminder->OnClose(true);
- RemoveFromShowedReminders(reminder);
- store_->UpdateOrInsert(reminder);
if (cancelNotification) {
CancelNotification(reminder);
}
+ reminder->OnClose(true);
+ RemoveFromShowedReminders(reminder);
+ if (reminder->IsShare()) {
+ ReminderDataShareHelper::GetInstance().Update(reminderId, ReminderCalendarShareTable::STATE_DISMISSED);
+ } else {
+ store_->UpdateOrInsert(reminder);
+ }
}
std::shared_ptr ReminderDataManager::GetInstance()
@@ -575,7 +596,7 @@ std::shared_ptr ReminderDataManager::InitInstance()
return REMINDER_DATA_MANAGER;
}
-void ReminderDataManager::StartReminderLoadTimer()
+void ReminderDataManager::StartLoadTimer()
{
sptr timer = MiscServices::TimeServiceClient::GetInstance();
if (timer == nullptr) {
@@ -584,14 +605,14 @@ void ReminderDataManager::StartReminderLoadTimer()
}
std::lock_guard locker(timeLoadMutex_);
if (reminderLoadtimerId_ == 0) {
- reminderLoadtimerId_ = CreateReminderLoadTimer(timer);
+ reminderLoadtimerId_ = CreateTimer(timer);
}
timer->StopTimer(reminderLoadtimerId_);
uint64_t nowMilli = GetCurrentTime() + NEXT_LOAD_TIME;
timer->StartTimer(reminderLoadtimerId_, nowMilli);
}
-int64_t ReminderDataManager::CreateReminderLoadTimer(const sptr timer)
+uint64_t ReminderDataManager::CreateTimer(const sptr& timer);
{
auto sharedTimerInfo = std::make_shared();
sharedTimerInfo->SetRepeat(true);
@@ -791,6 +812,13 @@ void ReminderDataManager::RefreshRemindersDueToSysTimeChange(uint8_t type)
StopTimerLocked(TimerType::TRIGGER_TIMER);
}
LoadReminderFromDb();
+ int64_t now = GetCurrentTime();
+ LoadShareReminders();
+ if (TimeDistance(now, lastStartTime_) > ONE_DAY_TIME) {
+ lastStartTime_ = now;
+ ReminderDataShareHelper::GetInstance().StartDataExtension(type == TIME_ZONE_CHANGE ?
+ ReminderCalendarShareTable::START_BY_TIMEZONE_CHANGE : ReminderCalendarShareTable::START_BY_TIME_CHANGE);
+ }
std::vector> showImmediately;
std::vector> extensionReminders;
RefreshRemindersLocked(type, showImmediately, extensionReminders);
@@ -802,7 +830,8 @@ void ReminderDataManager::RefreshRemindersDueToSysTimeChange(uint8_t type)
void ReminderDataManager::TerminateAlerting(const OHOS::EventFwk::Want &want)
{
int32_t reminderId = static_cast(want.GetIntParam(ReminderRequest::PARAM_REMINDER_ID, -1));
- sptr reminder = FindReminderRequestLocked(reminderId);
+ bool isShare = want.GetBoolParam(ReminderRequest::PARAM_REMINDER_SHARE, false);
+ sptr reminder = FindReminderRequestLocked(reminderId, isShare);
if (reminder == nullptr) {
ANSR_LOGE("Invalid reminder id: %{public}d", reminderId);
return;
@@ -900,11 +929,12 @@ bool ReminderDataManager::ShouldAlert(const sptr &reminder) con
void ReminderDataManager::ShowActiveReminder(const EventFwk::Want &want)
{
int32_t reminderId = static_cast(want.GetIntParam(ReminderRequest::PARAM_REMINDER_ID, -1));
+ bool isShare = want.GetBoolParam(ReminderRequest::PARAM_REMINDER_SHARE, false);
ANSR_LOGI("Begin to show reminder(reminderId=%{public}d)", reminderId);
if (reminderId == activeReminderId_) {
ResetStates(TimerType::TRIGGER_TIMER);
}
- sptr reminder = FindReminderRequestLocked(reminderId);
+ sptr reminder = FindReminderRequestLocked(reminderId, isShare);
if (reminder == nullptr) {
ANSR_LOGW("Invalid reminder id: %{public}d", reminderId);
return;
@@ -1045,6 +1075,7 @@ void ReminderDataManager::ShowReminder(const sptr &reminder, co
ANSR_LOGD("Show the reminder(Play sound: %{public}d), %{public}s",
static_cast(isNeedToPlaySound), reminder->Dump().c_str());
int32_t reminderId = reminder->GetReminderId();
+ bool isShare = reminder->IsShare();
if (!IsAllowedNotify(reminder)) {
ANSR_LOGE("Not allow to notify.");
reminder->OnShow(false, isSysTimeChanged, false);
@@ -1075,6 +1106,9 @@ void ReminderDataManager::ShowReminder(const sptr &reminder, co
}
}
HandleSameNotificationIdShowing(reminder);
+ if (isShare) {
+ ReminderDataShareHelper::GetInstance().Update(reminderId, ReminderCalendarShareTable::STATE_FIRED);
+ }
}
store_->UpdateOrInsert(reminder);
@@ -1086,7 +1120,8 @@ void ReminderDataManager::ShowReminder(const sptr &reminder, co
void ReminderDataManager::SnoozeReminder(const OHOS::EventFwk::Want &want)
{
int32_t reminderId = static_cast(want.GetIntParam(ReminderRequest::PARAM_REMINDER_ID, -1));
- sptr reminder = FindReminderRequestLocked(reminderId);
+ bool isShare = want.GetBoolParam(ReminderRequest::PARAM_REMINDER_SHARE, false);
+ sptr reminder = FindReminderRequestLocked(reminderId, isShare);
if (reminder == nullptr) {
ANSR_LOGW("Invalid reminder id: %{public}d", reminderId);
return;
@@ -1234,9 +1269,11 @@ sptr ReminderDataManager::GetRecentReminder()
}
int32_t reminderId = (*it)->GetReminderId();
ANSR_LOGD("Containers(vector) remove. reminderId=%{public}d", reminderId);
+ if (!(*it)->IsShare()) {
+ totalCount_--;
+ store_->Delete(reminderId);
+ }
it = reminderVector_.erase(it);
- totalCount_--;
- store_->Delete(reminderId);
}
return nullptr;
}
@@ -1294,12 +1331,13 @@ void ReminderDataManager::HandleSameNotificationIdShowing(const sptrGetNotificationId();
+ bool isShare = reminder->IsShare();
ANSR_LOGD("HandleSameNotificationIdShowing notificationId=%{public}d", notificationId);
int32_t curReminderId = reminder->GetReminderId();
for (auto it = reminderVector_.begin(); it != reminderVector_.end(); ++it) {
int32_t tmpId = (*it)->GetReminderId();
- if (tmpId == curReminderId) {
+ if (tmpId == curReminderId && (*it)->IsShare() == isShare) {
continue;
}
if (!(*it)->IsShowing()) {
@@ -1311,7 +1349,11 @@ void ReminderDataManager::HandleSameNotificationIdShowing(const sptrOnSameNotificationIdCovered();
RemoveFromShowedReminders(*it);
- store_->UpdateOrInsert((*it));
+ if ((*it)->IsShare()) {
+ ReminderDataShareHelper::GetInstance().Update(tmpId, ReminderCalendarShareTable::STATE_DISMISSED);
+ } else {
+ store_->UpdateOrInsert((*it));
+ }
}
}
}
@@ -1344,13 +1386,19 @@ void ReminderDataManager::Init()
InitServiceHandler();
LoadReminderFromDb();
InitUserId();
+ ReminderDataShareHelper::GetInstance().SetUserId(currentUserId_);
+ ReminderDataShareHelper::GetInstance().UpdateCalendarUid();
+ ReminderDataShareHelper::GetInstance().RegisterObserver();
+ LoadShareReminders();
+ lastStartTime_ = GetCurrentTime();
+ ReminderDataShareHelper::GetInstance().StartDataExtension(ReminderCalendarShareTable::START_BY_BOOT_COMPLETE);
std::vector> immediatelyReminders;
std::vector> extensionReminders;
CheckReminderTime(immediatelyReminders, extensionReminders);
HandleImmediatelyShow(immediatelyReminders, false);
HandleExtensionReminder(extensionReminders);
StartRecentReminder();
- StartReminderLoadTimer();
+ StartLoadTimer();
isReminderAgentReady_ = true;
ANSR_LOGD("ReminderAgent is ready.");
}
@@ -1465,16 +1513,23 @@ bool ReminderDataManager::IsBelongToSameApp(const int32_t uidSrc,
return result;
}
-void ReminderDataManager::ReceiveLoadReminderEvent()
+void ReminderDataManager::OnLoadReminderEvent()
{
LoadReminderFromDb();
+ LoadShareReminders();
+ int64_t now = static_cast(ReminderRequest::GetCurrentTimeInMilli());
+ if (TimeDistance(now, lastStartTime_) > ONE_DAY_TIME) {
+ lastStartTime_ = now;
+ ReminderDataShareHelper::GetInstance().StartDataExtension(ReminderCalendarShareTable::START_BY_NORMAL);
+ }
StartRecentReminder();
+ StartLoadTimer();
}
void ReminderDataManager::LoadReminderFromDb()
{
- std::lock_guard lock(ReminderDataManager::MUTEX);
std::vector> existReminders = store_->GetHalfHourReminders();
+ std::lock_guard lock(ReminderDataManager::MUTEX);
reminderVector_ = existReminders;
totalCount_ = static_cast(reminderVector_.size());
ReminderRequest::GLOBAL_ID = store_->GetMaxId() + 1;
@@ -1591,7 +1646,8 @@ void ReminderDataManager::RemoveFromShowedReminders(const sptr
{
std::lock_guard lock(ReminderDataManager::SHOW_MUTEX);
for (auto it = showedReminderVector_.begin(); it != showedReminderVector_.end(); ++it) {
- if ((*it)->GetReminderId() == reminder->GetReminderId()) {
+ if ((*it)->GetReminderId() == reminder->GetReminderId() &&
+ (*it)->IsShare() == reminder->IsShare()) {
ANSR_LOGD("Containers(shownVector) remove. reminderId=%{public}d", reminder->GetReminderId());
showedReminderVector_.erase(it);
break;
@@ -1615,15 +1671,17 @@ void ReminderDataManager::RefreshRemindersLocked(uint8_t type,
}
}
-void ReminderDataManager::RemoveReminderLocked(const int32_t &reminderId)
+void ReminderDataManager::RemoveReminderLocked(const int32_t reminderId, bool isShare)
{
std::lock_guard lock(ReminderDataManager::MUTEX);
for (auto it = reminderVector_.begin(); it != reminderVector_.end();) {
- if (reminderId == (*it)->GetReminderId()) {
+ if (reminderId == (*it)->GetReminderId() && isShare == (*it)->IsShare()) {
ANSR_LOGD("Containers(vector) remove. reminderId=%{public}d", reminderId);
it = reminderVector_.erase(it);
- totalCount_--;
- store_->Delete(reminderId);
+ if (!isShare) {
+ totalCount_--;
+ store_->Delete(reminderId);
+ }
break;
} else {
++it;
@@ -1780,7 +1838,8 @@ void ReminderDataManager::ResetStates(TimerType type)
void ReminderDataManager::HandleCustomButtonClick(const OHOS::EventFwk::Want &want)
{
int32_t reminderId = static_cast(want.GetIntParam(ReminderRequest::PARAM_REMINDER_ID, -1));
- sptr reminder = FindReminderRequestLocked(reminderId);
+ bool isShare = want.GetBoolParam(ReminderRequest::PARAM_REMINDER_SHARE, false);
+ sptr reminder = FindReminderRequestLocked(reminderId, isShare);
if (reminder == nullptr) {
ANSR_LOGE("Invalid reminder id: %{public}d", reminderId);
return;
@@ -1812,13 +1871,14 @@ void ReminderDataManager::HandleCustomButtonClick(const OHOS::EventFwk::Want &wa
void ReminderDataManager::ClickReminder(const OHOS::EventFwk::Want &want)
{
int32_t reminderId = static_cast(want.GetIntParam(ReminderRequest::PARAM_REMINDER_ID, -1));
+ bool isShare = want.GetBoolParam(ReminderRequest::PARAM_REMINDER_SHARE, false);
ANSR_LOGI("click reminder[%{public}d] start", reminderId);
- sptr reminder = FindReminderRequestLocked(reminderId);
+ sptr reminder = FindReminderRequestLocked(reminderId, isShare);
if (reminder == nullptr) {
ANSR_LOGW("Invalid reminder id: %{public}d", reminderId);
return;
}
- CloseReminder(reminder, true);
+ CloseReminder(reminder, false);
StartRecentReminder();
auto wantInfo = reminder->GetWantAgentInfo();
@@ -1910,6 +1970,9 @@ void ReminderDataManager::OnLanguageChanged()
{
std::lock_guard lock(ReminderDataManager::MUTEX);
for (auto it = reminderVector_.begin(); it != reminderVector_.end(); ++it) {
+ if ((*it)->IsShare()) {
+ continue;
+ }
reminders[(*it)->GetUid()].push_back((*it));
}
}
@@ -1922,9 +1985,13 @@ void ReminderDataManager::OnLanguageChanged()
showedReminder = showedReminderVector_;
}
for (auto it = showedReminder.begin(); it != showedReminder.end(); ++it) {
+ if ((*it)->IsShare()) {
+ continue;
+ }
std::lock_guard lock(ReminderDataManager::MUTEX);
ShowReminder((*it), false, false, false, false);
}
+ ReminderDataShareHelper::GetInstance().StartDataExtension(ReminderCalendarShareTable::START_BY_LANGUAGE_CHANGE);
ANSR_LOGI("System language config changed end.");
}
@@ -2000,5 +2067,62 @@ int32_t ReminderDataManager::QueryActiveReminderCount()
{
return store_->QueryActiveReminderCount();
}
+
+void ReminderDataManager::LoadShareReminders()
+{
+ std::map> reminders;
+ ReminderDataShareHelper::GetInstance().Query(reminders);
+ std::lock_guard locker(ReminderDataManager::MUTEX);
+ for (auto it = reminderVector_.begin(); it != reminderVector_.end();) {
+ if (!(*it)->IsShare()) {
+ ++it;
+ continue;
+ }
+ int32_t reminderId = (*it)->GetReminderId();
+ if (reminders.find(reminderId) != reminders.end()) {
+ // only exit
+ reminders.erase(reminderId);
+ ++it;
+ continue;
+ }
+ // already remove
+ if ((*it)->IsShowing()) {
+ CloseReminder(*it, true);
+ }
+ if (activeReminderId_ == reminderId) {
+ {
+ std::lock_guard locker(ReminderDataManager::ACTIVE_MUTEX);
+ activeReminder_->OnStop();
+ }
+ StopTimerLocked(TimerType::TRIGGER_TIMER);
+ }
+ it = reminderVector_.erase(it);
+ reminders.erase(reminderId);
+ }
+ // new reminder
+ for (auto& each : reminders) {
+ reminderVector_.push_back(each.second);
+ }
+}
+
+void ReminderDataManager::UpdateShareReminders(const std::map>& reminders)
+{
+ std::lock_guard locker(ReminderDataManager::MUTEX);
+ for (auto it = reminderVector_.begin(); it != reminderVector_.end(); ++it) {
+ if (!(*it)->IsShare() || (*it)->GetReminderType() != ReminderRequest::ReminderType::CALENDAR) {
+ continue;
+ }
+ int32_t reminderId = (*it)->GetReminderId();
+ auto iter = reminders.find(reminderId);
+ if (iter == reminders.end()) {
+ continue;
+ }
+ ReminderRequestCalendar* calendar = static_cast((*it).GetRefPtr());
+ calendar->Copy(iter->second);
+ if ((*it)->IsShowing()) {
+ ShowReminder((*it), false, false, false, false);
+ }
+ }
+}
}
}
diff --git a/services/reminder/src/reminder_data_manager_inner.cpp b/services/reminder/src/reminder_data_manager_inner.cpp
index 261f4d745effab466d94d8041bcfce6519925a7e..761d4b6459811a5c4597cdda25dcaea74c724955 100644
--- a/services/reminder/src/reminder_data_manager_inner.cpp
+++ b/services/reminder/src/reminder_data_manager_inner.cpp
@@ -162,5 +162,26 @@ void ReminderDataManager::ReportSysEvent(const sptr& reminder)
"RING_TIME", ringTime);
#endif
}
+
+void ReminderDataManager::OnDataShareInsert()
+{
+ LoadShareReminders();
+ std::vector> immediatelyReminders;
+ std::vector> extensionReminders;
+ CheckReminderTime(immediatelyReminders, extensionReminders);
+ HandleImmediatelyShow(immediatelyReminders, false);
+ StartRecentReminder();
+}
+
+void ReminderDataManager::OnDataShareUpdate(const std::map>& reminders)
+{
+ UpdateShareReminders(reminders);
+}
+
+void ReminderDataManager::OnDataShareDelete()
+{
+ LoadShareReminders();
+ StartRecentReminder();
+}
}
}
diff --git a/services/reminder/src/reminder_datashare_helper.cpp b/services/reminder/src/reminder_datashare_helper.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ca9435924c9d1875dab2011cfc9936355b921095
--- /dev/null
+++ b/services/reminder/src/reminder_datashare_helper.cpp
@@ -0,0 +1,414 @@
+/*
+ * Copyright (c) 2024 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 "reminder_datashare_helper.h"
+
+#include "ans_log_wrapper.h"
+#include "iservice_registry.h"
+#include "reminder_calendar_share_table.h"
+#include "system_ability_definition.h"
+#include "reminder_request_calendar.h"
+#include "reminder_data_manager.h"
+#include "ability_manager_client.h"
+#include "in_process_call_wrapper.h"
+#include "bundle_manager_helper.h"
+
+namespace OHOS::Notification {
+namespace {
+constexpr int64_t DURATION_ONE_HOUR = 60 * 60 * 1000; // 1h, millisecond
+constexpr int64_t DURATION_DELAY_TASK = 1 * 1000 * 1000; // 1s, microsecond
+constexpr int64_t CYCLE_DATASHARE_TASK = 1; // 1s
+}
+
+template
+void GetRdbValue(const std::shared_ptr& resultSet,
+ const std::string& name, T& value)
+{
+ value = T();
+ int32_t columnIndex = -1;
+ resultSet->GetColumnIndex(name, columnIndex);
+ if (columnIndex == -1) {
+ ANSR_LOGE("the column %{public}s does not exsit.", name.c_str());
+ return;
+ }
+
+ if constexpr (std::is_same_v) {
+ resultSet->GetString(columnIndex, value);
+ } else if constexpr (std::is_same_v) {
+ resultSet->GetLong(columnIndex, value);
+ } else if constexpr (std::is_same_v) {
+ int64_t t = 0;
+ resultSet->GetLong(columnIndex, t);
+ value = static_cast(t);
+ } else if constexpr (std::is_integral_v) {
+ int32_t t = 0;
+ resultSet->GetInt(columnIndex, t);
+ value = static_cast(t);
+ }
+}
+
+ReminderDataShareHelper& ReminderDataShareHelper::GetInstance()
+{
+ static ReminderDataShareHelper helper;
+ return helper;
+}
+
+bool ReminderDataShareHelper::RegisterObserver()
+{
+ std::lock_guard locker(mutex_);
+ if (observer_ != nullptr) {
+ return true;
+ }
+ auto helper = CreateDataShareHelper();
+ if (helper == nullptr) {
+ ANSR_LOGE("Create datashare helper failed.");
+ return false;
+ }
+ observer_ = std::make_shared();
+ Uri uri(ReminderCalendarShareTable::PROXY);
+ helper->RegisterObserverExt(uri, observer_, false);
+ ReleaseDataShareHelper(helper);
+ return true;
+}
+
+bool ReminderDataShareHelper::UnRegisterObserver()
+{
+ std::lock_guard locker(mutex_);
+ if (observer_ == nullptr) {
+ return true;
+ }
+ auto helper = CreateDataShareHelper();
+ if (helper == nullptr) {
+ ANSR_LOGE("Create datashare helper failed.");
+ return false;
+ }
+ Uri uri(ReminderCalendarShareTable::PROXY);
+ helper->UnregisterObserverExt(uri, observer_);
+ ReleaseDataShareHelper(helper);
+ observer_ = nullptr;
+ return true;
+}
+
+bool ReminderDataShareHelper::Query(std::map>& reminders)
+{
+ auto helper = CreateDataShareHelper();
+ if (helper == nullptr) {
+ ANSR_LOGE("Create datashare helper failed.");
+ return false;
+ }
+ int64_t timestamp = GetCurrentTime();
+ int64_t targetTimestamp = timestamp + DURATION_ONE_HOUR;
+
+ std::string proxy = ReminderCalendarShareTable::PROXY;
+ proxy.append("?user=").append(std::to_string(curUserId_));
+ Uri uri(proxy);
+ static std::vector columns = GetColumns();
+ DataShare::DataSharePredicates predicates;
+ predicates.NotEqualTo(ReminderCalendarShareTable::STATE, ReminderCalendarShareTable::STATE_DISMISSED);
+ predicates.And();
+ predicates.BeginWrap();
+ predicates.BeginWrap();
+ predicates.LessThanOrEqualTo(ReminderCalendarShareTable::ALARM_TIME, timestamp);
+ predicates.And();
+ predicates.GreaterThanOrEqualTo(ReminderCalendarShareTable::END, timestamp);
+ predicates.EndWrap();
+ predicates.Or();
+ predicates.BeginWrap();
+ predicates.GreaterThanOrEqualTo(ReminderCalendarShareTable::BEGIN, timestamp);
+ predicates.And();
+ predicates.LessThanOrEqualTo(ReminderCalendarShareTable::BEGIN, targetTimestamp);
+ predicates.EndWrap();
+ predicates.EndWrap();
+ auto resultSet = helper->Query(uri, predicates, columns);
+ if (resultSet == nullptr) {
+ ReleaseDataShareHelper(helper);
+ return false;
+ }
+
+ bool isAtLastRow = false;
+ int32_t ret = resultSet->IsAtLastRow(isAtLastRow);
+ while (ret == 0 && !isAtLastRow) {
+ resultSet->GoToNextRow();
+ sptr reminder = CreateReminder(resultSet);
+ if (reminder == nullptr) {
+ continue;
+ }
+ reminders[reminder->GetReminderId()] = reminder;
+ ret = resultSet->IsAtLastRow(isAtLastRow);
+ }
+ ReleaseDataShareHelper(helper);
+ return true;
+}
+
+bool ReminderDataShareHelper::Update(const int32_t reminderId, const int32_t state)
+{
+ auto helper = CreateDataShareHelper();
+ if (helper == nullptr) {
+ ANSR_LOGE("Create datashare helper failed.");
+ return false;
+ }
+ std::string proxy = ReminderCalendarShareTable::PROXY;
+ proxy.append("?user=").append(std::to_string(curUserId_));
+ Uri uri(proxy);
+
+ DataShare::DataSharePredicates predicates;
+ predicates.EqualTo(ReminderCalendarShareTable::ID, reminderId);
+ DataShare::DataShareValuesBucket valuesBucket;
+ valuesBucket.Put(ReminderCalendarShareTable::STATE, state);
+ helper->UpdateEx(uri, predicates, valuesBucket);
+ ReleaseDataShareHelper(helper);
+ return true;
+}
+
+void ReminderDataShareHelper::StartDataExtension(const int32_t reason)
+{
+ AAFwk::Want want;
+ want.SetElementName(ReminderCalendarShareTable::DATA_NAME, ReminderCalendarShareTable::ENTRY);
+ want.SetParam(ReminderCalendarShareTable::PARAM_CALLBACK_TYPE, reason);
+ IN_PROCESS_CALL_WITHOUT_RET(AAFwk::AbilityManagerClient::GetInstance()->StartExtensionAbility(want, nullptr));
+}
+
+void ReminderDataShareHelper::UpdateCalendarUid()
+{
+ uid_ = BundleManagerHelper::GetInstance()->GetDefaultUidByBundleName(ReminderCalendarShareTable::NAME,
+ curUserId_);
+ dataUid_ = BundleManagerHelper::GetInstance()->GetDefaultUidByBundleName(ReminderCalendarShareTable::DATA_NAME,
+ curUserId_);
+}
+
+void ReminderDataShareHelper::OnDataInsert(const DataShare::DataShareObserver::ChangeInfo&)
+{
+ auto func = []() {
+ auto manager = ReminderDataManager::GetInstance();
+ if (manager == nullptr) {
+ ANSR_LOGE("ReminderDataManager is nullptr.");
+ return;
+ }
+ manager->OnDataShareInsert();
+ };
+ int64_t timestamp =
+ std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count();
+ if (timestamp - insertTime_ > CYCLE_DATASHARE_TASK) {
+ insertTime_ = timestamp;
+ insertTask_ = false;
+ queue_->submit(func);
+ } else {
+ bool expected = false;
+ if (insertTask_.compare_exchange_strong(expected, true)) {
+ ffrt::task_attr taskAttr;
+ taskAttr.delay(DURATION_DELAY_TASK);
+ queue_->submit(func, taskAttr);
+ }
+ }
+}
+
+void ReminderDataShareHelper::OnDataUpdate(const DataShare::DataShareObserver::ChangeInfo& info)
+{
+ std::map> reminders = CreateReminder(info);
+ queue_->submit([reminders = std::move(reminders)]() {
+ auto manager = ReminderDataManager::GetInstance();
+ if (manager == nullptr) {
+ ANSR_LOGE("ReminderDataManager is nullptr.");
+ return;
+ }
+ manager->OnDataShareUpdate(reminders);
+ });
+}
+
+void ReminderDataShareHelper::OnDataDelete(const DataShare::DataShareObserver::ChangeInfo&)
+{
+ auto func = []() {
+ auto manager = ReminderDataManager::GetInstance();
+ if (manager == nullptr) {
+ ANSR_LOGE("ReminderDataManager is nullptr.");
+ return;
+ }
+ manager->OnDataShareDelete();
+ };
+ int64_t timestamp =
+ std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count();
+ if (timestamp - deleteTime_ > CYCLE_DATASHARE_TASK) {
+ deleteTime_ = timestamp;
+ deleteTask_ = false;
+ queue_->submit(func);
+ } else {
+ bool expected = false;
+ if (deleteTask_.compare_exchange_strong(expected, true)) {
+ ffrt::task_attr taskAttr;
+ taskAttr.delay(DURATION_DELAY_TASK);
+ queue_->submit(func, taskAttr);
+ }
+ }
+}
+
+std::shared_ptr ReminderDataShareHelper::CreateDataShareHelper()
+{
+ sptr manager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
+ if (manager == nullptr) {
+ ANSR_LOGE("Get sa manager failed.");
+ return nullptr;
+ }
+ sptr remoteObj = manager->GetSystemAbility(ADVANCED_NOTIFICATION_SERVICE_ABILITY_ID);
+ if (remoteObj == nullptr) {
+ ANSR_LOGE("Get system ability failed.");
+ return nullptr;
+ }
+
+ std::string proxy = ReminderCalendarShareTable::PROXY;
+ proxy.append("?user=").append(std::to_string(curUserId_));
+ std::pair> ret =
+ DataShare::DataShareHelper::Create(remoteObj, proxy, "");
+ if (ret.first == 0 && ret.second != nullptr) {
+ return ret.second;
+ } else {
+ ANSR_LOGE("Create DataShareHelper failed.");
+ return nullptr;
+ }
+}
+
+bool ReminderDataShareHelper::ReleaseDataShareHelper(const std::shared_ptr& helper)
+{
+ if (helper == nullptr) {
+ ANSR_LOGE("DataShareHelper is nullptr.");
+ return false;
+ }
+ return helper->Release();
+}
+
+std::vector ReminderDataShareHelper::GetColumns() const
+{
+ return std::vector {
+ ReminderCalendarShareTable::ID, ReminderCalendarShareTable::EVENT_ID,
+ ReminderCalendarShareTable::BEGIN, ReminderCalendarShareTable::END,
+ ReminderCalendarShareTable::ALARM_TIME, ReminderCalendarShareTable::STATE,
+ ReminderCalendarShareTable::MINUTES, ReminderCalendarShareTable::TITLE,
+ ReminderCalendarShareTable::CONTENT, ReminderCalendarShareTable::WANT_AGENT,
+ ReminderCalendarShareTable::BUTTONS, ReminderCalendarShareTable::SLOT_TYPE
+ };
+}
+
+sptr ReminderDataShareHelper::CreateReminder(
+ const std::shared_ptr& result)
+{
+ sptr reminder = sptr::MakeSptr();
+ InitBaseInfo(reminder);
+ uint64_t triggerTime = 0;
+ GetRdbValue(result, ReminderCalendarShareTable::ALARM_TIME, triggerTime);
+ reminder->SetTriggerTimeInMilli(triggerTime);
+
+ int32_t reminderId = 0;
+ GetRdbValue(result, ReminderCalendarShareTable::ID, reminderId);
+ reminder->SetReminderId(reminderId);
+ int32_t notificationId = 0;
+ GetRdbValue(result, ReminderCalendarShareTable::EVENT_ID, notificationId);
+ reminder->SetNotificationId(notificationId);
+
+ int32_t slotType = 0;
+ GetRdbValue(result, ReminderCalendarShareTable::SLOT_TYPE, slotType);
+ reminder->SetSlotType(NotificationConstant::SlotType(slotType));
+
+ std::string title;
+ GetRdbValue(result, ReminderCalendarShareTable::TITLE, title);
+ reminder->SetTitle(title);
+ std::string content;
+ GetRdbValue(result, ReminderCalendarShareTable::CONTENT, content);
+ reminder->SetContent(content);
+ std::string actionButtons;
+ GetRdbValue(result, ReminderCalendarShareTable::BUTTONS, actionButtons);
+ reminder->DeserializeButtonInfoFromJson(actionButtons);
+ std::string wantAgent;
+ GetRdbValue(result, ReminderCalendarShareTable::WANT_AGENT, wantAgent);
+ reminder->DeserializeWantAgent(wantAgent, 0);
+ uint64_t minutes = 0;
+ GetRdbValue(result, ReminderCalendarShareTable::MINUTES, minutes);
+ minutes = minutes * 60 * 1000;
+ uint64_t endDateTime = 0;
+ GetRdbValue(result, ReminderCalendarShareTable::END, endDateTime);
+ reminder->SetAutoDeletedTime(endDateTime);
+
+ ReminderRequestCalendar* calendar = static_cast(reminder.GetRefPtr());
+ uint64_t dateTime = 0;
+ GetRdbValue(result, ReminderCalendarShareTable::BEGIN, dateTime);
+ dateTime -= minutes;
+ calendar->SetDateTime(dateTime);
+ calendar->SetEndDateTime(endDateTime);
+
+ time_t now = static_cast(dateTime/1000);
+ struct tm nowTime;
+ (void)localtime_r(&now, &nowTime);
+ calendar->SetFirstDesignateYear(static_cast(ReminderRequest::GetActualTime(
+ ReminderRequest::TimeTransferType::YEAR, nowTime.tm_year)));
+ calendar->SetFirstDesignageMonth(static_cast(ReminderRequest::GetActualTime(
+ ReminderRequest::TimeTransferType::MONTH, nowTime.tm_mon)));
+ calendar->SetFirstDesignateDay(nowTime.tm_mday);
+ return reminder;
+}
+
+std::map> ReminderDataShareHelper::CreateReminder(
+ const DataShare::DataShareObserver::ChangeInfo& info)
+{
+ std::map> reminders;
+ for (auto& values : info.valueBuckets_) {
+ sptr reminder = sptr::MakeSptr();
+ InitBaseInfo(reminder);
+ auto iter = values.find(ReminderCalendarShareTable::ALARM_TIME);
+ if (iter != values.end()) {
+ reminder->SetTriggerTimeInMilli(static_cast(std::get(iter->second)));
+ }
+ }
+}
+
+void ReminderDataShareHelper::InitBaseInfo(sptr& reminder)
+{
+ reminder->SetRingDuration(0);
+ reminder->InitUserId(curUserId_);
+ reminder->InitUid(uid_);
+ reminder->InitCreatorUid(dataUid_);
+ reminder->SetShare(true);
+ reminder->InitBundleName(ReminderCalendarShareTable::NAME);
+ reminder->InitCreatorBundleName(ReminderCalendarShareTable::DATA_NAME);
+ reminder->SetSystemApp(true);
+ reminder->SetTapDismissed(true);
+}
+
+ReminderDataShareHelper::ReminderDataShareHelper()
+{
+ queue_ = std::make_shared("ReminderDataShareHelper");
+ insertTime_ =
+ std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count();
+ deleteTime_.store(insertTime_.load());
+}
+
+void ReminderDataShareHelper::ReminderDataObserver::OnChange(const ChangeInfo& info)
+{
+ switch (info.changeType_) {
+ case DataShare::DataShareObserver::ChangeType::INSERT: {
+ ReminderDataShareHelper::GetInstance().OnDataInsert(info);
+ break;
+ }
+ case DataShare::DataShareObserver::ChangeType::UPDATE: {
+ ReminderDataShareHelper::GetInstance().OnDataUpdate(info);
+ break;
+ }
+ case DataShare::DataShareObserver::ChangeType::DELETE: {
+ ReminderDataShareHelper::GetInstance().OnDataDelete(info);
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+}
+}
\ No newline at end of file
diff --git a/services/reminder/src/reminder_event_manager.cpp b/services/reminder/src/reminder_event_manager.cpp
index c26ed1d98a710616506019b71623db63ee198344..f633ab7330f0f66d679dc05dd1da43622d670dfd 100644
--- a/services/reminder/src/reminder_event_manager.cpp
+++ b/services/reminder/src/reminder_event_manager.cpp
@@ -175,7 +175,7 @@ void ReminderEventManager::ReminderEventCustomSubscriber::OnReceiveEvent(const E
return;
}
if (action == ReminderRequest::REMINDER_EVENT_LOAD_REMINDER) {
- reminderDataManager_->ReceiveLoadReminderEvent();
+ reminderDataManager_->OnLoadReminderEvent(want);
return;
}
}
diff --git a/services/reminder/src/reminder_store.cpp b/services/reminder/src/reminder_store.cpp
index 4a75c58628217e9c243ba09c76e1b19230ad0c2b..9ab8285214db09185e444f2f46d982346a593033 100644
--- a/services/reminder/src/reminder_store.cpp
+++ b/services/reminder/src/reminder_store.cpp
@@ -382,6 +382,9 @@ int32_t ReminderStore::UpdateOrInsert(
ANSR_LOGE("Rdb store is not initialized.");
return STATE_FAIL;
}
+ if (reminder != nullptr && reminder->IsShare()) {
+ return STATE_OK;
+ }
if (IsReminderExist(reminder)) {
return Update(reminder);
} else {