From a44857e8779394d226691a0065404858d979a948 Mon Sep 17 00:00:00 2001 From: gaojiaqi Date: Thu, 26 Jun 2025 14:37:46 +0800 Subject: [PATCH] add taihe Signed-off-by: gaojiaqi --- bundle.json | 3 +- frameworks/reminder_ani/BUILD.gn | 99 ++ .../ohos.reminderAgentManager.manager.taihe | 169 ++++ .../idl/ohos.reminderAgentManager.taihe | 22 + .../include/reminder_ani_common.h | 130 +++ .../reminder_ani/src/ani_constructor.cpp | 31 + .../src/ohos.reminderAgentManager.impl.cpp | 342 +++++++ .../reminder_ani/src/reminder_ani_common.cpp | 870 ++++++++++++++++++ 8 files changed, 1665 insertions(+), 1 deletion(-) create mode 100644 frameworks/reminder_ani/BUILD.gn create mode 100644 frameworks/reminder_ani/idl/ohos.reminderAgentManager.manager.taihe create mode 100644 frameworks/reminder_ani/idl/ohos.reminderAgentManager.taihe create mode 100644 frameworks/reminder_ani/include/reminder_ani_common.h create mode 100644 frameworks/reminder_ani/src/ani_constructor.cpp create mode 100644 frameworks/reminder_ani/src/ohos.reminderAgentManager.impl.cpp create mode 100644 frameworks/reminder_ani/src/reminder_ani_common.cpp diff --git a/bundle.json b/bundle.json index 4beffc327..d4726111c 100644 --- a/bundle.json +++ b/bundle.json @@ -122,7 +122,8 @@ "//base/notification/distributed_notification_service/frameworks/js/napi:napi_reminder", "//base/notification/distributed_notification_service/interfaces/ndk:ohnotification", "//base/notification/distributed_notification_service/frameworks/reminder:reminder_client", - "//base/notification/distributed_notification_service/frameworks/ets:ani_packages" + "//base/notification/distributed_notification_service/frameworks/ets:ani_packages", + "//base/notification/distributed_notification_service/frameworks/reminder_ani:reminder_agent_manager_taihe" ], "service_group": [ "//base/notification/distributed_notification_service/sa_profile:ans_sa_profile", diff --git a/frameworks/reminder_ani/BUILD.gn b/frameworks/reminder_ani/BUILD.gn new file mode 100644 index 000000000..3043269be --- /dev/null +++ b/frameworks/reminder_ani/BUILD.gn @@ -0,0 +1,99 @@ +# Copyright (c) 2025 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. + +import("//base/notification/distributed_notification_service/notification.gni") +import("//build/ohos.gni") +import("//build/ohos/taihe_idl/taihe.gni") +import("//build/config/components/ets_frontend/ets2abc_config.gni") + +taihe_generated_file_path = "${taihe_file_path}/out/${subsystem_name}/${component_name}" + +copy_taihe_idl("copy_reminder_agent_manager") { + sources = [ + "idl/ohos.reminderAgentManager.manager.taihe", + "idl/ohos.reminderAgentManager.taihe", + ] +} + +ohos_taihe("run_taihe") { + taihe_generated_file_path = "${taihe_generated_file_path}" + deps = [ ":copy_reminder_agent_manager" ] + outputs = [ + "${taihe_generated_file_path}/src/ohos.reminderAgentManager.manager.ani.cpp", + "${taihe_generated_file_path}/src/ohos.reminderAgentManager.manager.abi.c", + ] +} + +taihe_shared_library("reminder_agent_manager_ani") { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } + + taihe_generated_file_path = "${taihe_generated_file_path}" + subsystem_name = "${subsystem_name}" + part_name = "${component_name}" + + include_dirs = [ + "include", + ] + sources = get_target_outputs(":run_taihe") + sources += [ + "src/ani_constructor.cpp", + "src/ohos.reminderAgentManager.impl.cpp", + "src/reminder_ani_common.cpp", + ] + + deps = [ + ":run_taihe", + "${frameworks_module_reminder_path}:reminder_innerkits", + "${frameworks_module_ans_path}:ans_innerkits", + "${frameworks_path}/ets/ani:notification_manager_ani", + ] + + external_deps = [ + "ability_base:zuri", + "access_token:libaccesstoken_sdk", + "access_token:libtokenid_sdk", + "c_utils:utils", + "hilog:libhilog", + "ipc:ipc_single", + ] +} + +generate_static_abc("reminder_agent_manager_abc") { + base_url = "${taihe_generated_file_path}" + files = [ "${taihe_generated_file_path}/@ohos.reminderAgentManager.ets" ] + is_boot_abc = "True" + device_dst_file = "/system/framework/reminder_agent_manager_abc.abc" + dependencies = [ ":run_taihe" ] +} + +ohos_prebuilt_etc("reminder_agent_manager_etc") { + source = "${target_out_dir}/reminder_agent_manager_abc.abc" + module_install_dir = "framework" + part_name = "${component_name}" + subsystem_name = "${subsystem_name}" + deps = [ + ":reminder_agent_manager_abc", + ] +} + +group("reminder_agent_manager_taihe") { + deps = [ + ":reminder_agent_manager_ani", + ":reminder_agent_manager_etc", + ] +} \ No newline at end of file diff --git a/frameworks/reminder_ani/idl/ohos.reminderAgentManager.manager.taihe b/frameworks/reminder_ani/idl/ohos.reminderAgentManager.manager.taihe new file mode 100644 index 000000000..f88f896dc --- /dev/null +++ b/frameworks/reminder_ani/idl/ohos.reminderAgentManager.manager.taihe @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2025 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. + */ + +@!namespace("@ohos.reminderAgentManager", "reminderAgentManager") + +@!sts_inject(""" +static { loadLibrary("reminder_agent_manager_ani.z"); } +""") + +enum ReminderType: i32 { + REMINDER_TYPE_TIMER = 0, + REMINDER_TYPE_CALENDAR = 1, + REMINDER_TYPE_ALARM = 2, +} + +enum ActionButtonType: i32 { + ACTION_BUTTON_TYPE_CLOSE = 0, + ACTION_BUTTON_TYPE_SNOOZE = 1, + ACTION_BUTTON_TYPE_CUSTOM = 2, +} + +union ParamType { + string_t: String; + double_t: f64; + int_t: i32; + bool_t: bool; +} + +struct DataShareUpdate { + uri: String; + equalTo: @record Map; + value: @sts_type("ValuesBucket") Opaque; +} + +struct WantAgent { + pkgName: String; + abilityName: String; + uri: Optional; + parameters: Optional<@record Map>; +} + +struct MaxScreenWantAgent { + pkgName: String; + abilityName: String; +} + +struct ActionButton { + title: String; + titleResource: Optional; + type: ActionButtonType; + wantAgent: Optional; + dataShareUpdate: Optional; +} + +struct LocalDateTime { + year: f64; + month: f64; + day: f64; + hour: f64; + minute: f64; + second: Optional; +} + +struct ReminderRequest { + reminderType: ReminderType; + actionButton: Optional>; + wantAgent: Optional; + maxScreenWantAgent: Optional; + ringDuration: Optional; + snoozeTimes: Optional; + timeInterval: Optional; + title: Optional; + titleResourceId: Optional; + content: Optional; + contentResourceId: Optional; + expiredContent: Optional; + expiredContentResourceId: Optional; + snoozeContent: Optional; + snoozeContentResourceId: Optional; + notificationId: Optional; + groupId: Optional; + slotType: Optional<@sts_type("notification.SlotType") Opaque>; + tapDismissed: Optional; + autoDeletedTime: Optional; + snoozeSlotType: Optional<@sts_type("notification.SlotType") Opaque>; + customRingUri: Optional; +} + +struct ReminderRequestCalendar { + @extends base: ReminderRequest; + dateTime: LocalDateTime; + repeatMonths: Optional>; + repeatDays: Optional>; + daysOfWeek: Optional>; + endDateTime: Optional; + rruleWantAgent: Optional; +} + +struct ReminderRequestAlarm { + @extends base: ReminderRequest; + hour: f64; + minute: f64; + daysOfWeek: Optional>; +} + +struct ReminderRequestTimer { + @extends base: ReminderRequest; + triggerTimeInSeconds: f64; +} + +union ParamReminder { + timer: ReminderRequestTimer; + alarm: ReminderRequestAlarm; + calendar: ReminderRequestCalendar; + base: ReminderRequest; +} + +struct ReminderInfo { + reminderId: f64; + reminderReq: ParamReminder; +} + +@gen_async("publishReminder") +@gen_promise("publishReminder") +function PublishReminderSync(reminderReq: ParamReminder): f64; + +@gen_async("cancelReminder") +@gen_promise("cancelReminder") +function CancelReminderSync(reminderId: f64): void; + +@gen_async("getValidReminders") +@gen_promise("getValidReminders") +function GetValidRemindersSync(): Array; + +@gen_async("cancelAllReminders") +@gen_promise("cancelAllReminders") +function CancelAllRemindersSync(): void; + +@gen_async("addNotificationSlot") +@gen_promise("addNotificationSlot") +function AddNotificationSlotSync(slot: @sts_type("NotificationSlot") Opaque): void; + +@gen_async("removeNotificationSlot") +@gen_promise("removeNotificationSlot") +function RemoveNotificationSlotSync(slotType: @sts_type("notification.SlotType") Opaque): void; + +@gen_promise("addExcludeDate") +function AddExcludeDateSync(reminderId: f64, date: @sts_type("Date") Opaque): void; + +@gen_promise("deleteExcludeDates") +function DeleteExcludeDatesSync(reminderId: f64): void; + +@gen_promise("getExcludeDates") +function GetExcludeDatesSync(reminderId: f64): Array<@sts_type("Date") Opaque>; + +@gen_promise("getAllValidReminders") +function GetAllValidRemindersSync(): Array; \ No newline at end of file diff --git a/frameworks/reminder_ani/idl/ohos.reminderAgentManager.taihe b/frameworks/reminder_ani/idl/ohos.reminderAgentManager.taihe new file mode 100644 index 000000000..b3cbbd106 --- /dev/null +++ b/frameworks/reminder_ani/idl/ohos.reminderAgentManager.taihe @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2025 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. + */ + +@!namespace("@ohos.reminderAgentManager") + +@!sts_inject(""" +import type notification from '@ohos.notificationManager'; +import type { NotificationSlot } from 'notification.notificationSlot'; +import type { ValuesBucket } from '@ohos.data.ValuesBucket'; +""") diff --git a/frameworks/reminder_ani/include/reminder_ani_common.h b/frameworks/reminder_ani/include/reminder_ani_common.h new file mode 100644 index 000000000..f74c67ab2 --- /dev/null +++ b/frameworks/reminder_ani/include/reminder_ani_common.h @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2025 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_FRAMEWORKS_REMINDER_ANI_INCLUDE_REMINDER_ANI_COMMON_H +#define BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_FRAMEWORKS_REMINDER_ANI_INCLUDE_REMINDER_ANI_COMMON_H + +#include "ohos.reminderAgentManager.manager.proj.hpp" + +#include "reminder_request.h" + +namespace OHOS::ReminderAgentManagerNapi { +class Common { +public: + enum ErrorCode : int32_t { + ERR_REMINDER_PERMISSION_DENIED = 201, + ERR_REMINDER_INVALID_PARAM = 401, + ERR_REMINDER_NOTIFICATION_NOT_ENABLE = 1700001, + ERR_REMINDER_NUMBER_OVERLOAD, + ERR_REMINDER_NOT_EXIST, + ERR_REMINDER_PACKAGE_NOT_EXIST, + ERR_REMINDER_CALLER_TOKEN_INVALID, + ERR_REMINDER_DATA_SHARE_PERMISSION_DENIED, + }; + + enum AniSlotType { + UNKNOWN_TYPE = 0, + SOCIAL_COMMUNICATION = 1, + SERVICE_INFORMATION = 2, + CONTENT_INFORMATION = 3, + LIVE_VIEW = 4, + CUSTOMER_SERVICE = 5, + EMERGENCY_INFORMATION = 10, + OTHER_TYPES = 0xFFFF, + }; + + static std::string getErrCodeMsg(const int32_t errorCode); + + static bool CreateReminder(const ::ohos::reminderAgentManager::manager::ParamReminder& reminderReq, + std::shared_ptr& reminder); + + static ::taihe::optional<::ohos::reminderAgentManager::manager::ParamReminder> GenAniReminder( + const sptr& reminder); + + static void ConvertSlotType(AniSlotType aniSlotType, Notification::NotificationConstant::SlotType& slotType); + + static bool UnWarpSlotType(uintptr_t slotType, Notification::NotificationConstant::SlotType& outSlot); + +private: + static bool ParseIntArray(const ::taihe::array& values, std::vector& result, uint8_t maxLen); + + static bool ParseIntParam(const ::ohos::reminderAgentManager::manager::ReminderRequest& reminderReq, + std::shared_ptr& reminder); + static void ParseStringParam(const ::ohos::reminderAgentManager::manager::ReminderRequest& reminderReq, + std::shared_ptr& reminder); + + static bool ParseLocalDateTime(const ::ohos::reminderAgentManager::manager::LocalDateTime& dateTimeReq, + struct tm& dateTime); + static void ParseWantAgent(const ::ohos::reminderAgentManager::manager::WantAgent& wantAgentReq, + std::shared_ptr& wantAgent); + static void ParseMaxScreenWantAgent(const ::ohos::reminderAgentManager::manager::MaxScreenWantAgent& wantAgentReq, + std::shared_ptr& reminder); + static void ParseButtonWantAgent(const ::ohos::reminderAgentManager::manager::WantAgent& wantAgentReq, + std::shared_ptr& buttonWantAgent, + std::shared_ptr& reminder); + static void ParseDataShareUpdateEqualTo( + const ::taihe::map<::taihe::string, ::ohos::reminderAgentManager::manager::ParamType>& aniEqualTo, + std::string& equalTo); + static void ParseButtonDataShareUpdate( + const ::ohos::reminderAgentManager::manager::DataShareUpdate& aniDataShareUpdate, + std::shared_ptr& dataShareUpdate); + static bool ParseActionButton( + const ::taihe::array<::ohos::reminderAgentManager::manager::ActionButton>& actionButtons, + std::shared_ptr& reminder); + + static bool ParseCalendarParam(const ::ohos::reminderAgentManager::manager::ReminderRequestCalendar& calendarReq, + std::vector& repeatMonths, std::vector& repeatDays, std::vector& daysOfWeek); + + static bool CreateReminderBase(const ::ohos::reminderAgentManager::manager::ReminderRequest& reminderReq, + std::shared_ptr& reminder); + static bool CreateReminderTimer(const ::ohos::reminderAgentManager::manager::ReminderRequestTimer& timerReq, + std::shared_ptr& reminder); + static bool CreateReminderAlarm(const ::ohos::reminderAgentManager::manager::ReminderRequestAlarm& alarmReq, + std::shared_ptr& reminder); + static bool CreateReminderCalendar( + const ::ohos::reminderAgentManager::manager::ReminderRequestCalendar& calendarReq, + std::shared_ptr& reminder); + +private: + static void GenAniIntResult(const sptr& reminder, + ::ohos::reminderAgentManager::manager::ReminderRequest& base); + static void GenAniStringResult(const sptr& reminder, + ::ohos::reminderAgentManager::manager::ReminderRequest& base); + + static void GenAniWantParams(const std::shared_ptr& wantInfo, + ::ohos::reminderAgentManager::manager::WantAgent& aniWantAgent); + + static void GenAniWantAgent(const sptr& reminder, + ::taihe::optional<::ohos::reminderAgentManager::manager::WantAgent>& aniWantAgent); + static void GenAniMaxScreenWantAgent(const sptr& reminder, + ::taihe::optional<::ohos::reminderAgentManager::manager::MaxScreenWantAgent>& aniWantAgent); + static void GenAniActionButton(const sptr& reminder, + ::taihe::optional<::taihe::array<::ohos::reminderAgentManager::manager::ActionButton>>& aniActionButtons); + + static void GenAniReminderBase(const sptr& reminder, + ::ohos::reminderAgentManager::manager::ReminderRequest& base); + static void GenAniReminderTimer(const sptr& reminder, + ::ohos::reminderAgentManager::manager::ReminderRequestTimer& timer); + static void GenAniReminderAlarm(const sptr& reminder, + ::ohos::reminderAgentManager::manager::ReminderRequestAlarm& alarm); + static void GenAniReminderCalendar(const sptr& reminder, + ::ohos::reminderAgentManager::manager::ReminderRequestCalendar& calendar); + +private: + static bool IsSelfSystemApp(); +}; +} // namespace OHOS::ReminderAgentManagerNapi + +#endif // BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_FRAMEWORKS_REMINDER_ANI_INCLUDE_REMINDER_ANI_COMMON_H \ No newline at end of file diff --git a/frameworks/reminder_ani/src/ani_constructor.cpp b/frameworks/reminder_ani/src/ani_constructor.cpp new file mode 100644 index 000000000..d7c7f6ae9 --- /dev/null +++ b/frameworks/reminder_ani/src/ani_constructor.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2025 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 "taihe/runtime.hpp" +#include "ohos.reminderAgentManager.manager.ani.hpp" + +ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) +{ + ani_env *env; + if (ANI_OK != vm->GetEnv(ANI_VERSION_1, &env)) { + return ANI_ERROR; + } + if (ANI_OK != ohos::reminderAgentManager::manager::ANIRegister(env)) { + std::cerr << "Error from ohos::reminderAgentManager::manager::ANIRegister" << std::endl; + return ANI_ERROR; + } + *result = ANI_VERSION_1; + return ANI_OK; +} \ No newline at end of file diff --git a/frameworks/reminder_ani/src/ohos.reminderAgentManager.impl.cpp b/frameworks/reminder_ani/src/ohos.reminderAgentManager.impl.cpp new file mode 100644 index 000000000..eccc3e3de --- /dev/null +++ b/frameworks/reminder_ani/src/ohos.reminderAgentManager.impl.cpp @@ -0,0 +1,342 @@ +/* + * Copyright (c) 2025 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 "ohos.reminderAgentManager.manager.proj.hpp" +#include "ohos.reminderAgentManager.manager.impl.hpp" +#include "taihe/runtime.hpp" +#include "stdexcept" + +#include "ans_log_wrapper.h" +#include "reminder_helper.h" +#include "notification_helper.h" +#include "reminder_ani_common.h" + +using namespace OHOS; + +namespace { +static bool CheckReminderId(int32_t reminderId) +{ + if (reminderId < 0) { + ANSR_LOGW("Param reminder id is illegal."); + int32_t ret = ReminderAgentManagerNapi::Common::ERR_REMINDER_INVALID_PARAM; + ::taihe::set_business_error(ret, ReminderAgentManagerNapi::Common::getErrCodeMsg(ret)); + return false; + } + return true; +} + +static bool UnWarpDate(uintptr_t date, ani_double& outValue) +{ + ani_object value = reinterpret_cast(date); + ani_env* env = ::taihe::get_env(); + if (env == nullptr || value == nullptr) { + ANSR_LOGE("Env is nullptr."); + return false; + } + static const char* className = "Lescompat/Date;"; + ani_class cls; + if (ANI_OK != env->FindClass(className, &cls)) { + ANSR_LOGE("Failed to find class %{public}s.", className); + return false; + } + ani_method get; + if (ANI_OK != env->Class_FindMethod(cls, "valueOf", nullptr, &get)) { + ANSR_LOGE("Failed to find method valueOf."); + return false; + } + if (ANI_OK != env->Object_CallMethod_Double(value, get, &outValue)) { + ANSR_LOGE("Failed to call method valueOf."); + return false; + } + return true; +} + +static bool UnWarpNotificationSlot(uintptr_t slot, Notification::NotificationConstant::SlotType& outSlot) +{ + ani_object slotObj = reinterpret_cast(slot); + ani_env* env = ::taihe::get_env(); + if (env == nullptr || slotObj == nullptr) { + ANSR_LOGE("Env is nullptr or slot is nullptr."); + return false; + } + static const char* className = "Lnotification/notificationSlot/NotificationSlotInner;"; + ani_class cls; + if (ANI_OK != env->FindClass(className, &cls)) { + ANSR_LOGE("Failed to find class %{public}s.", className); + return false; + } + ani_ref notificationTypeRef = {}; + if (ANI_OK != env->Object_GetPropertyByName_Ref(slotObj, "notificationType", ¬ificationTypeRef)) { + ANSR_LOGE("Failed to get property notificationType."); + return false; + } + if (notificationTypeRef == nullptr) { + ANSR_LOGE("Failed to get property, notificationTypeRef is nullptr."); + return false; + } + ani_boolean isUndefined = ANI_TRUE; + ani_status status = env->Reference_IsUndefined(notificationTypeRef, &isUndefined); + if (status != ANI_OK || isUndefined == ANI_TRUE) { + ANS_LOGE("Failed to check undefined for 'notificationType', status: %{public}d", status); + return false; + } + ani_int intValue; + status = env->EnumItem_GetValue_Int(static_cast(notificationTypeRef), &intValue); + if (status != ANI_OK) { + ANS_LOGE("EnumItem_GetValue_Int failed, status: %{public}d", status); + return false; + } + outSlot = Notification::NotificationConstant::SlotType::OTHER; + ReminderAgentManagerNapi::Common::ConvertSlotType( + static_cast(intValue), outSlot); + return true; +} + +static ani_object WarpDouble(ani_env* env, double value) +{ + ani_class doubleCls; + ani_status status = ANI_ERROR; + if ((status = env->FindClass("Lstd/core/Double;", &doubleCls)) != ANI_OK) { + ANSR_LOGE("Failed to find classLstd/core/Double."); + return nullptr; + } + ani_method doubleCtor; + if ((status = env->Class_FindMethod(doubleCls, "", "D:V", &doubleCtor)) != ANI_OK) { + ANSR_LOGE("Failed to find method ."); + return nullptr; + } + ani_object doubleObj; + if ((status = env->Object_New(doubleCls, doubleCtor, &doubleObj, static_cast(value))) != ANI_OK) { + ANSR_LOGE("Failed to create double object."); + return nullptr; + } + return doubleObj; +} + +static bool WarpDate(int64_t time, ani_object &outObj) +{ + ani_env* env = ::taihe::get_env(); + if (env == nullptr || time < 0) { + ANSR_LOGE("Env is nullptr or time is invalid value."); + return false; + } + ani_class cls; + ani_status status; + if (ANI_OK != (status = env->FindClass("Lescompat/Date;", &cls))) { + ANSR_LOGE("Failed to find class Lescompat/Date."); + return false; + } + ani_method ctor; + if (ANI_OK != (status = env->Class_FindMethod(cls, "", "Lstd/core/Object;:V", &ctor))) { + ANSR_LOGE("Failed to find method . Lstd/core/Object;:V"); + return false; + } + ani_object timeObj = WarpDouble(env, static_cast(time)); + if (timeObj == nullptr) { + return false; + } + if (ANI_OK != (status = env->Object_New(cls, ctor, &outObj, timeObj))) { + ANSR_LOGE("Failed to create date object."); + return false; + } + return true; +} + +double PublishReminderSync(::ohos::reminderAgentManager::manager::ParamReminder const& reminderReq) +{ + std::shared_ptr reminder; + if (!ReminderAgentManagerNapi::Common::CreateReminder(reminderReq, reminder)) { + int32_t ret = ReminderAgentManagerNapi::Common::ERR_REMINDER_INVALID_PARAM; + ::taihe::set_business_error(ret, ReminderAgentManagerNapi::Common::getErrCodeMsg(ret)); + return -1; + } + int32_t reminderId = -1; + int32_t ret = Notification::ReminderHelper::PublishReminder(*reminder, reminderId); + if (ret != ERR_OK) { + ::taihe::set_business_error(ret, ReminderAgentManagerNapi::Common::getErrCodeMsg(ret)); + return -1; + } + return static_cast(reminderId); +} + +void CancelReminderSync(double reminderId) +{ + int32_t id = static_cast(reminderId); + if (!CheckReminderId(id)) { + return; + } + int32_t ret = Notification::ReminderHelper::CancelReminder(id); + if (ret != ERR_OK) { + ::taihe::set_business_error(ret, ReminderAgentManagerNapi::Common::getErrCodeMsg(ret)); + } +} + +::taihe::array<::ohos::reminderAgentManager::manager::ParamReminder> GetValidRemindersSync() +{ + std::vector reminders; + int32_t ret = Notification::ReminderHelper::GetValidReminders(reminders); + std::vector<::ohos::reminderAgentManager::manager::ParamReminder> aniReminders; + if (ret != ERR_OK) { + ::taihe::set_business_error(ret, ReminderAgentManagerNapi::Common::getErrCodeMsg(ret)); + return ::taihe::array<::ohos::reminderAgentManager::manager::ParamReminder>(aniReminders); + } + for (const auto& reminder : reminders) { + if (reminder.reminderRequest_ == nullptr) { + continue; + } + auto result = ReminderAgentManagerNapi::Common::GenAniReminder(reminder.reminderRequest_); + if (result.has_value()) { + aniReminders.push_back(result.value()); + } + } + return ::taihe::array<::ohos::reminderAgentManager::manager::ParamReminder>(aniReminders); +} + +void CancelAllRemindersSync() +{ + int32_t ret = Notification::ReminderHelper::CancelAllReminders(); + if (ret != ERR_OK) { + ::taihe::set_business_error(ret, ReminderAgentManagerNapi::Common::getErrCodeMsg(ret)); + } +} + +void AddNotificationSlotSync(uintptr_t slot) +{ + Notification::NotificationConstant::SlotType notificationSlot; + int32_t ret = ReminderAgentManagerNapi::Common::ERR_REMINDER_INVALID_PARAM; + if (!UnWarpNotificationSlot(slot, notificationSlot)) { + ::taihe::set_business_error(ret, ReminderAgentManagerNapi::Common::getErrCodeMsg(ret)); + return; + } + ret = Notification::NotificationHelper::AddSlotByType(notificationSlot); + if (ret != ERR_OK) { + ::taihe::set_business_error(ret, ReminderAgentManagerNapi::Common::getErrCodeMsg(ret)); + } +} + +void RemoveNotificationSlotSync(uintptr_t slotType) +{ + int32_t ret = ReminderAgentManagerNapi::Common::ERR_REMINDER_INVALID_PARAM; + Notification::NotificationConstant::SlotType slot; + if (!ReminderAgentManagerNapi::Common::UnWarpSlotType(slotType, slot)) { + ::taihe::set_business_error(ret, ReminderAgentManagerNapi::Common::getErrCodeMsg(ret)); + return; + } + ret = Notification::ReminderHelper::RemoveNotificationSlot(slot); + if (ret != ERR_OK) { + ::taihe::set_business_error(ret, ReminderAgentManagerNapi::Common::getErrCodeMsg(ret)); + } +} + +void AddExcludeDateSync(double reminderId, uintptr_t date) +{ + int32_t id = static_cast(reminderId); + if (!CheckReminderId(id)) { + return; + } + ani_double dateValue; + int32_t ret = ERR_OK; + if (!UnWarpDate(date, dateValue)) { + ret = ReminderAgentManagerNapi::Common::ERR_REMINDER_INVALID_PARAM; + ::taihe::set_business_error(ret, ReminderAgentManagerNapi::Common::getErrCodeMsg(ret)); + return; + } + if (dateValue <= 0) { + ANSR_LOGW("Param exclude date is illegal."); + ret = ReminderAgentManagerNapi::Common::ERR_REMINDER_INVALID_PARAM; + ::taihe::set_business_error(ret, ReminderAgentManagerNapi::Common::getErrCodeMsg(ret)); + return; + } + ret = Notification::ReminderHelper::AddExcludeDate(id, static_cast(dateValue)); + if (ret != ERR_OK) { + ::taihe::set_business_error(ret, ReminderAgentManagerNapi::Common::getErrCodeMsg(ret)); + } +} + +void DeleteExcludeDatesSync(double reminderId) +{ + int32_t id = static_cast(reminderId); + if (!CheckReminderId(id)) { + return; + } + int32_t ret = Notification::ReminderHelper::DelExcludeDates(id); + if (ret != ERR_OK) { + ::taihe::set_business_error(ret, ReminderAgentManagerNapi::Common::getErrCodeMsg(ret)); + } +} + +::taihe::array GetExcludeDatesSync(double reminderId) +{ + int32_t id = static_cast(reminderId); + std::vector results; + if (!CheckReminderId(id)) { + return ::taihe::array(results); + } + std::vector dates; + int32_t ret = Notification::ReminderHelper::GetExcludeDates(id, dates); + if (ret != ERR_OK) { + ::taihe::set_business_error(ret, ReminderAgentManagerNapi::Common::getErrCodeMsg(ret)); + return ::taihe::array(results); + } + for (const auto date : dates) { + ani_object dateObj; + if (!WarpDate(date, dateObj)) { + continue; + } + results.push_back(reinterpret_cast(dateObj)); + } + return ::taihe::array(results); +} + +::taihe::array<::ohos::reminderAgentManager::manager::ReminderInfo> GetAllValidRemindersSync() +{ + std::vector reminders; + int32_t ret = Notification::ReminderHelper::GetValidReminders(reminders); + std::vector<::ohos::reminderAgentManager::manager::ReminderInfo> aniReminders; + if (ret != ERR_OK) { + ::taihe::set_business_error(ret, ReminderAgentManagerNapi::Common::getErrCodeMsg(ret)); + return ::taihe::array<::ohos::reminderAgentManager::manager::ReminderInfo>(aniReminders); + } + for (const auto& reminder : reminders) { + if (reminder.reminderRequest_ == nullptr) { + continue; + } + auto result = ReminderAgentManagerNapi::Common::GenAniReminder(reminder.reminderRequest_); + if (!result.has_value()) { + continue; + } + ::ohos::reminderAgentManager::manager::ReminderInfo reminderInfo { + .reminderId = static_cast(reminder.reminderRequest_->GetReminderId()), + .reminderReq = result.value() + }; + aniReminders.push_back(reminderInfo); + } + return ::taihe::array<::ohos::reminderAgentManager::manager::ReminderInfo>(aniReminders); +} +} // namespace + +// Since these macros are auto-generate, lint will cause false positive. +// NOLINTBEGIN +TH_EXPORT_CPP_API_PublishReminderSync(PublishReminderSync); +TH_EXPORT_CPP_API_CancelReminderSync(CancelReminderSync); +TH_EXPORT_CPP_API_GetValidRemindersSync(GetValidRemindersSync); +TH_EXPORT_CPP_API_CancelAllRemindersSync(CancelAllRemindersSync); +TH_EXPORT_CPP_API_AddNotificationSlotSync(AddNotificationSlotSync); +TH_EXPORT_CPP_API_RemoveNotificationSlotSync(RemoveNotificationSlotSync); +TH_EXPORT_CPP_API_AddExcludeDateSync(AddExcludeDateSync); +TH_EXPORT_CPP_API_DeleteExcludeDatesSync(DeleteExcludeDatesSync); +TH_EXPORT_CPP_API_GetExcludeDatesSync(GetExcludeDatesSync); +TH_EXPORT_CPP_API_GetAllValidRemindersSync(GetAllValidRemindersSync); +// NOLINTEND \ No newline at end of file diff --git a/frameworks/reminder_ani/src/reminder_ani_common.cpp b/frameworks/reminder_ani/src/reminder_ani_common.cpp new file mode 100644 index 000000000..2a2da97a6 --- /dev/null +++ b/frameworks/reminder_ani/src/reminder_ani_common.cpp @@ -0,0 +1,870 @@ +/* + * Copyright (c) 2025 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_ani_common.h" + +#include "reminder_request_alarm.h" +#include "reminder_request_timer.h" +#include "reminder_request_calendar.h" + +#include "securec.h" +#include "int_wrapper.h" +#include "tokenid_kit.h" +#include "bool_wrapper.h" +#include "ipc_skeleton.h" +#include "double_wrapper.h" +#include "string_wrapper.h" +#include "taihe/runtime.hpp" + +using namespace ohos; + +namespace OHOS::ReminderAgentManagerNapi { +static constexpr int32_t MAX_HOUR = 23; +static constexpr int32_t MAX_MINUTE = 59; +static constexpr uint8_t MAX_DAYS_OF_WEEK = 7; + +// need to be same as WantParams +enum { + VALUE_TYPE_NULL = -1, + VALUE_TYPE_BOOLEAN = 1, + VALUE_TYPE_INT = 5, + VALUE_TYPE_DOUBLE = 8, + VALUE_TYPE_STRING = 9, +}; + +template +static std::vector ConvertInt(const std::vector& values) +{ + std::vector results; + results.reserve(values.size()); + for (const auto value : values) { + results.push_back(static_cast(value)); + } + return results; +} + +static bool IsValidateString(const std::string& str) +{ + if (str.find(Notification::ReminderRequest::SEP_BUTTON_VALUE_TYPE) != std::string::npos) { + ANSR_LOGW("The string contains SEP_BUTTON_VALUE_TYPE"); + return false; + } + if (str.find(Notification::ReminderRequest::SEP_BUTTON_VALUE) != std::string::npos) { + ANSR_LOGW("The string contains SEP_BUTTON_VALUE"); + return false; + } + if (str.find(Notification::ReminderRequest::SEP_BUTTON_VALUE_BLOB) != std::string::npos) { + ANSR_LOGW("The string contains SEP_BUTTON_VALUE_BLOB"); + return false; + } + return true; +} + +std::string Common::getErrCodeMsg(const int32_t errorCode) +{ + switch (errorCode) { + case ERR_REMINDER_PERMISSION_DENIED: + return "Permission denied."; + case ERR_REMINDER_INVALID_PARAM: + return "Parameter error."; + case ERR_REMINDER_NOTIFICATION_NOT_ENABLE: + return "Notification not enable."; + case ERR_REMINDER_NUMBER_OVERLOAD: + return "The number of reminders exceeds the limit."; + case ERR_REMINDER_NOT_EXIST: + return "The reminder not exist."; + case ERR_REMINDER_PACKAGE_NOT_EXIST: + return "The package name not exist."; + case ERR_REMINDER_CALLER_TOKEN_INVALID: + return "The caller token invalid."; + case ERR_REMINDER_DATA_SHARE_PERMISSION_DENIED: + return "The data share permission denied."; + default: + return "Inner error"; + } +} + +bool Common::CreateReminder(const reminderAgentManager::manager::ParamReminder& reminderReq, + std::shared_ptr& reminder) +{ + switch (reminderReq.get_tag()) { + case reminderAgentManager::manager::ParamReminder::tag_t::timer: { + auto& timer = reminderReq.get_timer_ref(); + return CreateReminderTimer(timer, reminder); + } + case reminderAgentManager::manager::ParamReminder::tag_t::alarm: { + auto& alarm = reminderReq.get_alarm_ref(); + return CreateReminderAlarm(alarm, reminder); + } + case reminderAgentManager::manager::ParamReminder::tag_t::calendar: { + auto& calendar = reminderReq.get_calendar_ref(); + return CreateReminderCalendar(calendar, reminder); + } + default: + ANSR_LOGE("Invalid reminder type."); + return false; + } +} + +::taihe::optional Common::GenAniReminder( + const sptr& reminder) +{ + switch (reminder->GetReminderType()) { + case Notification::ReminderRequest::ReminderType::TIMER: { + reminderAgentManager::manager::ReminderRequestTimer timer { + .base = { + reminderAgentManager::manager::ReminderType::key_t::REMINDER_TYPE_TIMER + } + }; + GenAniReminderTimer(reminder, timer); + return ::taihe::optional::make( + reminderAgentManager::manager::ParamReminder::make< + reminderAgentManager::manager::ParamReminder::tag_t::timer>(timer)); + } + case Notification::ReminderRequest::ReminderType::ALARM: { + reminderAgentManager::manager::ReminderRequestAlarm alarm { + .base = { + reminderAgentManager::manager::ReminderType::key_t::REMINDER_TYPE_ALARM + } + }; + GenAniReminderAlarm(reminder, alarm); + return ::taihe::optional::make( + reminderAgentManager::manager::ParamReminder::make< + reminderAgentManager::manager::ParamReminder::tag_t::alarm>(alarm)); + } + case Notification::ReminderRequest::ReminderType::CALENDAR: { + reminderAgentManager::manager::ReminderRequestCalendar calendar { + .base = { + reminderAgentManager::manager::ReminderType::key_t::REMINDER_TYPE_CALENDAR + } + }; + GenAniReminderCalendar(reminder, calendar); + return ::taihe::optional::make( + reminderAgentManager::manager::ParamReminder::make< + reminderAgentManager::manager::ParamReminder::tag_t::calendar>(calendar)); + } + case Notification::ReminderRequest::ReminderType::INVALID: + default: { + ANSR_LOGE("Invalid reminder type."); + return ::taihe::optional(); + } + } +} + +void Common::ConvertSlotType(AniSlotType aniSlotType, Notification::NotificationConstant::SlotType& slotType) +{ + switch (aniSlotType) { + case AniSlotType::SOCIAL_COMMUNICATION: + slotType = Notification::NotificationConstant::SlotType::SOCIAL_COMMUNICATION; + break; + case AniSlotType::SERVICE_INFORMATION: + slotType = Notification::NotificationConstant::SlotType::SERVICE_REMINDER; + break; + case AniSlotType::CONTENT_INFORMATION: + slotType = Notification::NotificationConstant::SlotType::CONTENT_INFORMATION; + break; + case AniSlotType::LIVE_VIEW: + slotType = Notification::NotificationConstant::SlotType::LIVE_VIEW; + break; + case AniSlotType::CUSTOMER_SERVICE: + slotType = Notification::NotificationConstant::SlotType::CUSTOMER_SERVICE; + break; + case AniSlotType::EMERGENCY_INFORMATION: + slotType = Notification::NotificationConstant::SlotType::EMERGENCY_INFORMATION; + break; + case AniSlotType::UNKNOWN_TYPE: + case AniSlotType::OTHER_TYPES: + default: + slotType = Notification::NotificationConstant::SlotType::OTHER; + break; + } +} + +bool Common::UnWarpSlotType(uintptr_t slotType, Notification::NotificationConstant::SlotType& outSlot) +{ + ani_enum_item value = reinterpret_cast(slotType); + ani_env* env = ::taihe::get_env(); + if (env == nullptr || value == nullptr) { + ANSR_LOGE("Invalid env or slotType."); + return false; + } + ani_int intValue; + if (ANI_OK != env->EnumItem_GetValue_Int(value, &intValue)) { + ANSR_LOGE("EnumItem_GetValue_Int failed."); + return false; + } + ConvertSlotType(static_cast(intValue), outSlot); + return true; +} + +bool Common::ParseIntArray(const ::taihe::array& values, std::vector& result, uint8_t maxLen) +{ + size_t size = values.size(); + if (size > maxLen) { + ANSR_LOGE("The max length of array is %{pulbic}hhu", maxLen); + return false; + } + for (size_t i = 0; i < size; ++i) { + int32_t value = static_cast(values[i]); + if (value < 1 || value > static_cast(maxLen)) { + ANSR_LOGE("The array element must between [1, %{public}d].", maxLen); + return false; + } + result.push_back(static_cast(value)); + } + return true; +} + +bool Common::ParseIntParam(const reminderAgentManager::manager::ReminderRequest& reminderReq, + std::shared_ptr& reminder) +{ + if (reminderReq.ringDuration.has_value()) { + int64_t ringDuration = static_cast(reminderReq.ringDuration.value()); + if (ringDuration < 0 || ringDuration > static_cast( + Notification::ReminderRequest::MAX_RING_DURATION / Notification::ReminderRequest::MILLI_SECONDS)) { + ANSR_LOGE("Param[ringDuration] out of range."); + return false; + } + reminder->SetRingDuration(static_cast(ringDuration)); + } + if (reminderReq.snoozeTimes.has_value()) { + int32_t snoozeTimes = static_cast(reminderReq.snoozeTimes.value()); + if (snoozeTimes < 0) { + reminder->SetSnoozeTimes(0); + } else { + reminder->SetSnoozeTimes(snoozeTimes > UINT8_MAX ? UINT8_MAX : static_cast(snoozeTimes)); + } + } + if (reminderReq.timeInterval.has_value()) { + reminder->SetTimeInterval(static_cast(reminderReq.timeInterval.value())); + } + if (reminderReq.titleResourceId.has_value()) { + reminder->SetTitleResourceId(static_cast(reminderReq.titleResourceId.value())); + } + if (reminderReq.contentResourceId.has_value()) { + reminder->SetContentResourceId(static_cast(reminderReq.contentResourceId.value())); + } + if (reminderReq.expiredContentResourceId.has_value()) { + reminder->SetExpiredContentResourceId(static_cast(reminderReq.expiredContentResourceId.value())); + } + if (reminderReq.snoozeContentResourceId.has_value()) { + reminder->SetSnoozeContentResourceId(static_cast(reminderReq.snoozeContentResourceId.value())); + } + if (reminderReq.notificationId.has_value()) { + reminder->SetNotificationId(static_cast(reminderReq.notificationId.value())); + } + if (reminderReq.autoDeletedTime.has_value()) { + int64_t autoDeletedTime = static_cast(reminderReq.autoDeletedTime.value()); + reminder->SetAutoDeletedTime(autoDeletedTime > 0 ? autoDeletedTime : 0); + } + return true; +} + +void Common::ParseStringParam(const reminderAgentManager::manager::ReminderRequest& reminderReq, + std::shared_ptr& reminder) +{ + if (reminderReq.title.has_value()) { + reminder->SetTitle(reminderReq.title.value().c_str()); + } + if (reminderReq.content.has_value()) { + reminder->SetContent(reminderReq.content.value().c_str()); + } + if (reminderReq.expiredContent.has_value()) { + reminder->SetExpiredContent(reminderReq.expiredContent.value().c_str()); + } + if (reminderReq.snoozeContent.has_value()) { + reminder->SetSnoozeContent(reminderReq.snoozeContent.value().c_str()); + } + if (reminderReq.groupId.has_value()) { + reminder->SetGroupId(reminderReq.groupId.value().c_str()); + } + if (reminderReq.customRingUri.has_value()) { + reminder->SetCustomRingUri(reminderReq.customRingUri.value().c_str()); + } +} + +bool Common::ParseLocalDateTime(const reminderAgentManager::manager::LocalDateTime& dateTimeReq, + struct tm& dateTime) +{ + int32_t year = static_cast(dateTimeReq.year); + if (year < 0 || year > UINT16_MAX) { + ANSR_LOGE("Param[year] out of range[0, %{public}d]", UINT16_MAX); + return false; + } + dateTime.tm_year = Notification::ReminderRequest::GetCTime( + Notification::ReminderRequest::TimeTransferType::YEAR, year); + + int32_t month = static_cast(dateTimeReq.month); + if (month < 1 || month > Notification::ReminderRequestCalendar::MAX_MONTHS_OF_YEAR) { + ANSR_LOGE("Param[month] out of range[1, %{public}hhu]", + Notification::ReminderRequestCalendar::MAX_MONTHS_OF_YEAR); + return false; + } + dateTime.tm_mon = Notification::ReminderRequest::GetCTime( + Notification::ReminderRequest::TimeTransferType::MONTH, month); + + uint8_t maxDaysOfMonth = Notification::ReminderRequestCalendar::GetDaysOfMonth( + static_cast(year), static_cast(month)); + int32_t day = static_cast(dateTimeReq.day); + if ((day < 1) || (day > maxDaysOfMonth)) { + ANSR_LOGW("Param[day] out of range[1, %{public}hhu]", maxDaysOfMonth); + return false; + } + dateTime.tm_mday = day; + + int32_t hour = static_cast(dateTimeReq.hour); + if (hour < 0 || hour > MAX_HOUR) { + ANSR_LOGW("Param[hour] out of range[0, %{public}d]", MAX_HOUR); + return false; + } + dateTime.tm_hour = hour; + + int32_t minute = static_cast(dateTimeReq.minute); + if (minute < 0 || minute > MAX_MINUTE) { + ANSR_LOGW("Param[minute] out of range[0, %{public}d]", MAX_MINUTE); + return false; + } + dateTime.tm_min = minute; + + if (dateTimeReq.second.has_value()) { + dateTime.tm_sec = static_cast(dateTimeReq.second.value()); + } else { + dateTime.tm_sec = 0; + } + dateTime.tm_isdst = -1; + return true; +} + +void Common::ParseWantAgent(const reminderAgentManager::manager::WantAgent& wantAgentReq, + std::shared_ptr& wantAgent) +{ + wantAgent = std::make_shared(); + wantAgent->pkgName = std::string(wantAgentReq.pkgName.c_str()); + wantAgent->abilityName = std::string(wantAgentReq.abilityName.c_str()); + if (wantAgentReq.uri.has_value()) { + wantAgent->uri = std::string(wantAgentReq.uri.value().c_str()); + } + if (!wantAgentReq.parameters.has_value()) { + return; + } + + for (const auto& [key, value] : wantAgentReq.parameters.value()) { + switch (value.get_tag()) { + case reminderAgentManager::manager::ParamType::tag_t::string_t: { + wantAgent->parameters.SetParam(std::string(key.c_str()), + AAFwk::String::Box(std::string(value.get_string_t_ref().c_str()))); + break; + } + case reminderAgentManager::manager::ParamType::tag_t::double_t: { + wantAgent->parameters.SetParam(std::string(key.c_str()), + AAFwk::Double::Box(value.get_double_t_ref())); + break; + } + case reminderAgentManager::manager::ParamType::tag_t::int_t: { + wantAgent->parameters.SetParam(std::string(key.c_str()), + AAFwk::Integer::Box(value.get_int_t_ref())); + break; + } + case reminderAgentManager::manager::ParamType::tag_t::bool_t: { + wantAgent->parameters.SetParam(std::string(key.c_str()), + AAFwk::Boolean::Box(value.get_bool_t_ref())); + break; + } + default: + break; + } + } +} + +void Common::ParseMaxScreenWantAgent(const reminderAgentManager::manager::MaxScreenWantAgent& wantAgentReq, + std::shared_ptr& reminder) +{ + auto wantAgent = std::shared_ptr(); + reminder->SetMaxScreenWantAgentInfo(wantAgent); + wantAgent->pkgName = std::string(wantAgentReq.pkgName.c_str()); + wantAgent->abilityName = std::string(wantAgentReq.abilityName.c_str()); +} + +void Common::ParseButtonWantAgent(const reminderAgentManager::manager::WantAgent& wantAgentReq, + std::shared_ptr& buttonWantAgent, + std::shared_ptr& reminder) +{ + buttonWantAgent->pkgName = std::string(wantAgentReq.pkgName.c_str()); + buttonWantAgent->abilityName = std::string(wantAgentReq.abilityName.c_str()); + if (wantAgentReq.uri.has_value()) { + reminder->SetCustomButtonUri(wantAgentReq.uri.value().c_str()); + } +} + +void Common::ParseDataShareUpdateEqualTo( + const ::taihe::map<::taihe::string, reminderAgentManager::manager::ParamType>& aniEqualTo, + std::string& equalTo) +{ + size_t arrlen = aniEqualTo.size(); + size_t i = 0; + for (const auto& [key, value] : aniEqualTo) { + ++i; + std::string type; + std::string result; + switch (value.get_tag()) { + case reminderAgentManager::manager::ParamType::tag_t::string_t: { + type = "string"; + result = std::string(value.get_string_t_ref().c_str()); + break; + } + case reminderAgentManager::manager::ParamType::tag_t::double_t: { + type = "double"; + result = std::to_string(value.get_double_t_ref()); + break; + } + case reminderAgentManager::manager::ParamType::tag_t::int_t: { + type = "int"; + result = std::to_string(value.get_int_t_ref()); + break; + } + case reminderAgentManager::manager::ParamType::tag_t::bool_t: { + type = "bool"; + result = std::to_string(value.get_bool_t_ref()); + break; + } + default: + break; + } + if (type.empty()) { + continue; + } + if (!IsValidateString(std::string(key.c_str())) || !IsValidateString(result)) { + continue; + } + equalTo += key + Notification::ReminderRequest::SEP_BUTTON_VALUE + type + + Notification::ReminderRequest::SEP_BUTTON_VALUE + result; + if (i < arrlen) { + equalTo += Notification::ReminderRequest::SEP_BUTTON_VALUE_TYPE; + } + } +} + +void Common::ParseButtonDataShareUpdate( + const reminderAgentManager::manager::DataShareUpdate& aniDataShareUpdate, + std::shared_ptr& dataShareUpdate) +{ + dataShareUpdate->uri = std::string(aniDataShareUpdate.uri.c_str()); + ParseDataShareUpdateEqualTo(aniDataShareUpdate.equalTo, dataShareUpdate->equalTo); +} + +bool Common::ParseActionButton( + const ::taihe::array<::ohos::reminderAgentManager::manager::ActionButton>& actionButtons, + std::shared_ptr& reminder) +{ + for (const auto& actionButton : actionButtons) { + auto buttonType = Notification::ReminderRequest::ActionButtonType::INVALID; + auto buttonWantAgent = std::make_shared(); + switch (actionButton.type.get_key()) { + case reminderAgentManager::manager::ActionButtonType::key_t::ACTION_BUTTON_TYPE_CLOSE: + buttonType = Notification::ReminderRequest::ActionButtonType::CLOSE; + break; + case reminderAgentManager::manager::ActionButtonType::key_t::ACTION_BUTTON_TYPE_SNOOZE: + buttonType = Notification::ReminderRequest::ActionButtonType::SNOOZE; + break; + case reminderAgentManager::manager::ActionButtonType::key_t::ACTION_BUTTON_TYPE_CUSTOM: { + if (!IsSelfSystemApp()) { + ANSR_LOGW("Not system app, ACTION_BUTTON_TYPE_CUSTOM not supported."); + return false; + } + buttonType = Notification::ReminderRequest::ActionButtonType::CUSTOM; + if (actionButton.wantAgent.has_value()) { + ParseButtonWantAgent(actionButton.wantAgent.value(), buttonWantAgent, reminder); + } + break; + } + default: + continue; + } + std::string title = std::string(actionButton.title.c_str()); + std::string resource = ""; + if (actionButton.titleResource.has_value()) { + resource = std::string(actionButton.titleResource.value().c_str()); + } + auto buttonDataShareUpdate = std::make_shared(); + if (actionButton.dataShareUpdate.has_value()) { + ParseButtonDataShareUpdate(actionButton.dataShareUpdate.value(), buttonDataShareUpdate); + } + reminder->SetActionButton(title, buttonType, resource, buttonWantAgent, buttonDataShareUpdate); + } + return true; +} + +bool Common::ParseCalendarParam(const ::ohos::reminderAgentManager::manager::ReminderRequestCalendar& calendarReq, + std::vector& repeatMonths, std::vector& repeatDays, std::vector& daysOfWeek) +{ + if (calendarReq.repeatMonths.has_value() && !ParseIntArray(calendarReq.repeatMonths.value(), + repeatMonths, Notification::ReminderRequestCalendar::MAX_MONTHS_OF_YEAR)) { + return false; + } + if (calendarReq.repeatDays.has_value() && !ParseIntArray(calendarReq.repeatDays.value(), + repeatDays, Notification::ReminderRequestCalendar::MAX_DAYS_OF_MONTH)) { + return false; + } + if (calendarReq.daysOfWeek.has_value() && !ParseIntArray(calendarReq.daysOfWeek.value(), + daysOfWeek, MAX_DAYS_OF_WEEK)) { + return false; + } + return true; +} + +bool Common::CreateReminderBase(const reminderAgentManager::manager::ReminderRequest& reminderReq, + std::shared_ptr& reminder) +{ + if (!ParseIntParam(reminderReq, reminder)) { + return false; + } + ParseStringParam(reminderReq, reminder); + if (reminderReq.tapDismissed.has_value()) { + reminder->SetTapDismissed(reminderReq.tapDismissed.value()); + } + if (reminderReq.wantAgent.has_value()) { + std::shared_ptr wantAgent; + ParseWantAgent(reminderReq.wantAgent.value(), wantAgent); + reminder->SetWantAgentInfo(wantAgent); + } + if (reminderReq.maxScreenWantAgent.has_value()) { + ParseMaxScreenWantAgent(reminderReq.maxScreenWantAgent.value(), reminder); + } + if (reminderReq.actionButton.has_value()) { + if (!ParseActionButton(reminderReq.actionButton.value(), reminder)) { + return false; + } + } + if (reminderReq.slotType.has_value()) { + Notification::NotificationConstant::SlotType slotType; + if (!UnWarpSlotType(reminderReq.slotType.value(), slotType)) { + return false; + } + reminder->SetSlotType(slotType); + } + if (reminderReq.snoozeSlotType.has_value()) { + Notification::NotificationConstant::SlotType slotType; + if (!UnWarpSlotType(reminderReq.snoozeSlotType.value(), slotType)) { + return false; + } + reminder->SetSnoozeSlotType(slotType); + } + return true; +} + +bool Common::CreateReminderTimer(const reminderAgentManager::manager::ReminderRequestTimer& timerReq, + std::shared_ptr& reminder) +{ + uint64_t triggerTimeInSeconds = static_cast(timerReq.triggerTimeInSeconds); + if (triggerTimeInSeconds >= (UINT64_MAX / Notification::ReminderRequest::MILLI_SECONDS)) { + ANSR_LOGE("Param[triggerTimeInSeconds] out of range."); + return false; + } + auto timer = std::make_shared(triggerTimeInSeconds); + reminder = timer; + if (!CreateReminderBase(timerReq.base, reminder)) { + reminder = nullptr; + return false; + } + return true; +} + +bool Common::CreateReminderAlarm(const reminderAgentManager::manager::ReminderRequestAlarm& alarmReq, + std::shared_ptr& reminder) +{ + int32_t hour = static_cast(alarmReq.hour); + int32_t minute = static_cast(alarmReq.minute); + if (hour < 0 || hour > MAX_HOUR) { + ANSR_LOGE("Param[hour] out of range[0, 23]."); + return false; + } + if (minute < 0 || minute > MAX_MINUTE) { + ANSR_LOGE("Param[minute] out of range[0, 59]."); + return false; + } + std::vector daysOfWeek; + if (alarmReq.daysOfWeek.has_value() && + !ParseIntArray(alarmReq.daysOfWeek.value(), daysOfWeek, MAX_DAYS_OF_WEEK)) { + return false; + } + auto alarm = std::make_shared(static_cast(hour), + static_cast(minute), daysOfWeek); + reminder = alarm; + if (!CreateReminderBase(alarmReq.base, reminder)) { + reminder = nullptr; + return false; + } + return true; +} + +bool Common::CreateReminderCalendar(const reminderAgentManager::manager::ReminderRequestCalendar& calendarReq, + std::shared_ptr& reminder) +{ + struct tm dateTime; + if (!ParseLocalDateTime(calendarReq.dateTime, dateTime)) { + return false; + } + std::vector repeatMonths; + std::vector repeatDays; + std::vector daysOfWeek; + if (!ParseCalendarParam(calendarReq, repeatMonths, repeatDays, daysOfWeek)) { + return false; + } + + std::shared_ptr rruleWantAgent; + if (calendarReq.rruleWantAgent.has_value()) { + ParseWantAgent(calendarReq.rruleWantAgent.value(), rruleWantAgent); + } + if (!IsSelfSystemApp() && rruleWantAgent != nullptr) { + ANS_LOGE("Not system app, rruleWantAgent not supported."); + return false; + } + auto calendar = + std::make_shared(dateTime, repeatMonths, repeatDays, daysOfWeek); + if (calendarReq.endDateTime.has_value()) { + struct tm endDateTime; + if (!ParseLocalDateTime(calendarReq.endDateTime.value(), endDateTime)) { + return false; + } + time_t endTime = mktime(&endDateTime); + if (endTime == -1) { + ANS_LOGE("Param[endDateTime] not a valid value."); + return false; + } + if (!calendar->SetEndDateTime(Notification::ReminderRequest::GetDurationSinceEpochInMilli(endTime))) { + ANSR_LOGW("The endDateTime must be greater than dateTime"); + return false; + } + } + if (!calendar->InitTriggerTime()) { + return false; + } + calendar->SetRRuleWantAgentInfo(rruleWantAgent); + reminder = calendar; + if (!CreateReminderBase(calendarReq.base, reminder)) { + reminder = nullptr; + return false; + } + return true; +} + +void Common::GenAniIntResult(const sptr& reminder, + reminderAgentManager::manager::ReminderRequest& base) +{ + base.ringDuration = ::taihe::optional::make(static_cast(reminder->GetRingDuration())); + base.snoozeTimes = ::taihe::optional::make(static_cast(reminder->GetSnoozeTimes())); + base.timeInterval = ::taihe::optional::make(static_cast(reminder->GetTimeInterval())); + base.titleResourceId = ::taihe::optional::make(static_cast(reminder->GetTitleResourceId())); + base.contentResourceId = ::taihe::optional::make(static_cast(reminder->GetContentResourceId())); + base.expiredContentResourceId = ::taihe::optional::make( + static_cast(reminder->GetExpiredContentResourceId())); + base.snoozeContentResourceId = ::taihe::optional::make( + static_cast(reminder->GetSnoozeContentResourceId())); + base.notificationId = ::taihe::optional::make(static_cast(reminder->GetNotificationId())); + base.autoDeletedTime = ::taihe::optional::make(static_cast(reminder->GetAutoDeletedTime())); +} + +void Common::GenAniStringResult(const sptr& reminder, + reminderAgentManager::manager::ReminderRequest& base) +{ + base.title = ::taihe::optional<::taihe::string>::make(::taihe::string(reminder->GetTitle())); + base.content = ::taihe::optional<::taihe::string>::make(::taihe::string(reminder->GetContent())); + base.expiredContent = ::taihe::optional<::taihe::string>::make(::taihe::string(reminder->GetExpiredContent())); + base.snoozeContent = ::taihe::optional<::taihe::string>::make(::taihe::string(reminder->GetSnoozeContent())); + base.groupId = ::taihe::optional<::taihe::string>::make(::taihe::string(reminder->GetGroupId())); + base.customRingUri = ::taihe::optional<::taihe::string>::make(::taihe::string(reminder->GetCustomRingUri())); +} + +void Common::GenAniWantParams(const std::shared_ptr& wantInfo, + reminderAgentManager::manager::WantAgent& aniWantAgent) +{ + auto params = wantInfo->parameters.GetParams(); + if (params.size() == 0) { + return; + } + ::taihe::map<::taihe::string, reminderAgentManager::manager::ParamType> aniParams; + for (const auto& iter : params) { + int32_t typeId = AAFwk::WantParams::GetDataType(iter.second); + switch (typeId) { + case VALUE_TYPE_INT: { + AAFwk::IInteger* intPtr = AAFwk::IInteger::Query(iter.second); + if (intPtr != nullptr) { + int32_t intVal = AAFwk::Integer::Unbox(intPtr); + aniParams.emplace(iter.first, reminderAgentManager::manager::ParamType::make_int_t(intVal)); + } + break; + } + case VALUE_TYPE_DOUBLE: { + AAFwk::IDouble* doublePtr = AAFwk::IDouble::Query(iter.second); + if (doublePtr != nullptr) { + double doubleVal = AAFwk::Double::Unbox(doublePtr); + aniParams.emplace(iter.first, reminderAgentManager::manager::ParamType::make_double_t(doubleVal)); + } + break; + } + case VALUE_TYPE_BOOLEAN: { + AAFwk::IBoolean *boolPtr = AAFwk::IBoolean::Query(iter.second); + if (boolPtr != nullptr) { + bool boolVal = AAFwk::Boolean::Unbox(boolPtr); + aniParams.emplace(iter.first, reminderAgentManager::manager::ParamType::make_bool_t(boolVal)); + } + break; + } + case VALUE_TYPE_STRING: { + AAFwk::IString *strPtr = AAFwk::IString::Query(iter.second); + if (strPtr != nullptr) { + std::string strVal = AAFwk::String::Unbox(strPtr); + aniParams.emplace(iter.first, reminderAgentManager::manager::ParamType::make_string_t(strVal)); + } + break; + } + default: { + break; + } + } + } + aniWantAgent.parameters = + ::taihe::optional<::taihe::map<::taihe::string, reminderAgentManager::manager::ParamType>>::make(aniParams); +} + +void Common::GenAniWantAgent(const sptr& reminder, + ::taihe::optional& aniWantAgent) +{ + if (reminder->GetWantAgentInfo() == nullptr) { + return; + } + auto wantAgent = reminder->GetWantAgentInfo(); + reminderAgentManager::manager::WantAgent aniWant { + .pkgName = ::taihe::string(wantAgent->pkgName), + .abilityName = ::taihe::string(wantAgent->abilityName), + .uri = ::taihe::optional<::taihe::string>::make(::taihe::string(wantAgent->uri)), + }; + GenAniWantParams(wantAgent, aniWant); + aniWantAgent = ::taihe::optional::make(aniWant); +} + +void Common::GenAniMaxScreenWantAgent(const sptr& reminder, + ::taihe::optional& aniWantAgent) +{ + if (reminder->GetMaxScreenWantAgentInfo() == nullptr) { + return; + } + auto wantAgent = reminder->GetMaxScreenWantAgentInfo(); + reminderAgentManager::manager::MaxScreenWantAgent aniWant { + .pkgName = ::taihe::string(wantAgent->pkgName), + .abilityName = ::taihe::string(wantAgent->abilityName), + }; + aniWantAgent = ::taihe::optional::make(aniWant); +} + +void Common::GenAniActionButton(const sptr& reminder, + ::taihe::optional<::taihe::array>& aniActionButtons) +{ + auto actionButtons = reminder->GetActionButtons(); + if (actionButtons.empty()) { + return; + } + std::vector aniButtons; + for (const auto& [type, actionButton] : actionButtons) { + reminderAgentManager::manager::ActionButton aniActionButton { + .type = static_cast(type), + }; + aniActionButton.title = ::taihe::string(actionButton.title); + aniActionButton.titleResource = ::taihe::optional<::taihe::string>::make( + ::taihe::string(actionButton.resource)); + if (type == Notification::ReminderRequest::ActionButtonType::CUSTOM && actionButton.wantAgent != nullptr) { + reminderAgentManager::manager::WantAgent wantAgent { + .pkgName = ::taihe::string(actionButton.wantAgent->pkgName), + .abilityName = ::taihe::string(actionButton.wantAgent->abilityName), + }; + wantAgent.uri = ::taihe::optional<::taihe::string>::make(::taihe::string(reminder->GetCustomButtonUri())); + aniActionButton.wantAgent = ::taihe::optional::make(wantAgent); + } + aniButtons.push_back(aniActionButton); + } + aniActionButtons = ::taihe::optional<::taihe::array>::make(aniButtons); +} + +void Common::GenAniReminderBase(const sptr& reminder, + reminderAgentManager::manager::ReminderRequest& base) +{ + GenAniIntResult(reminder, base); + GenAniStringResult(reminder, base); + base.tapDismissed = ::taihe::optional::make(reminder->IsTapDismissed()); + GenAniWantAgent(reminder, base.wantAgent); + GenAniMaxScreenWantAgent(reminder, base.maxScreenWantAgent); + GenAniActionButton(reminder, base.actionButton); +} + +void Common::GenAniReminderTimer(const sptr& reminder, + reminderAgentManager::manager::ReminderRequestTimer& timer) +{ + GenAniReminderBase(reminder, timer.base); + Notification::ReminderRequestTimer* timerReq = + static_cast(reminder.GetRefPtr()); + timer.triggerTimeInSeconds = static_cast(timerReq->GetInitInfo()); +} + +void Common::GenAniReminderAlarm(const sptr& reminder, + reminderAgentManager::manager::ReminderRequestAlarm& alarm) +{ + GenAniReminderBase(reminder, alarm.base); + Notification::ReminderRequestAlarm* alarmReq = + static_cast(reminder.GetRefPtr()); + alarm.hour = static_cast(alarmReq->GetHour()); + alarm.minute = static_cast(alarmReq->GetMinute()); + auto daysOfWeek = reminder->GetDaysOfWeek(); + if (daysOfWeek.empty()) { + return; + } + std::vector results = ConvertInt(daysOfWeek); + alarm.daysOfWeek = ::taihe::optional<::taihe::array>::make(results); +} + +void Common::GenAniReminderCalendar(const sptr& reminder, + reminderAgentManager::manager::ReminderRequestCalendar& calendar) +{ + GenAniReminderBase(reminder, calendar.base); + Notification::ReminderRequestCalendar* calendarReq = + static_cast(reminder.GetRefPtr()); + calendar.dateTime.year = static_cast(calendarReq->GetFirstDesignateYear()); + calendar.dateTime.month = static_cast(calendarReq->GetFirstDesignageMonth()); + calendar.dateTime.day = static_cast(calendarReq->GetFirstDesignateDay()); + calendar.dateTime.hour = static_cast(calendarReq->GetHour()); + calendar.dateTime.minute = static_cast(calendarReq->GetMinute()); + calendar.dateTime.second = ::taihe::optional::make(static_cast(calendarReq->GetSecond())); + auto months = calendarReq->GetRepeatMonths(); + if (!months.empty()) { + std::vector results = ConvertInt(months); + calendar.repeatMonths = ::taihe::optional<::taihe::array>::make(results); + } + auto days = calendarReq->GetRepeatDays(); + if (!days.empty()) { + std::vector results = ConvertInt(days); + calendar.repeatDays = ::taihe::optional<::taihe::array>::make(results); + } + auto daysOfWeek = reminder->GetDaysOfWeek(); + if (!daysOfWeek.empty()) { + std::vector results = ConvertInt(daysOfWeek); + calendar.daysOfWeek = ::taihe::optional<::taihe::array>::make(results); + } +} + +bool Common::IsSelfSystemApp() +{ + auto selfToken = IPCSkeleton::GetSelfTokenID(); + return Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(selfToken); +} +} \ No newline at end of file -- Gitee