diff --git a/bundle.json b/bundle.json index de58f375c789c1037f09c35d63552c0f33216007..b6e84f4676b27560ea13ab78d8624f0519368aca 100644 --- a/bundle.json +++ b/bundle.json @@ -90,6 +90,7 @@ "init", "eventhandler", "c_utils", + "runtime_core", "i18n", "device_manager", "kv_store", @@ -120,7 +121,8 @@ "//base/notification/distributed_notification_service/frameworks/js/napi:napi_notification", "//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/reminder:reminder_client", + "//base/notification/distributed_notification_service/frameworks/ani:ani_packages" ], "service_group": [ "//base/notification/distributed_notification_service/sa_profile:ans_sa_profile", diff --git a/frameworks/ani/BUILD.gn b/frameworks/ani/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..071a0da8dfb3da17be6f183062cda92ae6d97cf2 --- /dev/null +++ b/frameworks/ani/BUILD.gn @@ -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. + +import("//base/notification/distributed_notification_service/notification.gni") +import("//build/ohos.gni") + +group("ani_packages") { + deps = [ + "notification_manager:notification_manager_ani_kit", + "notification_manager:notification_manager_abc_etc" + ] +} \ No newline at end of file diff --git a/frameworks/ani/notification_manager/BUILD.gn b/frameworks/ani/notification_manager/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..d91eb3ccda758bb8939bdb5fc16ee3fbd1c6071c --- /dev/null +++ b/frameworks/ani/notification_manager/BUILD.gn @@ -0,0 +1,109 @@ +# 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("//build/config/components/ets_frontend/ets2abc_config.gni") +import("//build/ohos.gni") +import("//base/notification/distributed_notification_service/notification.gni") + +ohos_shared_library("notification_manager_ani_kit") { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + cfi_vcall_icall_only = true + debug = false + } + + include_dirs = [ + "./include", + "${core_path}/common/include", + "${inner_api_path}", + "${frameworks_path}/cj/ffi/include", + ] + + sources = [ + "./src/sts_notification_manager.cpp", + "./src/sts_common_util.cpp", + "./src/sts_bundle_option.cpp", + "./src/sts_notification_enum_type.cpp", + "./src/sts_notification_slot.cpp", + "./src/sts_do_not_disturb_profile.cpp", + "./src/sts_notification_utils.cpp", + "./src/sts_notification_flags.cpp", + "./src/sts_notification_template.cpp", + "./src/sts_notification_user_input.cpp", + "./src/sts_notification_action_button.cpp", + "./src/sts_notification_content.cpp", + "./src/sts_notification_request.cpp", + ] + + cflags = [] + if (target_cpu == "arm") { + cflags += [ "-DBINDER_IPC_32BIT" ] + } + + deps = [ + "${frameworks_module_ans_path}:ans_innerkits", + "${frameworks_path}/cj/ffi:cj_notification_manager_ffi", + ] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + "runtime_core:ani", + "ipc:ipc_core", + "ability_base:zuri", + "ability_runtime:ani_common", + "ability_runtime:aniwantagent", + "ability_runtime:wantagent_innerkits", + "ability_runtime:ani_wantagent_common", + "ability_runtime:runtime", + "napi:ace_napi", + "image_framework:image_native", + "image_framework:image_ani", + "resource_management:global_resmgr", + ] + + innerapi_tags = [ "platformsdk" ] + subsystem_name = "${subsystem_name}" + part_name = "${component_name}" +} + +generate_static_abc("notification_manager_abc") { + base_url = "./ets" + files = [ + "./ets/notification/NotificationCommonDef.ets", + "./ets/@ohos.notificationManager.ets", + "./ets/notification/notificationContent.ets", + "./ets/notification/notificationFlags.ets", + "./ets/notification/notificationRequest.ets", + "./ets/notification/notificationTemplate.ets", + "./ets/notification/notificationUserInput.ets", + "./ets/notification/notificationActionButton.ets", + "./ets/notification/notificationSlot.ets", + ] + + dst_file = "$target_out_dir/notification_manager.abc" + out_puts = [ "$target_out_dir/notification_manager.abc" ] + + is_boot_abc = "True" + device_dst_file = "/system/framework/notification_manager.abc" +} + +ohos_prebuilt_etc("notification_manager_abc_etc") { + source = "$target_out_dir/notification_manager.abc" + module_install_dir = "framework" + subsystem_name = "${subsystem_name}" + part_name = "${component_name}" + deps = [ ":notification_manager_abc" ] +} diff --git a/frameworks/ani/notification_manager/ets/@ohos.notificationManager.ets b/frameworks/ani/notification_manager/ets/@ohos.notificationManager.ets new file mode 100644 index 0000000000000000000000000000000000000000..73c1e825dc804cf3a8055be6e6890667bea84d38 --- /dev/null +++ b/frameworks/ani/notification_manager/ets/@ohos.notificationManager.ets @@ -0,0 +1,484 @@ +/* + * 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 { BundleOption } from 'notification.NotificationCommonDef'; +import { NotificationRequest } from 'notification.notificationRequest'; +import { BusinessError, AsyncCallback } from '@ohos.base'; +import { NotificationSlot } from 'notification.notificationSlot'; + +type ResolveCallback = (data: T) => void; +type RejectCallback = (err: Object) => void; + +export default namespace notificationManager { + loadLibrary("notification_manager_ani_kit.z") + export enum SlotType { + UNKNOWN_TYPE = 0, + SOCIAL_COMMUNICATION = 1, + SERVICE_INFORMATION = 2, + CONTENT_INFORMATION = 3, + LIVE_VIEW = 4, + CUSTOMER_SERVICE = 5, + EMERGENCY_INFORMATION = 10, + OTHER_TYPES = 0xFFFF + } + + export interface DoNotDisturbProfile { + id: number; + name: string; + trustlist?: Array; + } + + class DoNotDisturbProfileInner implements DoNotDisturbProfile { + id: number = -1; + name: string = ""; + trustlist?: Array = new Array(); + } + + export enum DoNotDisturbType { + TYPE_NONE = 0, + TYPE_ONCE = 1, + TYPE_DAILY = 2, + TYPE_CLEARLY = 3 + } + + export interface DoNotDisturbDate { + type: DoNotDisturbType; + begin: Date; + end: Date; + } + + class DoNotDisturbDateInner implements DoNotDisturbDate { + type: DoNotDisturbType; + begin: Date; + end: Date; + } + + export native function nativeDisplayBadge(bundle: BundleOption, enable: boolean): void; + export native function nativeIsBadgeDisplayed(bundle: BundleOption): boolean; + export native function nativeGetActiveNotificationCount(): number; + export native function nativeIsNotificationEnabled(userId?: number, bundleOption?: BundleOption): boolean; + export native function nativegetSlotFlagsByBundle(bundle: BundleOption): int; + export native function nativesetSlotFlagsByBundle(bundle: BundleOption, slotFlags: number): void; + export native function nativeSetNotificationEnable(bundle: BundleOption, enable: boolean): void; + export native function nativeIsNotificationSlotEnabled(bundle: BundleOption, type: SlotType): boolean; + export native function nativeCancelWithId(id: number): void; + export native function nativeCancelWithIdOptionalLabel(id: number, label?: string): void; + export native function nativeCancelWithIdLabel(id: number, label: string): void; + export native function nativeCancelWithBundle(bundle: BundleOption, id: number): void; + export native function nativeCancelAll(): void; + export native function nativeGetSlotsByBundle(bundle: BundleOption): Array; + export native function nativeaddDoNotDisturbProfile(templates: Array): void; + export native function nativeremoveDoNotDisturbProfile(templates: Array): void; + export native function nativeSetNotificationEnableSlot(bundle: BundleOption, type: SlotType, enable: boolean, isForceControl?: boolean): void; + export native function nativeSetNotificationEnableSlotByOld(bundle: BundleOption, type: SlotType, enable: boolean): void; + export native function nativegetActiveNotifications():Array; + + export function displayBadge(bundle: BundleOption, enable: boolean, callback: AsyncCallback): void { + let p = taskpool.execute((): void => { return nativeDisplayBadge(bundle, enable); }); + p.then((e: NullishType): void => { + let err: BusinessError = {code: 0, data: undefined}; + callback(err, undefined); + }, (error: Object): void => { + let err: BusinessError = error as BusinessError; + callback(err, undefined); + }) + } + + export function displayBadge(bundle: BundleOption, enable: boolean): Promise { + let pPromise = new Promise((resolve: ResolveCallback, reject: RejectCallback): void => { + let p = taskpool.execute((): void => { return nativeDisplayBadge(bundle, enable); }); + p.then((data: NullishType): void => { + resolve(undefined); + }, (error: Object): void => { + reject(error); + }); + }); + return pPromise; + } + + export function isBadgeDisplayed(bundle: BundleOption, callback: AsyncCallback): void { + let p = taskpool.execute((): boolean => { return nativeIsBadgeDisplayed(bundle); }); + p.then((data: NullishType): void => { + let ret : boolean = data as boolean; + let err: BusinessError = {code: 0, data: undefined}; + callback(err, ret); + }, (error: Object): void => { + let ret : boolean = false; + let err: BusinessError = error as BusinessError; + callback(err, ret); + }) + } + + export function isBadgeDisplayed(bundle: BundleOption): Promise { + let pPromise = new Promise((resolve: ResolveCallback, reject: RejectCallback): void => { + let p = taskpool.execute((): boolean => { return nativeIsBadgeDisplayed(bundle); }); + p.then((data: NullishType): void => { + let ret : boolean = data as boolean; + resolve(ret); + }, (error: Object): void => { + reject(error); + }); + }); + return pPromise; + } + + export function getActiveNotificationCount(): Promise { + let pPromise = new Promise((resolve: ResolveCallback, reject: RejectCallback):void => { + let p = taskpool.execute((): number => { return nativeGetActiveNotificationCount(); }); + p.then((data :NullishType): void => { + let ret : number = data as number; + resolve(ret); + }, (err:Object): void => { + reject(err); + }); + }); + return pPromise; + } + + export function isNotificationEnabled(userId: number, callback: AsyncCallback): void + { + let p = taskpool.execute((): boolean => { return nativeIsNotificationEnabled(userId, undefined); }); + p.then((data: NullishType): void => { + let ret : boolean = data as boolean; + let err: BusinessError = {code: 0, data: undefined}; + callback(err, ret); + }, (error: Object): void => { + let ret : boolean = false; + let err: BusinessError = error as BusinessError; + callback(err, ret); + }) + } + + export function isNotificationEnabled(userId: number): Promise + { + let pPromise = new Promise((resolve: ResolveCallback, reject: RejectCallback): void => { + let p = taskpool.execute((): boolean => { return nativeIsNotificationEnabled(userId, undefined); }); + p.then((data: NullishType): void => { + let ret : boolean = data as boolean; + resolve(ret); + }, (error: Object): void => { + reject(error); + }); + }); + return pPromise; + } + + export function isNotificationEnabled(bundleOption: BundleOption, callback: AsyncCallback): void + { + let p = taskpool.execute((): boolean => { return nativeIsNotificationEnabled(undefined, bundleOption); }); + p.then((data: NullishType): void => { + let ret : boolean = data as boolean; + let err: BusinessError = {code: 0, data: undefined}; + callback(err, ret); + }, (error: Object): void => { + let ret : boolean = false; + let err: BusinessError = error as BusinessError; + callback(err, ret); + }) + } + + export function isNotificationEnabled(bundleOption: BundleOption): Promise + { + let pPromise = new Promise((resolve: ResolveCallback, reject: RejectCallback): void => { + let p = taskpool.execute((): boolean => { return nativeIsNotificationEnabled(undefined, bundleOption); }); + p.then((data: NullishType): void => { + let ret : boolean = data as boolean; + resolve(ret); + }, (error: Object): void => { + reject(error); + }); + }); + return pPromise; + } + + export function isNotificationEnabled(callback: AsyncCallback): void + { + let p = taskpool.execute((): boolean => { return nativeIsNotificationEnabled(undefined, undefined); }); + p.then((data: NullishType): void => { + let ret : boolean = data as boolean; + let err: BusinessError = {code: 0, data: undefined}; + callback(err, ret); + }, (error: Object): void => { + let ret : boolean = false; + let err: BusinessError = error as BusinessError; + callback(err, ret); + }) + } + + export function isNotificationEnabled(): Promise + { + let pPromise = new Promise((resolve: ResolveCallback, reject: RejectCallback): void => { + let p = taskpool.execute((): boolean => { return nativeIsNotificationEnabled(undefined, undefined); }); + p.then((data: NullishType): void => { + let ret : boolean = data as boolean; + resolve(ret); + }, (error: Object): void => { + reject(error); + }); + }); + return pPromise; + } + + export function getSlotFlagsByBundle(bundle: BundleOption): Promise { + let pPromise = new Promise((resolve: ResolveCallback, reject: RejectCallback): void => { + let p = taskpool.execute((): number => { return nativegetSlotFlagsByBundle(bundle); }); + p.then((data: NullishType): void => { + let ret : Double = data as Double; + resolve(ret); + }, (error: Object): void => { + reject(error); + }); + }); + return pPromise; + } + + export function setSlotFlagsByBundle(bundle: BundleOption, slotFlags: number): Promise { + let pPromise = new Promise((resolve: ResolveCallback, reject: RejectCallback): void => { + let p = taskpool.execute((): void => { return nativesetSlotFlagsByBundle(bundle, slotFlags); }); + p.then((data: NullishType): void => { + resolve(undefined); + }, (error: Object): void => { + reject(error); + }); + }); + return pPromise; + } + + export function setNotificationEnable(bundle: BundleOption, enable: boolean): Promise { + let pPromise = new Promise((resolve: ResolveCallback, reject: RejectCallback): void => { + let p = taskpool.execute((): void => { return nativeSetNotificationEnable(bundle, enable); }); + p.then((data: NullishType): void => { + resolve(undefined); + }, (error: Object): void => { + reject(error); + }); + }); + return pPromise; + } + + export function setNotificationEnable(bundle: BundleOption, enable: boolean, callback: AsyncCallback): void { + let p = taskpool.execute((): void => { return nativeSetNotificationEnable(bundle, enable); }); + p.then((data: NullishType): void => { + let err: BusinessError = {code: 0, data: undefined}; + callback(err, undefined); + }, (error: Object): void => { + let err: BusinessError = error as BusinessError; + callback(err, undefined); + }) + } + + export function isNotificationSlotEnabled(bundle: BundleOption, type: SlotType): Promise { + let pPromise = new Promise((resolve: ResolveCallback, reject: RejectCallback): void => { + let p = taskpool.execute((): boolean => { return nativeIsNotificationSlotEnabled(bundle, type); }); + p.then((data: NullishType): void => { + let ret : boolean = data as boolean; + resolve(ret); + }, (error: Object): void => { + reject(error); + }); + }); + return pPromise; + } + + export function isNotificationSlotEnabled(bundle: BundleOption, type: SlotType, callback: AsyncCallback): void { + let p = taskpool.execute((): boolean => { return nativeIsNotificationSlotEnabled(bundle, type); }); + p.then((data: NullishType): void => { + let ret : boolean = data as boolean; + let err: BusinessError = {code: 0, data: undefined}; + callback(err, ret); + }, (error: Object): void => { + let ret : boolean = false; + let err: BusinessError = error as BusinessError; + callback(err, ret); + }) + } + + export function cancel(id: number, callback: AsyncCallback): void { + let p = taskpool.execute((): void => { return nativeCancelWithId(id); }); + p.then((data: NullishType): void => { + let err: BusinessError = {code: 0, data: undefined}; + callback(err, undefined); + }, (error: Object): void => { + let err: BusinessError = error as BusinessError; + callback(err, undefined); + }) + } + + export function cancel(id: number, label?: string): Promise { + let pPromise = new Promise((resolve: ResolveCallback, reject: RejectCallback): void => { + let p = taskpool.execute((): void => { return nativeCancelWithIdOptionalLabel(id, label); }); + p.then((data: NullishType): void => { + resolve(undefined); + }, (error: Object): void => { + reject(error); + }); + }); + return pPromise; + } + + export function cancel(id: number, label: string, callback: AsyncCallback): void { + let p = taskpool.execute((): void => { return nativeCancelWithIdLabel(id, label); }); + p.then((data: NullishType): void => { + let err: BusinessError = {code: 0, data: undefined}; + callback(err, undefined); + }, (error: Object): void => { + let err: BusinessError = error as BusinessError; + callback(err, undefined); + }) + } + + export function cancel(bundle: BundleOption, id: number): Promise { + let pPromise = new Promise((resolve: ResolveCallback, reject: RejectCallback): void => { + let p = taskpool.execute((): void => { return nativeCancelWithBundle(bundle, id); }); + p.then((data: NullishType): void => { + resolve(undefined); + }, (error: Object): void => { + reject(error); + }); + }); + return pPromise; + } + + export function cancelAll(): Promise { + let pPromise = new Promise((resolve: ResolveCallback, reject: RejectCallback): void => { + let p = taskpool.execute((): void => { return nativeCancelAll(); }); + p.then((data: NullishType): void => { + resolve(undefined); + }, (error: Object): void => { + reject(error); + }); + }); + return pPromise; + } + + export function cancelAll(callback: AsyncCallback): void { + let p = taskpool.execute((): void => { return nativeCancelAll(); }); + p.then((data: NullishType): void => { + let err: BusinessError = {code: 0, data: undefined}; + callback(err, undefined); + }, (error: Object): void => { + let err: BusinessError = error as BusinessError; + callback(err, undefined); + }) + } + + export function getSlotsByBundle(bundle: BundleOption, callback: AsyncCallback>): void { + let p = taskpool.execute((): Array => { return nativeGetSlotsByBundle(bundle); }); + p.then((data: NullishType): void => { + let slots : Array = data as Array; + let err: BusinessError = {code: 0, data: undefined}; + callback(err, slots); + }, (error: Object): void => { + let slots : Array = []; + let err: BusinessError = error as BusinessError; + callback(err, slots); + }) + } + + export function getSlotsByBundle(bundle: BundleOption): Promise> { + let pPromise = new Promise>((resolve: ResolveCallback>, reject: RejectCallback): void => { + let p = taskpool.execute((): Array => { return nativeGetSlotsByBundle(bundle); }); + p.then((data: NullishType): void => { + let slots : Array = data as Array; + resolve(slots); + }, (error: Object): void => { + reject(error); + }); + }); + return pPromise; + } + + export function addDoNotDisturbProfile(templates: Array): Promise { + let pPromise = new Promise((resolve: ResolveCallback, reject: RejectCallback): void => { + let p = taskpool.execute((): void => { return nativeaddDoNotDisturbProfile(templates); }); + p.then((data: NullishType): void => { + resolve(undefined); + }, (error: Object): void => { + reject(error); + }); + }); + return pPromise; + } + + export function removeDoNotDisturbProfile(templates: Array): Promise { + let pPromise = new Promise((resolve: ResolveCallback, reject: RejectCallback): void => { + let p = taskpool.execute((): void => { return nativeremoveDoNotDisturbProfile(templates); }); + p.then((data: NullishType): void => { + resolve(undefined); + }, (error: Object): void => { + reject(error); + }); + }); + return pPromise; + } + + export function setNotificationEnableSlot(bundle: BundleOption, type: SlotType, enable: boolean, callback: AsyncCallback): void { + let p = taskpool.execute((): void => { return nativeSetNotificationEnableSlotByOld(bundle, type, enable); }); + p.then((data: NullishType): void => { + let err: BusinessError = {code: 1, data: undefined}; + callback(err, undefined); + }, (error: Object): void => { + let err: BusinessError = error as BusinessError; + callback(err, undefined); + }) + } + + export function setNotificationEnableSlot(bundle: BundleOption, type: SlotType, enable: boolean, isForceControl: boolean, callback: AsyncCallback): void { + let p = taskpool.execute((): void => { return nativeSetNotificationEnableSlot(bundle, type, enable, isForceControl); }); + p.then((data: NullishType): void => { + let err: BusinessError = {code: 1, data: undefined}; + callback(err, undefined); + }, (error: Object): void => { + let err: BusinessError = error as BusinessError; + callback(err, undefined); + }) + } + + export function setNotificationEnableSlot(bundle: BundleOption, type: SlotType, enable: boolean, isForceControl?: boolean): Promise { + let pPromise = new Promise((resolve: ResolveCallback, reject: RejectCallback): void => { + let p = taskpool.execute((): void => { return nativeSetNotificationEnableSlot(bundle, type, enable, isForceControl); }); + p.then((data: NullishType): void => { + resolve(undefined); + }, (error: Object): void => { + reject(error); + }); + }); + return pPromise; + } + + export function getActiveNotifications(callback: AsyncCallback>): void + { + let p = taskpool.execute((): Array => { return nativegetActiveNotifications(); }); + p.then((data: NullishType): void => { + let ret : Array = data as Array; + let err: BusinessError = {code: 1, data: undefined}; + callback(err, ret); + }, (error: Object): void => { + }) + } + + export function getActiveNotifications(): Promise> { + let pPromise = new Promise>((resolve: ResolveCallback>, reject: RejectCallback): void => { + let p = taskpool.execute((): Array => { return nativegetActiveNotifications(); }); + p.then((data: NullishType): void => { + let ret : Array = data as Array; + resolve(ret); + }, (error: Object): void => { + reject(error); + }); + }); + return pPromise; + } +} diff --git a/frameworks/ani/notification_manager/ets/notification/NotificationCommonDef.ets b/frameworks/ani/notification_manager/ets/notification/NotificationCommonDef.ets new file mode 100644 index 0000000000000000000000000000000000000000..df9b9489224cfbc550bd7dc4af83ef9dcb55d24b --- /dev/null +++ b/frameworks/ani/notification_manager/ets/notification/NotificationCommonDef.ets @@ -0,0 +1,24 @@ +/* + * 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. + */ + +export interface BundleOption { + bundle: string; + uid?: number; +} + +class BundleOptionInner implements BundleOption { + public bundle: string = ''; + public uid?: number | undefined; +} \ No newline at end of file diff --git a/frameworks/ani/notification_manager/ets/notification/notificationActionButton.ets b/frameworks/ani/notification_manager/ets/notification/notificationActionButton.ets new file mode 100644 index 0000000000000000000000000000000000000000..509e4a494dd58bcb75a8b324bd4145daa5c5ef66 --- /dev/null +++ b/frameworks/ani/notification_manager/ets/notification/notificationActionButton.ets @@ -0,0 +1,39 @@ +/* + * 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 { NotificationUserInput } from './notificationUserInput'; +import { WantAgent } from '@ohos.app.ability.wantAgent'; + +export interface NotificationActionButton { + + title: string; + + wantAgent: WantAgent; + + extras?: Record; + + userInput?: NotificationUserInput; +} + +class NotificationActionButtonInner implements NotificationActionButton { + + title: string = ""; + + wantAgent: WantAgent = {}; + + extras?: Record | undefined; + + userInput?: NotificationUserInput | undefined; +} \ No newline at end of file diff --git a/frameworks/ani/notification_manager/ets/notification/notificationContent.ets b/frameworks/ani/notification_manager/ets/notification/notificationContent.ets new file mode 100644 index 0000000000000000000000000000000000000000..11d78c74efde282dfc808ff5bae489ead95e6448 --- /dev/null +++ b/frameworks/ani/notification_manager/ets/notification/notificationContent.ets @@ -0,0 +1,398 @@ +/* + * 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 image from '@ohos.multimedia.image'; +import { Resource } from 'global.resource'; +import type notificationManager from '@ohos.notificationManager'; + +type IconType = Resource | image.PixelMap; + +class RecordTools { + public static GetKeys(record: Record): Array { + try { + let keys: Array = Object.keys(record); + return keys; + } catch (err) { + return {}; + } + } +} + +class ResourceInner implements Resource { + bundleName: string = ""; + moduleName: string = ""; + id: number = 0; + params?: Array | undefined; + type?: number | undefined; +} + +export interface NotificationBasicContent { + + title: string; + + text: string; + + additionalText?: string; + + lockscreenPicture?: image.PixelMap; +} + +class NotificationBasicContentInner implements NotificationBasicContent { + + title: string = ""; + + text: string = ""; + + additionalText?: string | undefined; + + lockscreenPicture?: image.PixelMap | undefined; +} + +export interface NotificationLongTextContent extends NotificationBasicContent { + + longText: string; + + briefText: string; + + expandedTitle: string; +} + +class NotificationLongTextContentInner implements NotificationLongTextContent { + + title: string = ""; + + text: string = ""; + + additionalText?: string; + + lockscreenPicture?: image.PixelMap | undefined; + + longText: string = ""; + + briefText: string = ""; + + expandedTitle: string = ""; +} + +export enum LiveViewStatus { + + LIVE_VIEW_CREATE = 0, + + LIVE_VIEW_INCREMENTAL_UPDATE = 1, + + LIVE_VIEW_END = 2, + + LIVE_VIEW_FULL_UPDATE = 3 +} + +export enum LiveViewTypes { + + LIVE_VIEW_ACTIVITY = 0, + + LIVE_VIEW_INSTANT = 1, + + LIVE_VIEW_LONG_TERM = 2 +} + +export interface NotificationLiveViewContent extends NotificationBasicContent { + + status: LiveViewStatus; + + version?: number; + + extraInfo?: Record; + + pictureInfo?: Record>; + + isLocalUpdateOnly?: boolean; +} + +class NotificationLiveViewContentInner implements NotificationLiveViewContent { + + title: string = ""; + + text: string = ""; + + additionalText?: string | undefined; + + lockscreenPicture?: image.PixelMap | undefined; + + status: LiveViewStatus = LiveViewStatus.LIVE_VIEW_CREATE; + + version?: number | undefined; + + extraInfo?: Record | undefined; + + pictureInfo?: Record> | undefined; + + isLocalUpdateOnly?: boolean | undefined; +} + +export interface NotificationMultiLineContent extends NotificationBasicContent { + + briefText: string; + + longTitle: string; + + lines: Array; +} + +class NotificationMultiLineContentInner implements NotificationMultiLineContent { + + title: string = ""; + + text: string = ""; + + additionalText?: string | undefined; + + lockscreenPicture?: image.PixelMap | undefined; + + briefText: string = ""; + + longTitle: string = ""; + + lines: Array = {}; +} + +export interface NotificationPictureContent extends NotificationBasicContent { + + briefText: string; + + expandedTitle: string; + + picture: image.PixelMap; +} + +class NotificationPictureContentInner implements NotificationPictureContent { + private CreatePixelMap() : image.PixelMap { + let opts: image.InitializationOptions = { size: { height: 4, width: 6 } } + return image.createPixelMapSync(opts); + } + + title: string = ""; + + text: string = ""; + + additionalText?: string | undefined; + + lockscreenPicture?: image.PixelMap | undefined; + + briefText: string = ""; + + expandedTitle: string = ""; + + picture: image.PixelMap = this.CreatePixelMap(); +} + +export interface NotificationSystemLiveViewContent extends NotificationBasicContent { + + typeCode: number; + + capsule?: NotificationCapsule; + + button?: NotificationButton; + + cardButtons?: Array; + + time?: NotificationTime; + + progress?: NotificationProgress; + + liveViewType?: LiveViewTypes; +} + +class NotificationSystemLiveViewContentInner implements NotificationSystemLiveViewContent { + private CreatePixelMap() : image.PixelMap { + let opts: image.InitializationOptions = { size: { height: 4, width: 6 } } + return image.createPixelMapSync(opts); + } + + title: string = ""; + + text: string = ""; + + additionalText?: string | undefined; + + lockscreenPicture?: image.PixelMap | undefined; + + briefText: string = ""; + + expandedTitle: string = ""; + + picture: image.PixelMap = this.CreatePixelMap(); + + typeCode: number = 0; + + capsule?: NotificationCapsule | undefined; + + button?: NotificationButton | undefined; + + cardButtons?: Array | undefined; + + time?: NotificationTime | undefined; + + progress?: NotificationProgress | undefined; + + liveViewType?: LiveViewTypes | undefined; +} + +export interface NotificationCapsule { + + title?: string; + + icon?: image.PixelMap; + + backgroundColor?: string; + + content?: string; + + time?: number; + + capsuleButtons?: Array; +} + +class NotificationCapsuleInner implements NotificationCapsule { + + title?: string | undefined; + + icon?: image.PixelMap | undefined; + + backgroundColor?: string | undefined; + + content?: string | undefined; + + time?: number | undefined; + + capsuleButtons?: Array | undefined; +} + +export interface NotificationIconButton { + + name: string; + + iconResource: IconType; + + text?: string; + + hidePanel?: boolean; +} + +class NotificationIconButtonInner implements NotificationIconButton { + + private CreatePixelMap() : image.PixelMap { + let opts: image.InitializationOptions = { size: { height: 4, width: 4 } } + return image.createPixelMapSync(opts); + } + + name: string = ""; + + iconResource: IconType = this.CreatePixelMap(); + + text?: string | undefined; + + hidePanel?: boolean | undefined; +} + +export interface NotificationButton { + + names?: Array; + + icons?: Array; + + iconsResource?: Array; +} + +class NotificationButtonInner implements NotificationButton { + + names?: Array | undefined; + + icons?: Array | undefined; + + iconsResource?: Array | undefined; +} + +export interface NotificationTime { + + initialTime?: number; + + isCountDown?: boolean; + + isPaused?: boolean; + + isInTitle?: boolean; +} + +class NotificationTimeInner implements NotificationTime { + + initialTime?: number; + + isCountDown?: boolean; + + isPaused?: boolean; + + isInTitle?: boolean; +} + +export interface NotificationProgress { + + maxValue?: number; + + currentValue?: number; + + isPercentage?: boolean; +} + +class NotificationProgressInner implements NotificationProgress { + + maxValue?: number | undefined; + + currentValue?: number | undefined; + + isPercentage?: boolean | undefined; +} + +export interface NotificationContent { + + notificationContentType?: notificationManager.ContentType; + + normal?: NotificationBasicContent; + + longText?: NotificationLongTextContent; + + multiLine?: NotificationMultiLineContent; + + picture?: NotificationPictureContent; + + systemLiveView?: NotificationSystemLiveViewContent; + + liveView?: NotificationLiveViewContent; +} + +class NotificationContentInner implements NotificationContent { + + notificationContentType?: notificationManager.ContentType | undefined; + + normal?: NotificationBasicContent | undefined; + + longText?: NotificationLongTextContent | undefined; + + multiLine?: NotificationMultiLineContent | undefined; + + picture?: NotificationPictureContent | undefined; + + systemLiveView?: NotificationSystemLiveViewContent | undefined; + + liveView?: NotificationLiveViewContent | undefined; +} \ No newline at end of file diff --git a/frameworks/ani/notification_manager/ets/notification/notificationFlags.ets b/frameworks/ani/notification_manager/ets/notification/notificationFlags.ets new file mode 100644 index 0000000000000000000000000000000000000000..e5480471af7ec82ebfd2b1dd68203a164decd74a --- /dev/null +++ b/frameworks/ani/notification_manager/ets/notification/notificationFlags.ets @@ -0,0 +1,41 @@ +/* + * 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. + */ + + export enum NotificationFlagStatus { + + TYPE_NONE = 0, + + TYPE_OPEN = 1, + + TYPE_CLOSE = 2 +} + +export interface NotificationFlags { + + readonly soundEnabled?: NotificationFlagStatus; + + readonly vibrationEnabled?: NotificationFlagStatus; + + readonly reminderFlags?: number; +} + +class NotificationFlagsInner implements NotificationFlags { + + soundEnabled?: NotificationFlagStatus | undefined; + + vibrationEnabled?: NotificationFlagStatus| undefined; + + reminderFlags?: number | undefined; +} \ No newline at end of file diff --git a/frameworks/ani/notification_manager/ets/notification/notificationRequest.ets b/frameworks/ani/notification_manager/ets/notification/notificationRequest.ets new file mode 100644 index 0000000000000000000000000000000000000000..8a8224eccfd024e7566ae02824b94ba9f3d5f3e0 --- /dev/null +++ b/frameworks/ani/notification_manager/ets/notification/notificationRequest.ets @@ -0,0 +1,181 @@ +/* + * 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 image from '@ohos.multimedia.image'; +import type notificationManager from '@ohos.notificationManager'; +import type notificationSubscribe from '@ohos.notificationSubscribe'; +import { NotificationContent } from 'notification.notificationContent'; +import { NotificationActionButton } from 'notification.notificationActionButton'; +import { NotificationTemplate } from 'notification.notificationTemplate'; +import { NotificationFlags } from 'notification.notificationFlags'; +import { WantAgent } from '@ohos.app.ability.wantAgent'; +import { BundleOption } from 'notification.NotificationCommonDef'; + +export interface DistributedOptions { + isDistributed?: boolean; + supportDisplayDevices?: Array; + supportOperateDevices?: Array; + readonly remindType?: number; +} + +class DistributedOptionsInner implements DistributedOptions { + isDistributed?: boolean | undefined; + supportDisplayDevices?: Array | undefined; + supportOperateDevices?: Array | undefined; + readonly remindType?: number | undefined; +} + +export interface NotificationFilter { + bundle: BundleOption; + notificationKey: notificationSubscribe.NotificationKey; + extraInfoKeys?: Array; +} + +class NotificationFilterInner implements NotificationFilter { + bundle: BundleOption = {}; + notificationKey: notificationSubscribe.NotificationKey = {}; + extraInfoKeys?: Array | undefined; +} + +export interface NotificationCheckRequest { + contentType: notificationManager.ContentType; + slotType: notificationManager.SlotType; + extraInfoKeys: Array; +} + +class NotificationCheckRequestInner implements NotificationCheckRequest { + contentType: notificationManager.ContentType = notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT; + slotType: notificationManager.SlotType = notificationManager.SlotType.OTHER_TYPES; + extraInfoKeys: Array = {}; +} + +export interface UnifiedGroupInfo { + key?: string; + title?: string; + content?: string; + sceneName?: string; + extraInfo?: Record; +} + +class UnifiedGroupInfoInner implements UnifiedGroupInfo { + key?: string | undefined; + title?: string | undefined; + content?: string | undefined; + sceneName?: string | undefined; + extraInfo?: Record | undefined; +} + +export interface NotificationRequest { + content: NotificationContent; + id?: number; + appMessageId?: string; + notificationSlotType?: notificationManager.SlotType; + isOngoing?: boolean; + isUnremovable?: boolean; + updateOnly?: boolean; + deliveryTime?: number; + tapDismissed?: boolean; + autoDeletedTime?: number; + wantAgent?: WantAgent; + extraInfo?: Record; + color?: number; + colorEnabled?: boolean; + isAlertOnce?: boolean; + isStopwatch?: boolean; + isCountDown?: boolean; + isFloatingIcon?: boolean; + label?: string; + badgeIconStyle?: number; + showDeliveryTime?: boolean; + actionButtons?: Array; + smallIcon?: image.PixelMap; + largeIcon?: image.PixelMap; + overlayIcon?: image.PixelMap; + groupName?: string; + readonly creatorBundleName?: string; + readonly creatorUid?: number; + readonly creatorPid?: number; + readonly creatorUserId?: number; + readonly creatorInstanceKey?: number; + sound?: string; + classification?: string; + readonly hashCode?: string; + isRemoveAllowed?: boolean; + readonly source?: number; + template?: NotificationTemplate; + distributedOption?: DistributedOptions; + readonly deviceId?: string; + readonly notificationFlags?: NotificationFlags; + removalWantAgent?: WantAgent; + badgeNumber?: number; + representativeBundle?: BundleOption; + readonly agentBundle?: BundleOption; + unifiedGroupInfo?: UnifiedGroupInfo; + notificationControlFlags?: number; + readonly appInstanceKey?: string; + forceDistributed?: boolean; + notDistributed?: boolean; +} + +class NotificationRequestInner implements NotificationRequest { + content: NotificationContent = {}; + id?: number | undefined; + appMessageId?: string | undefined; + notificationSlotType?: notificationManager.SlotType | undefined; + isOngoing?: boolean | undefined; + isUnremovable?: boolean | undefined; + updateOnly?: boolean | undefined; + deliveryTime?: number | undefined; + tapDismissed?: boolean | undefined; + autoDeletedTime?: number | undefined; + wantAgent?: WantAgent | undefined; + extraInfo?: Record | undefined; + color?: number | undefined; + colorEnabled?: boolean | undefined; + isAlertOnce?: boolean | undefined; + isStopwatch?: boolean | undefined; + isCountDown?: boolean | undefined; + isFloatingIcon?: boolean | undefined; + label?: string | undefined; + badgeIconStyle?: number | undefined; + showDeliveryTime?: boolean | undefined; + actionButtons?: Array | undefined; + smallIcon?: image.PixelMap | undefined; + largeIcon?: image.PixelMap | undefined; + overlayIcon?: image.PixelMap | undefined; + groupName?: string | undefined; + readonly creatorBundleName?: string | undefined; + readonly creatorUid?: number | undefined; + readonly creatorPid?: number | undefined; + readonly creatorUserId?: number | undefined; + readonly creatorInstanceKey?: number | undefined; + sound?: string | undefined; + classification?: string | undefined; + readonly hashCode?: string | undefined; + isRemoveAllowed?: boolean | undefined; + readonly source?: number | undefined; + template?: NotificationTemplate | undefined; + distributedOption?: DistributedOptions | undefined; + readonly deviceId?: string | undefined; + readonly notificationFlags?: NotificationFlags | undefined; + removalWantAgent?: WantAgent | undefined; + badgeNumber?: number | undefined; + representativeBundle?: BundleOption | undefined; + readonly agentBundle?: BundleOption | undefined; + unifiedGroupInfo?: UnifiedGroupInfo | undefined; + notificationControlFlags?: number | undefined; + readonly appInstanceKey?: string | undefined; + forceDistributed?: boolean | undefined; + notDistributed?: boolean | undefined; +} diff --git a/frameworks/ani/notification_manager/ets/notification/notificationSlot.ets b/frameworks/ani/notification_manager/ets/notification/notificationSlot.ets new file mode 100644 index 0000000000000000000000000000000000000000..8c6466d1953f2ad4e1a4f2c416f88898e880b465 --- /dev/null +++ b/frameworks/ani/notification_manager/ets/notification/notificationSlot.ets @@ -0,0 +1,35 @@ +import type notificationManager from '@ohos.notificationManager'; + +export interface NotificationSlot { + notificationType?: notificationManager.SlotType; + //level?: notification.SlotLevel; + desc?: string; + badgeFlag?: boolean; + bypassDnd?: boolean; + lockscreenVisibility?: number; + vibrationEnabled?: boolean; + sound?: string; + lightEnabled?: boolean; + lightColor?: number; + vibrationValues?: Array; + readonly enabled?: boolean; + readonly reminderMode?: number; + readonly authorizedStatus?: number; +} + +class NotificationSlotInner implements NotificationSlot { + notificationType?: notificationManager.SlotType | undefined; + //level?: notification.SlotLevel; + desc?: string | undefined; + badgeFlag?: boolean | undefined; + bypassDnd?: boolean | undefined; + lockscreenVisibility?: number | undefined; + vibrationEnabled?: boolean | undefined; + sound?: string | undefined; + lightEnabled?: boolean | undefined; + lightColor?: number | undefined; + vibrationValues?: Array | undefined; + readonly enabled?: boolean | undefined; + readonly reminderMode?: number | undefined; + readonly authorizedStatus?: number | undefined; +} \ No newline at end of file diff --git a/frameworks/ani/notification_manager/ets/notification/notificationTemplate.ets b/frameworks/ani/notification_manager/ets/notification/notificationTemplate.ets new file mode 100644 index 0000000000000000000000000000000000000000..8033b77234b10595eef121e0021dce265c89e238 --- /dev/null +++ b/frameworks/ani/notification_manager/ets/notification/notificationTemplate.ets @@ -0,0 +1,24 @@ +/* + * 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. + */ + + export interface NotificationTemplate { + name: string; + data: Record; +} + +class NotificationTemplateInner implements NotificationTemplate { + name: string = ""; + data: Record = {}; +} \ No newline at end of file diff --git a/frameworks/ani/notification_manager/ets/notification/notificationUserInput.ets b/frameworks/ani/notification_manager/ets/notification/notificationUserInput.ets new file mode 100644 index 0000000000000000000000000000000000000000..6ac04f6859c4bc506d5b3b6821ab65f778626726 --- /dev/null +++ b/frameworks/ani/notification_manager/ets/notification/notificationUserInput.ets @@ -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. + */ + +export interface NotificationUserInput { + inputKey: string; +} + +class NotificationUserInputInner implements NotificationUserInput { + inputKey: string = ""; +} \ No newline at end of file diff --git a/frameworks/ani/notification_manager/include/sts_bundle_option.h b/frameworks/ani/notification_manager/include/sts_bundle_option.h new file mode 100644 index 0000000000000000000000000000000000000000..c67cc05d3b6716161a5775440fc162cd578fadba --- /dev/null +++ b/frameworks/ani/notification_manager/include/sts_bundle_option.h @@ -0,0 +1,29 @@ +/* + * 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 OHOS_DISTRIBUTED_NOTIFICATION_SERVER_STS_BUNDLE_OPTION_H +#define OHOS_DISTRIBUTED_NOTIFICATION_SERVER_STS_BUNDLE_OPTION_H + +#include "ani.h" +#include "notification_bundle_option.h" + +namespace OHOS { +namespace NotificationSts { + bool UnwrapBundleOption(ani_env *env, ani_object param, Notification::NotificationBundleOption& option); + bool UnwrapArrayBundleOption(ani_env *env, ani_ref arrayObj, std::vector& options); +} +} + +#endif \ No newline at end of file diff --git a/frameworks/ani/notification_manager/include/sts_common_util.h b/frameworks/ani/notification_manager/include/sts_common_util.h new file mode 100644 index 0000000000000000000000000000000000000000..ce13d9ef3fea9425dcd254af94c01e2257e89334 --- /dev/null +++ b/frameworks/ani/notification_manager/include/sts_common_util.h @@ -0,0 +1,267 @@ +/* + * 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 OHOS_DISTRIBUTED_NOTIFICATION_SERVER_STS_COMMON_UTIL_H +#define OHOS_DISTRIBUTED_NOTIFICATION_SERVER_STS_COMMON_UTIL_H +#include "ani.h" +#include "notification_bundle_option.h" +#include "notification_constant.h" +#include +#include + +namespace OHOS { +namespace NotificationSts { +static const char *NotificationSlotClassName = "Lnotification/notificationSlot/NotificationSlotInner;"; + +bool GetAniString(ani_env* env, const std::string str, ani_string& aniStr); +ani_string GetAniString(ani_env* env, const std::string str); +ani_status GetStdString(ani_env *env, ani_string str, std::string &res); +ani_status GetPropertyRef(ani_env *env, ani_object obj, const char *name, ani_ref &ref, ani_boolean &isUndefined); +ani_status GetPropertyString(ani_env *env, ani_object obj, const char *name, + ani_boolean &isUndefined, std::string &outStr); +ani_status GetStringArrayOrUndefined(ani_env *env, ani_object param, const char *name, + ani_boolean &isUndefined, std::vector &res); +ani_status GetPropertyBooleanOrUndefined(ani_env *env, ani_object aniObj, const char *name, + ani_boolean isUndefined, bool outvalue); +ani_status GetPropertyDoubleOrUndefined(ani_env *env, ani_object obj, const char *name, + ani_boolean &isUndefined, ani_double &outvalue); +bool CreateClassObjByClassName(ani_env *env, const char *className, ani_class &cls, ani_object &outAniObj); + +bool SetFieldString(ani_env *env, ani_class cls, ani_object object, const std::string &fieldName, + const std::string &value); +bool SetOptionalFieldBoolean(ani_env *env, ani_class cls, ani_object object, const std::string &fieldName, bool value); +bool SetOptionalFieldDouble(ani_env *env, ani_class cls, ani_object object, const std::string &fieldName, double value); +bool SetOptionalFieldArrayDouble(ani_env *env, ani_class cls, ani_object object, const std::string &fieldName, + const std::vector &values); +bool SetOptionalFieldSlotType(ani_env *env, ani_class cls, ani_object object, const std::string &fieldName, + const Notification::NotificationConstant::SlotType& value); + +std::string FindAnsErrMsg(const int32_t errCode); +ani_object newArrayClass(ani_env *env, int length); + +ani_object createBoolean(ani_env *env, ani_boolean value); +ani_object createDouble(ani_env *env, ani_double value); + +inline bool AniBooleanToBool(ani_boolean value) +{ + return value == ANI_TRUE; +} + +inline ani_boolean BoolToAniBoolean(bool value) +{ + return value ? ANI_TRUE : ANI_FALSE; +} + +template +static ani_object ConvertToAniArrayString(ani_env* env, + const containerType& nativeArray, Converter converter, Args&&... args) +{ + ani_class arrayCls = nullptr; + ani_status status = env->FindClass("Lescompat/Array;", &arrayCls); + if (status != ANI_OK) { + ANS_LOGE("FindClass failed %{public}d", status); + return nullptr; + } + + ani_method arrayCtor; + status = env->Class_FindMethod(arrayCls, "", "I:V", &arrayCtor); + if (status != ANI_OK) { + ANS_LOGE("Class_FindMethod failed %{public}d", status); + return nullptr; + } + + ani_size length = nativeArray.size(); + ani_object arrayObj; + status = env->Object_New(arrayCls, arrayCtor, &arrayObj, length); + if (status != ANI_OK) { + ANS_LOGE("Object_New failed %{public}d", status); + return nullptr; + } + + ani_size i = 0; + for (const auto& iter : nativeArray) { + ani_object item = converter(env, iter, std::forward(args)...); + status = env->Object_CallMethodByName_Void(arrayObj, "$_set", "ILstd/core/Object;:V", i, item); + env->Reference_Delete(item); + if (status != ANI_OK) { + ANS_LOGE("Object_CallMethodByName_Void failed %{public}d", status); + return nullptr; + } + ++i; + } + + return arrayObj; +} + +[[maybe_unused]]static ani_object ConvertVectorToAniArrayString(ani_env* env, + const std::vector& strings) +{ + return ConvertToAniArrayString(env, strings, [](ani_env* env, const std::string& nativeStr) { + ani_string aniStr = nullptr; + return GetAniString(env, nativeStr) ? aniStr : nullptr; + }); +} + + +#define ANI_FAILED_AND_RETURN(status) \ +do \ +{ \ + ani_status const local_status = (status); \ + if (ani_status::ANI_OK != local_status) \ + { \ + ANS_LOGE("check status error: %{public}d", (int)local_status); \ + return false; \ + } \ +} while (0) + +#define RETURN_NULL_IF_NULL(ptr) \ + do { \ + if ((ptr) == nullptr) { \ + ANS_LOGE("ptr is null"); \ + return nullptr; \ + } \ + } while (0) +#define RETURN_FALSE_IF_NULL(ptr) \ + do { \ + if ((ptr) == nullptr) { \ + ANS_LOGE("ptr is null"); \ + return false; \ + } \ + } while (0) +#define RETURN_NULL_IF_FALSE(condition) \ + do { \ + if (!(condition)) { \ + ANS_LOGE("condition is false"); \ + return nullptr; \ + } \ + } while (0) +#define RETURN_FALSE_IF_FALSE(condition) \ + do { \ + if (!(condition)) { \ + return false; \ + } \ + } while (0) +#define RETURN_ANI_STATUS_IF_NOT_OK(res, err) \ + do { \ + if ((res) != ANI_OK) { \ + ANS_LOGE(err); \ + return res; \ + } \ + } while (0) + +template +bool CallSetter(ani_env* env, ani_class cls, ani_object &object, const char* propertyName, valueType value) +{ + RETURN_FALSE_IF_NULL(env); + RETURN_FALSE_IF_NULL(cls); + RETURN_FALSE_IF_NULL(object); + std::string setterName(""); + setterName.append(propertyName); + ani_method setter; + ani_status status = env->Class_FindMethod(cls, setterName.c_str(), nullptr, &setter); + if (status != ANI_OK) { + ANS_LOGE("Class_FindMethod %{public}s failed %{public}d", propertyName, status); + return false; + } + if constexpr (std::is_same_v || std::is_same_v || + std::is_same_v || std::is_same_v || + std::is_same_v || std::is_same_v || + std::is_same_v || std::is_same_v) { + status = env->Object_CallMethod_Void(object, setter, static_cast(value)); + } else { + status = env->Object_CallMethod_Void(object, setter, value); + } + if (status != ANI_OK) { + ANS_LOGE("Object_CallMethod_Void %{public}s failed %{public}d", propertyName, status); + return false; + } + return true; +} + +template +bool CallSetterOptional( + ani_env* env, ani_class cls, ani_object &object, const char* propertyName, valueType value) +{ + RETURN_FALSE_IF_NULL(env); + RETURN_FALSE_IF_NULL(cls); + RETURN_FALSE_IF_NULL(object); + if constexpr (std::is_pointer_v && std::is_base_of_v<__ani_ref, std::remove_pointer_t>) { + return CallSetter(env, cls, object, propertyName, value); + } + const char* valueClassName = nullptr; + const char* ctorSig = nullptr; + if constexpr (std::is_same_v) { + valueClassName = "Lstd/core/Boolean;"; + ctorSig = "Z:V"; + } else if constexpr (std::is_same_v) { + valueClassName = "Lstd/core/Char;"; + ctorSig = "C:V"; + } else if constexpr (std::is_same_v || std::is_same_v || + std::is_same_v || std::is_same_v || + std::is_same_v || std::is_same_v || + std::is_same_v || std::is_same_v) { + valueClassName = "Lstd/core/Double;"; + ctorSig = "D:V"; + } else { + ANS_LOGE("Classname %{public}s Unsupported", propertyName); + return false; + } + ani_class valueClass = nullptr; + ani_status status = env->FindClass(valueClassName, &valueClass); + if (status != ANI_OK) { + ANS_LOGE("FindClass %{public}s %{public}s failed %{public}d", propertyName, valueClassName, status); + return false; + } + ani_method ctor = nullptr; + status = env->Class_FindMethod(valueClass, "", ctorSig, &ctor); + if (status != ANI_OK) { + ANS_LOGE("Class_FindMethod %{public}s failed %{public}d", propertyName, status); + return false; + } + ani_object valueObj = nullptr; + if constexpr (std::is_same_v || std::is_same_v) { + status = env->Object_New(valueClass, ctor, &valueObj, value); + } else if constexpr (std::is_same_v || std::is_same_v || + std::is_same_v || std::is_same_v || + std::is_same_v || std::is_same_v || + std::is_same_v || std::is_same_v) { + status = env->Object_New(valueClass, ctor, &valueObj, static_cast(value)); + } else if constexpr (std::is_same_v) { + status = env->Object_New(valueClass, ctor, &valueObj, static_cast(value)); + } else { + ANS_LOGE("Classname %{public}s Unsupported", propertyName); + return false; + } + if (status != ANI_OK) { + ANS_LOGE("Object_New %{public}s failed %{public}d", propertyName, status); + return false; + } + return CallSetter(env, cls, object, propertyName, valueObj); +} + +[[maybe_unused]]static bool CallSetterNull(ani_env* env, ani_class cls, ani_object &object, const char* propertyName) +{ + ani_ref nullRef = nullptr; + ani_status status = env->GetNull(&nullRef); + if (status != ANI_OK) { + ANS_LOGE("GetNull %{public}s failed %{public}d", propertyName, status); + return false; + } + + return CallSetter(env, cls, object, propertyName, nullRef); +} +} // namespace NotificationSts +} // namespace OHOS +#endif \ No newline at end of file diff --git a/frameworks/ani/notification_manager/include/sts_do_not_disturb_profile.h b/frameworks/ani/notification_manager/include/sts_do_not_disturb_profile.h new file mode 100644 index 0000000000000000000000000000000000000000..d172231f6c80a85c2538f089da87701d0548499b --- /dev/null +++ b/frameworks/ani/notification_manager/include/sts_do_not_disturb_profile.h @@ -0,0 +1,32 @@ +/* + * 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 OHOS_DISTRIBUTED_NOTIFICATION_SERVER_STS_DO_NOT_DISTURB_PROFILE_H + #define OHOS_DISTRIBUTED_NOTIFICATION_SERVER_STS_DO_NOT_DISTURB_PROFILE_H + + #include "ani.h" + #include "notification_do_not_disturb_profile.h" + + namespace OHOS { + namespace NotificationSts { + using namespace OHOS::Notification; + + bool UnwrapDoNotDisturbProfile(ani_env *env, ani_object param, sptr &profile); + [[maybe_unused]]bool UnwrapArrayDoNotDisturbProfile(ani_env *env, ani_object arrayObj, + std::vector> &profiles); + } + } + + #endif // OHOS_DISTRIBUTED_NOTIFICATION_SERVER_STS_DO_NOT_DISTURB_PROFILE_H \ No newline at end of file diff --git a/frameworks/ani/notification_manager/include/sts_notification_action_button.h b/frameworks/ani/notification_manager/include/sts_notification_action_button.h new file mode 100644 index 0000000000000000000000000000000000000000..46f78387e082eb2cd56faa0c197a486375b9dd29 --- /dev/null +++ b/frameworks/ani/notification_manager/include/sts_notification_action_button.h @@ -0,0 +1,45 @@ +/* + * 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 OHOS_DISTRIBUTED_NOTIFICATION_SERVER_STS_NOTIFICATION_ACTION_BUTTON_H +#define OHOS_DISTRIBUTED_NOTIFICATION_SERVER_STS_NOTIFICATION_ACTION_BUTTON_H +#include "pixel_map.h" +#include "want_params.h" +#include "want_agent.h" +#include "notification_constant.h" +#include "notification_user_input.h" + +namespace OHOS { +namespace NotificationSts { +using namespace OHOS::AppExecFwk; +using namespace OHOS::AAFwk; +using SemanticActionButton = OHOS::Notification::NotificationConstant::SemanticActionButton; +using WantAgent = OHOS::AbilityRuntime::WantAgent::WantAgent; +using NotificationUserInput = OHOS::Notification::NotificationUserInput; + +struct StsActionButton { + std::shared_ptr icon; + std::string title; + std::shared_ptr wantAgent; + std::shared_ptr extras = {}; + SemanticActionButton semanticActionButton = SemanticActionButton::NONE_ACTION_BUTTON; + bool autoCreatedReplies = true; + std::vector> mimeTypeOnlyInputs = {}; + std::shared_ptr userInput = {}; + bool isContextual = false; +}; +} +} +#endif //OHOS_DISTRIBUTED_NOTIFICATION_SERVER_STS_ENUM_SLOT_TYPE_H \ No newline at end of file diff --git a/frameworks/ani/notification_manager/include/sts_notification_enum_type.h b/frameworks/ani/notification_manager/include/sts_notification_enum_type.h new file mode 100644 index 0000000000000000000000000000000000000000..abe13758131a146695ad5fd7b42cb9653027fc4a --- /dev/null +++ b/frameworks/ani/notification_manager/include/sts_notification_enum_type.h @@ -0,0 +1,156 @@ +/* + * 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 OHOS_DISTRIBUTED_NOTIFICATION_SERVER_STS_ENUM_SLOT_TYPE_H +#define OHOS_DISTRIBUTED_NOTIFICATION_SERVER_STS_ENUM_SLOT_TYPE_H +#include "sts_common_util.h" +#include "notification_constant.h" +#include "notification_local_live_view_content.h" +#include "notification_live_view_content.h" +#include "notification_content.h" + +using SlotType = OHOS::Notification::NotificationConstant::SlotType; +using LiveViewTypes = OHOS::Notification::NotificationLocalLiveViewContent::LiveViewTypes; +using LiveViewStatus = OHOS::Notification::NotificationLiveViewContent::LiveViewStatus; +using ContentType = OHOS::Notification::NotificationContent::Type; +namespace OHOS { +namespace NotificationSts { +enum STSSlotType { + UNKNOWN_TYPE = 0, + SOCIAL_COMMUNICATION = 1, + SERVICE_INFORMATION = 2, + CONTENT_INFORMATION = 3, + LIVE_VIEW = 4, + CUSTOMER_SERVICE = 5, + EMERGENCY_INFORMATION = 10, + OTHER_TYPES = 0xFFFF, +}; + +enum STSLiveViewStatus { + LIVE_VIEW_CREATE = 0, + LIVE_VIEW_INCREMENTAL_UPDATE = 1, + LIVE_VIEW_END = 2, + LIVE_VIEW_FULL_UPDATE = 3 +}; + +enum STSContentType { + NOTIFICATION_CONTENT_BASIC_TEXT, + NOTIFICATION_CONTENT_LONG_TEXT, + NOTIFICATION_CONTENT_PICTURE, + NOTIFICATION_CONTENT_CONVERSATION, + NOTIFICATION_CONTENT_MULTILINE, + NOTIFICATION_CONTENT_SYSTEM_LIVE_VIEW, + NOTIFICATION_CONTENT_LIVE_VIEW, +}; + +class StsSlotTypeUtils { +public: +static bool StsToC(const STSSlotType inType, SlotType &outType); +static bool CToSts(const SlotType inType, STSSlotType &outType); +}; + +class StsLiveViewStatusUtils { +public: +static bool StsToC(const STSLiveViewStatus inType, LiveViewStatus &outType); +static bool CToSts(const LiveViewStatus inType, STSLiveViewStatus &outType); +}; + +class StsContentTypeUtils { +public: +static bool StsToC(const STSContentType inType, ContentType &outType); +static bool CToSts(const ContentType inType, STSContentType &outType); +}; + +bool SlotTypeEtsToC(ani_env *env, ani_enum_item enumItem, SlotType &slotType); +bool SlotTypeCToEts(ani_env *env, SlotType slotType, ani_enum_item &enumItem); + +bool LiveViewTypesEtsToC(ani_env *env, ani_enum_item enumItem, LiveViewTypes &liveViewTypes); +bool LiveViewTypesCToEts(ani_env *env, LiveViewTypes liveViewTypes, ani_enum_item &enumItem); + +bool LiveViewStatusEtsToC(ani_env *env, ani_enum_item enumItem, LiveViewStatus &liveViewStatus); +bool LiveViewStatusCToEts(ani_env *env, LiveViewStatus liveViewStatus, ani_enum_item &enumItem); + +bool ContentTypeEtsToC(ani_env *env, ani_enum_item enumItem, ContentType &contentType); +bool ContentTypeCToEts(ani_env *env, ContentType contentType, ani_enum_item &enumItem); + +template +static bool EnumConvertAniToNative(ani_env *env, ani_enum_item enumItem, T &result) +{ + ani_status status = ANI_ERROR; + if constexpr (std::is_enum::value || std::is_integral::value) { + ani_int intValue{}; + status = env->EnumItem_GetValue_Int(enumItem, &intValue); + if (ANI_OK != status) { + ANS_LOGD("EnumConvert_StsToNative failed, status : %{public}d", status); + return false; + } + result = static_cast(intValue); + return true; + } else if constexpr (std::is_same::value) { + ani_string strValue{}; + status = env->EnumItem_GetValue_String(enumItem, &strValue); + if (ANI_OK != status) { + ANS_LOGD("EnumItem_GetValue_String failed, status : %{public}d", status); + return false; + } + status = GetStdString(env, strValue, result); + if (ANI_OK != status) { + ANS_LOGD("EnumConvertAniToNative GetStdString failed, status : %{public}d", status); + return false; + } + } else { + ANS_LOGD("Enum convert failed: type not supported"); + return false; + } +} + +template +static bool EnumConvertAniToNative(ani_env *env, ani_object enumItem, T &result) +{ + return EnumConvertAniToNative(env, static_cast(enumItem), result); +} + +template +static bool EnumConvertNativeToAni(ani_env *env, const char *enumName, const T enumValue, ani_enum_item &result) +{ + ani_enum aniEnum{}; + ani_status status = env->FindEnum(enumName, &aniEnum); + if (ANI_OK != status) { + ANS_LOGD("Enum convert FindEnum failed: %{public}s status: %{public}d", enumName, status); + return false; + } + constexpr int32_t loopMaxNum = 1000; + for (int32_t index = 0U; index < loopMaxNum; index++) { + ani_enum_item enumItem{}; + status = env->Enum_GetEnumItemByIndex(aniEnum, index, &enumItem); + if (ANI_OK != status) { + ANS_LOGD( + "Enum_GetEnumItemByIndex failed: enumName:%{public}s index:%{public}d, status:%{public}d", + enumName, index, status); + return false; + } + // compare value + T tmpValue{}; + if (EnumConvertAniToNative(env, enumItem, tmpValue) && tmpValue == enumValue) { + result = enumItem; + return true; + } + } + ANS_LOGD("EnumConvert_NativeToSts failed enumName: %{public}s", enumName); + return false; +} +} +} +#endif //OHOS_DISTRIBUTED_NOTIFICATION_SERVER_STS_ENUM_SLOT_TYPE_H \ No newline at end of file diff --git a/frameworks/ani/notification_manager/include/sts_notification_manager.h b/frameworks/ani/notification_manager/include/sts_notification_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..e24fdb058d38575915f570ede590db966c85e5a5 --- /dev/null +++ b/frameworks/ani/notification_manager/include/sts_notification_manager.h @@ -0,0 +1,24 @@ +/* + * 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 OHOS_DISTRIBUTED_NOTIFICATION_SERVER_NOTIFICATION_MANAGER_H +#define OHOS_DISTRIBUTED_NOTIFICATION_SERVER_NOTIFICATION_MANAGER_H +#include "ani.h" +namespace OHOS { +namespace NotificationManagerSts { +void StsNotificationManagerRegistryInit(ani_env *env); +} +} +#endif \ No newline at end of file diff --git a/frameworks/ani/notification_manager/include/sts_notification_request.h b/frameworks/ani/notification_manager/include/sts_notification_request.h new file mode 100644 index 0000000000000000000000000000000000000000..0e23308d4ea99716e38aa931c6f7923d9b4dd4ac --- /dev/null +++ b/frameworks/ani/notification_manager/include/sts_notification_request.h @@ -0,0 +1,38 @@ +/* + * 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 OHOS_DISTRIBUTED_NOTIFICATION_SERVER_STS_NOTIFICATION_REQUEST_H +#define OHOS_DISTRIBUTED_NOTIFICATION_SERVER_STS_NOTIFICATION_REQUEST_H +#include "ani.h" +#include "notification.h" + + +namespace OHOS { +namespace NotificationSts { +struct StsDistributedOptions { + bool isDistributed = false; + std::vector supportDisplayDevices = {}; + std::vector supportOperateDevices = {}; + int32_t remindType = -1; +}; +ani_object ConvertNotificationToAni(ani_env* env, const OHOS::Notification::Notification *notification); +void UnWarpDistributedOptions(ani_env *env, ani_object obj, StsDistributedOptions distributedOptions); +ani_object ConvertNotificationArrayToAni(ani_env* env, + const std::vector> ¬ifications); +ani_status UnWarpNotificationRequest(ani_env *env, ani_object obj, + std::shared_ptr ¬ificationRequest); +} +} +#endif //OHOS_DISTRIBUTED_NOTIFICATION_SERVER_STS_ENUM_SLOT_TYPE_H \ No newline at end of file diff --git a/frameworks/ani/notification_manager/include/sts_notification_slot.h b/frameworks/ani/notification_manager/include/sts_notification_slot.h new file mode 100644 index 0000000000000000000000000000000000000000..f5c4548360edfc8cf0d640f86420652d373f3374 --- /dev/null +++ b/frameworks/ani/notification_manager/include/sts_notification_slot.h @@ -0,0 +1,30 @@ +/* + * 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 OHOS_DISTRIBUTED_NOTIFICATION_SERVER_STS_NOTIFICATION_SLOT_H +#define OHOS_DISTRIBUTED_NOTIFICATION_SERVER_STS_NOTIFICATION_SLOT_H + +#include "ani.h" +#include "notification_slot.h" + +namespace OHOS { +namespace NotificationSts { + bool WrapNotificationSlot(ani_env *env, sptr slot, ani_object &outAniObj); + + bool WrapNotificationSlotArray(ani_env *env, const std::vector>& slots, ani_object &outAniObj); +} +} + +#endif \ No newline at end of file diff --git a/frameworks/ani/notification_manager/include/sts_notification_utils.h b/frameworks/ani/notification_manager/include/sts_notification_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..1350afd6062be1f55851823b564e533b288a7172 --- /dev/null +++ b/frameworks/ani/notification_manager/include/sts_notification_utils.h @@ -0,0 +1,97 @@ +/* + * 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 OHOS_DISTRIBUTED_NOTIFICATION_SERVER_STS_NOTIFICATION_UTILS_H +#define OHOS_DISTRIBUTED_NOTIFICATION_SERVER_STS_NOTIFICATION_UTILS_H + +#include "ani.h" +#include "notification_action_button.h" +#include "notification_bundle_option.h" +#include "notification_constant.h" +#include "notification_flags.h" +#include "notification_template.h" +#include "notification_user_input.h" +#include "notification_action_button.h" +#include "notification_basic_content.h" +#include "notification_normal_content.h" +#include "notification_long_text_content.h" +#include "notification_multiline_content.h" +#include "notification_picture_content.h" +#include "notification_live_view_content.h" +#include "notification_progress.h" +#include "notification_time.h" +#include "notification_icon_button.h" +#include "notification_local_live_view_button.h" +#include "notification_capsule.h" +#include "notification_local_live_view_content.h" +#include "notification_content.h" +#include "notification_request.h" +#include "notification_unified_group_Info.h" +#include "sts_notification_action_button.h" + +#include "pixel_map.h" + +namespace OHOS { +using namespace Global::Resource; +namespace NotificationSts { +using namespace OHOS::Notification; +using namespace OHOS::Media; + +void UnwrapWantAgent(ani_env *env, ani_object agent, void** result); +std::shared_ptr GetPixelMapFromEnvSp([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object obj); +ani_object CreatePixelMap([[maybe_unused]] ani_env* env, std::shared_ptr pixelMap); +ani_status UnwrapResource(ani_env *env, ani_object obj, ResourceManager::Resource resource); + +ani_status UnwrapNotificationTemplate(ani_env *env, + ani_object aniObj, OHOS::Notification::NotificationTemplate& tmplate); +void UnwrapNotificationFlags(ani_env *env, ani_object aniObj, NotificationFlags& flags); +ani_status UnwrapBundleOption(ani_env *env, ani_object param, NotificationBundleOption& option); +ani_status UnwrapNotificationUserInput(ani_env *env, ani_object param, + std::shared_ptr &userInput); +ani_status UnwrapNotificationActionButton(ani_env *env, ani_object param, StsActionButton &actionButton); +ani_status UnWarpNotificationBasicContent(ani_env *env, ani_object obj, + std::shared_ptr basicContent); +ani_status UnWarpNotificationNormalContent(ani_env *env, ani_object obj, + std::shared_ptr &normalContent); +ani_status UnWarpNotificationLongTextContent(ani_env *env, ani_object obj, + std::shared_ptr &longTextContent); +ani_status UnWarpNotificationMultiLineContent(ani_env *env, ani_object obj, + std::shared_ptr &multiLineContent); +ani_status UnWarpNotificationPictureContent(ani_env *env, ani_object obj, + std::shared_ptr &pictureContent); +ani_status UnWarpNotificationLiveViewContent(ani_env *env, ani_object obj, + std::shared_ptr &liveViewContent); +void UnWarpNotificationProgress(ani_env *env, ani_object obj, + NotificationProgress ¬ificationProgress); +void UnWarpNotificationTime(ani_env *env, ani_object obj, + NotificationTime ¬ificationTime); +ani_status UnWarpNotificationIconButton(ani_env *env, ani_object obj, + NotificationIconButton &iconButton); +void UnWarpNotificationLocalLiveViewButton(ani_env *env, ani_object obj, + NotificationLocalLiveViewButton &iconButton); +void UnWarpNotificationCapsule(ani_env *env, ani_object obj, + NotificationCapsule &iconButton); +ani_status UnWarpNotificationLocalLiveViewContent(ani_env *env, ani_object obj, + std::shared_ptr &localLiveViewContent); +/* NotificationRequest */ +ani_status UnWarpNotificationRequest(ani_env *env, ani_object obj, + std::shared_ptr ¬ificationRequest); + +ani_object WarpNotificationRequest(ani_env *env, std::shared_ptr notificationRequest); +bool SetNotificationRequestByNotificationContent(ani_env* env, ani_class cls, + const OHOS::Notification::NotificationRequest *request, ani_object &object); +} +} +#endif //OHOS_DISTRIBUTED_NOTIFICATION_SERVER_STS_NOTIFICATION_UTILS_H \ No newline at end of file diff --git a/frameworks/ani/notification_manager/src/sts_bundle_option.cpp b/frameworks/ani/notification_manager/src/sts_bundle_option.cpp new file mode 100644 index 0000000000000000000000000000000000000000..abed948bf3c8e5f058076348dd5a3b0306f250b5 --- /dev/null +++ b/frameworks/ani/notification_manager/src/sts_bundle_option.cpp @@ -0,0 +1,104 @@ +/* + * 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 +#include "sts_common_util.h" +#include "ans_log_wrapper.h" + +using namespace OHOS::NotificationSts; +namespace OHOS { +namespace NotificationSts { + +bool UnwrapBundleOption(ani_env *env, ani_object obj, Notification::NotificationBundleOption& option) +{ + ANS_LOGD("WrapBundleOption call"); + ani_ref bundleNameRef; + ani_status status = env->Object_GetPropertyByName_Ref(obj, "bundle", &bundleNameRef); + if (ANI_OK != status) { + ANS_LOGD("WrapBundleOption Object_GetField_Ref bundle fail, status: %{public}d", status); + return false; + } + + std::string bundleName; + if (ANI_OK != (status = GetStdString(env, static_cast(bundleNameRef), bundleName))) { + ANS_LOGD("WrapBundleOption GetStdString failed"); + return false; + } + option.SetBundleName(bundleName); + ANS_LOGD("WrapBundleOption bundleName: %{public}s", bundleName.c_str()); + + ani_ref uidRef; + status = env->Object_GetPropertyByName_Ref(obj, "uid", &uidRef); + if (ANI_OK != status) { + ANS_LOGD("WrapBundleOption Object_GetPropertyByName_Ref uid fail, status: %{public}d", status); + return false; + } + ani_boolean isUndefined = true; + if ((status = env->Reference_IsUndefined(uidRef, &isUndefined)) != ANI_OK) { + ANS_LOGD("WrapBundleOption Object_GetPropertyByName_Ref status : %{public}d", status); + return false; + } + if (isUndefined) { + ANS_LOGD("WrapBundleOption uid is undefined"); + return true; + } + ani_double result = 0.0; + status = env->Object_CallMethodByName_Double(static_cast(uidRef), "doubleValue", nullptr, &result); + if (ANI_OK != status) { + ANS_LOGD("WrapBundleOption Object_CallMethodByName_Double uid fail, status: %{public}d", status); + return false; + } + + int32_t uid = static_cast(result); + + ANS_LOGD("WrapBundleOption bundleName: %{public}s, uid: %{public}d", bundleName.c_str(), uid); + + option.SetUid(uid); + + return true; +} + +bool UnwrapArrayBundleOption(ani_env *env, ani_ref arrayObj, std::vector& options) +{ + ani_status status; + ani_double length; + status = env->Object_GetPropertyByName_Double(static_cast(arrayObj), "length", &length); + if (status != ANI_OK) { + ANS_LOGD("status : %{public}d", status); + return false; + } + + Notification::NotificationBundleOption option; + for (int i = 0; i < static_cast(length); i++) { + ani_ref optionRef; + status = env->Object_CallMethodByName_Ref(static_cast(arrayObj), + "$_get", "I:Lnotification/NotificationCommonDef/BundleOption;", &optionRef, (ani_int)i); + if (status != ANI_OK) { + ANS_LOGD("status : %{public}d, index: %{public}d", status, i); + return false; + } + + if (!UnwrapBundleOption(env, static_cast(optionRef), option)) { + ANS_LOGD("Get oprion failed, index: %{public}d", i); + return false; + } + options.push_back(option); + ANS_LOGD("GetOptions index: %{public}d", i); + } + return true; +} + +} +} \ No newline at end of file diff --git a/frameworks/ani/notification_manager/src/sts_common_util.cpp b/frameworks/ani/notification_manager/src/sts_common_util.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ec01ec102facfeb6e5616b13f465d1d40533828b --- /dev/null +++ b/frameworks/ani/notification_manager/src/sts_common_util.cpp @@ -0,0 +1,489 @@ +/* + * 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 +#include "sts_common_util.h" +#include "ans_log_wrapper.h" +#include "securec.h" +#include "sts_notification_enum_type.h" +#include "ans_inner_errors.h" + +using namespace OHOS::Notification; +namespace OHOS { +namespace NotificationSts { + +static const std::unordered_map ERROR_CODE_TO_MESSAGE { + {ERROR_PERMISSION_DENIED, "Permission denied"}, + {ERROR_NOT_SYSTEM_APP, "The application isn't system application"}, + {ERROR_PARAM_INVALID, "Invalid parameter"}, + {ERROR_SYSTEM_CAP_ERROR, "SystemCapability not found"}, + {ERROR_INTERNAL_ERROR, "Internal error"}, + {ERROR_IPC_ERROR, "Marshalling or unmarshalling error"}, + {ERROR_SERVICE_CONNECT_ERROR, "Failed to connect to the service"}, + {ERROR_NOTIFICATION_CLOSED, "Notification disabled"}, + {ERROR_SLOT_CLOSED, "Notification slot disabled"}, + {ERROR_NOTIFICATION_UNREMOVABLE, "Notification deletion disabled"}, + {ERROR_NOTIFICATION_NOT_EXIST, "The notification does not exist"}, + {ERROR_USER_NOT_EXIST, "The user does not exist"}, + {ERROR_OVER_MAX_NUM_PER_SECOND, "The notification sending frequency reaches the upper limit"}, + {ERROR_DISTRIBUTED_OPERATION_FAILED, "Distributed operation failed"}, + {ERROR_READ_TEMPLATE_CONFIG_FAILED, "Failed to read the template configuration"}, + {ERROR_NO_MEMORY, "No memory space"}, + {ERROR_BUNDLE_NOT_FOUND, "The specified bundle name was not found"}, + {ERROR_NO_AGENT_SETTING, "There is no corresponding agent relationship configuration"}, + {ERROR_DIALOG_IS_POPPING, "Dialog is popping"}, + {ERROR_SETTING_WINDOW_EXIST, "The notification settings window is already displayed"}, + {ERROR_NO_PROFILE_TEMPLATE, "Not exit noNotDisturb profile template"}, + {ERROR_REPEAT_SET, "Repeat create or end"}, + {ERROR_NO_RIGHT, "No permission"}, + {ERROR_EXPIRED_NOTIFICATION, "Low update version"}, + {ERROR_NETWORK_UNREACHABLE, "Network unreachable"}, + {ERROR_REJECTED_WITH_DISABLE_NOTIFICATION, + "The application is not allowed to publish notifications due to permission control settings"}, + {ERROR_DISTRIBUTED_OPERATION_TIMEOUT, "Distributed operation timeout"}, +}; + +constexpr const char* CLASSNAME_BOOLEAN = "Lstd/core/Boolean;"; +constexpr const char* CLASSNAME_DOUBLE = "Lstd/core/Double;"; + +bool GetAniString(ani_env* env, const std::string str, ani_string& aniStr) +{ + ani_status status = env->String_NewUTF8(str.c_str(), str.size(), &aniStr); + if (status != ANI_OK) { + ANS_LOGE("String_NewUTF8 failed %{public}d", status); + return false; + } + return true; +} + +ani_string GetAniString(ani_env* env, const std::string str) +{ + ani_string aniStr; + ani_status status = env->String_NewUTF8(str.c_str(), str.size(), &aniStr); + if (status != ANI_OK) { + ANS_LOGE("String_NewUTF8 failed %{public}d", status); + return nullptr; + } + return aniStr; +} + +ani_status GetStdString(ani_env *env, ani_string str, std::string &res) +{ + ani_size sz {}; + ani_status status = ANI_ERROR; + if ((status = env->String_GetUTF8Size(str, &sz)) != ANI_OK) { + ANS_LOGD("status : %{public}d", status); + return status; + } + res.resize(sz + 1); + if ((status = env->String_GetUTF8SubString(str, 0, sz, res.data(), res.size(), &sz)) != ANI_OK) { + ANS_LOGD("status : %{public}d", status); + return status; + } + res.resize(sz); + return status; +} + +ani_status GetPropertyRef(ani_env *env, ani_object obj, const char *name, ani_ref &ref, ani_boolean &isUndefined) +{ + ani_status status = env->Object_GetPropertyByName_Ref(obj, name, &ref); + if (status != ANI_OK) { + ANS_LOGI("Failed to get property '%{public}s', status: %{public}d", name, status); + return status; + } + status = env->Reference_IsUndefined(ref, &isUndefined); + if (status != ANI_OK) { + ANS_LOGI("Failed to check undefined for '%{public}s', status: %{public}d", name, status); + } + return status; +} + +ani_status GetPropertyString(ani_env *env, ani_object obj, const char *name, + ani_boolean &isUndefined, std::string &outStr) +{ + ani_status status = ANI_ERROR; + ani_ref strRef; + if ((status =env->Object_GetPropertyByName_Ref(obj, name, &strRef)) != ANI_OK) { + ANS_LOGD("Object_GetField_Ref bundle fail, status: %{public}d", status); + return status; + } + status = env->Reference_IsUndefined(strRef, &isUndefined); + if (status != ANI_OK) { + ANS_LOGI("Failed to check undefined for '%{public}s', status: %{public}d", name, status); + return status; + } + if(isUndefined == ANI_TRUE) { + return status; + } + std::string result = ""; + if ((status = GetStdString(env, reinterpret_cast(strRef), result)) != ANI_OK) { + ANS_LOGD("GetStdString failed"); + return status; + } + outStr = result; + return status; +} + +ani_status GetStringArrayOrUndefined(ani_env *env, ani_object param, const char *name, + ani_boolean &isUndefined, std::vector &res) +{ + ani_ref arrayObj = nullptr; + ani_status status; + ani_double length; + std::string str; + + if ((status = env->Object_GetFieldByName_Ref(param, name, &arrayObj)) != ANI_OK) { + ANS_LOGI("status : %{public}d", status); + return status; + } + if ((status = env->Reference_IsUndefined(arrayObj, &isUndefined)) != ANI_OK) { + ANS_LOGI("status : %{public}d", status); + return status; + } + if (isUndefined) { + ANS_LOGI("%{public}s : undefined", name); + return status; + } + + status = env->Object_GetPropertyByName_Double(static_cast(arrayObj), "length", &length); + if (status != ANI_OK) { + ANS_LOGI("status : %{public}d", status); + return status; + } + + for (int i = 0; i < static_cast(length); i++) { + ani_ref stringEntryRef; + status = env->Object_CallMethodByName_Ref(static_cast(arrayObj), + "$_get", "I:Lstd/core/Object;", &stringEntryRef, (ani_int)i); + if (status != ANI_OK) { + ANS_LOGI("status : %{public}d, index: %{public}d", status, i); + return status; + } + + str = ""; + status = GetStdString(env, static_cast(stringEntryRef), str); + if (status != ANI_OK) { + ANS_LOGI("GetStdString failed, index: %{public}d", i); + return status; + } + + res.push_back(str); + ANS_LOGI("GetStdString index: %{public}d %{public}s", i, str.c_str()); + } + return status; +} + +ani_status GetPropertyBooleanOrUndefined(ani_env *env, ani_object aniObj, const char *name, + ani_boolean isUndefined, bool outvalue) +{ + ani_ref refObj = nullptr; + ani_status status = ANI_ERROR; + ani_boolean res = ANI_FALSE; + if (((status = GetPropertyRef(env, aniObj, name, refObj, isUndefined)) != ANI_OK) && (isUndefined == ANI_TRUE)) { + ANS_LOGI("GetPropertyRef failed or %{public}s : undefined", name); + return ANI_INVALID_ARGS; + } + if ((status = env->Object_CallMethodByName_Boolean(static_cast(refObj), + "unboxed", ":Z", &res)) != ANI_OK) { + ANS_LOGI("Object_CallMethodByName_Boolean failed, status : %{public}d", status); + return status; + } + outvalue = (res == ANI_TRUE); + return status; +} + +ani_status GetPropertyDoubleOrUndefined(ani_env *env, ani_object obj, const char *name, + ani_boolean &isUndefined, ani_double &outvalue) +{ + ani_status status = ANI_ERROR; + ani_ref uidRef; + if ((status = env->Object_GetPropertyByName_Ref(obj, name, &uidRef)) != ANI_OK) { + ANS_LOGI("Object_GetPropertyByName_Ref uid fail, status: %{public}d", status); + return status; + } + if ((status = env->Reference_IsUndefined(uidRef, &isUndefined)) == ANI_OK) { + ANS_LOGI("Object_GetPropertyByName_Ref status : %{public}d", status); + return status; + } + if (isUndefined) { + ANS_LOGI("%{public}s is undefined", name); + return ANI_INVALID_ARGS; + } + ani_double result = 0.0; + status = env->Object_CallMethodByName_Double(static_cast(uidRef), "doubleValue", nullptr, &result); + if (ANI_OK != status) { + ANS_LOGI("Object_CallMethodByName_Double uid fail, status: %{public}d", status); + return status; + } + outvalue = result; + return status; +} + +bool CreateClassObjByClassName(ani_env *env, const char *className, ani_class &cls, ani_object &outAniObj) +{ + ANI_FAILED_AND_RETURN(env->FindClass(className, &cls)); + ani_method ctor; + ANI_FAILED_AND_RETURN(env->Class_FindMethod(cls, "", nullptr, &ctor)); + outAniObj = {}; + ANI_FAILED_AND_RETURN(env->Object_New(cls, ctor, &outAniObj)); + return true; +} + +bool SetFieldString(ani_env *env, ani_class cls, ani_object object, const std::string &fieldName, const std::string &value) +{ + ani_field field = nullptr; + ani_string string = nullptr; + ani_status status = env->Class_FindField(cls, fieldName.c_str(), &field); + + ANS_LOGD("SetFieldString fieldName : %{public}s", fieldName.c_str()); + + if (status != ANI_OK) { + ANS_LOGE("SetFieldString status : %{public}d", status); + return false; + } + + if (value.empty()) { + ani_ref nullRef = nullptr; + if ((status = env->GetNull(&nullRef)) != ANI_OK) { + ANS_LOGE("SetFieldString GetNull fail status : %{public}d", status); + return false; + } + if ((status = env->Object_SetField_Ref(object, field, nullRef)) != ANI_OK) { + ANS_LOGE("SetFieldString Object_SetField_Ref fail status : %{public}d", status); + return false; + } + return true; + } + + if ((status = env->String_NewUTF8(value.c_str(), value.size(), &string)) != ANI_OK) { + ANS_LOGE("SetFieldString String_NewUTF8 fail status : %{public}d", status); + return false; + } + + if ((status = env->Object_SetField_Ref(object, field, string)) != ANI_OK) { + ANS_LOGE("SetFieldString Object_SetField_Ref fail status : %{public}d", status); + return false; + } + return true; +} + +ani_object newArrayClass(ani_env *env, int length) +{ + ANS_LOGD("newArrayClass call"); + ani_class arrayCls = nullptr; + if (ANI_OK != env->FindClass("Lescompat/Array;", &arrayCls)){ + ANS_LOGE("FindClass Lescompat/Array; Failed"); + return nullptr; + } + ani_method arrayCtor; + if(ANI_OK != env->Class_FindMethod(arrayCls, "", "I:V", &arrayCtor)){ + ANS_LOGE("Class_FindMethod Failed"); + return nullptr; + } + ani_object arrayObj = nullptr; + if(ANI_OK != env->Object_New(arrayCls, arrayCtor, &arrayObj, length)){ + ANS_LOGE("Object_New Array Faild"); + return arrayObj; + } + ANS_LOGD("newArrayClass end"); + return arrayObj; +} + +ani_object createBoolean(ani_env *env, ani_boolean value) +{ + ani_class persion_cls; + ani_status status = ANI_ERROR; + if ((status = env->FindClass(CLASSNAME_BOOLEAN, &persion_cls)) != ANI_OK) { + ANS_LOGE("status : %{public}d", status); + return nullptr; + } + ani_method personInfoCtor; + if ((status = env->Class_FindMethod(persion_cls, "", "Z:V", &personInfoCtor)) != ANI_OK) { + ANS_LOGE("status : %{public}d", status); + return nullptr; + } + ani_object personInfoObj; + if ((status = env->Object_New(persion_cls, personInfoCtor, &personInfoObj, value)) != ANI_OK) { + ANS_LOGE("status : %{public}d", status); + return nullptr; + } + return personInfoObj; +} + +ani_object createDouble(ani_env *env, ani_double value) +{ + ani_class persion_cls; + ani_status status = ANI_ERROR; + if ((status = env->FindClass(CLASSNAME_DOUBLE, &persion_cls)) != ANI_OK) { + ANS_LOGE( "status : %{public}d", status); + return nullptr; + } + ani_method personInfoCtor; + if ((status = env->Class_FindMethod(persion_cls, "", "D:V", &personInfoCtor)) != ANI_OK) { + ANS_LOGE("status : %{public}d", status); + return nullptr; + } + ani_object personInfoObj; + if ((status = env->Object_New(persion_cls, personInfoCtor, &personInfoObj, value)) != ANI_OK) { + ANS_LOGE("status : %{public}d", status); + return nullptr; + } + return personInfoObj; +} + +bool SetOptionalFieldBoolean(ani_env *env, ani_class cls, ani_object object, const std::string &fieldName, bool value) +{ + ani_field field = nullptr; + ani_status status = env->Class_FindField(cls, fieldName.c_str(), &field); + if (status != ANI_OK || field == nullptr) { + ANS_LOGE("Class_FindField failed or null field, status=%{public}d, fieldName=%{public}s", + status, fieldName.c_str()); + return false; + } + ani_object intObj = createBoolean(env, BoolToAniBoolean(value)); + if (intObj == nullptr) { + ANS_LOGE("null intObj"); + return false; + } + status = env->Object_SetField_Ref(object, field, intObj); + if (status != ANI_OK) { + ANS_LOGE("Object_SetField_Ref failed, status=%{public}d, fieldName=%{public}s", + status, fieldName.c_str()); + return false; + } + return true; +} + +bool SetOptionalFieldDouble(ani_env *env, ani_class cls, ani_object object, const std::string &fieldName, double value) +{ + ani_field field = nullptr; + ani_status status = env->Class_FindField(cls, fieldName.c_str(), &field); + if (status != ANI_OK || field == nullptr) { + ANS_LOGE("Class_FindField failed or null field, status=%{public}d, fieldName=%{public}s", + status, fieldName.c_str()); + return false; + } + ani_object intObj = createDouble(env, value); + if (intObj == nullptr) { + ANS_LOGE("null intObj"); + return false; + } + status = env->Object_SetField_Ref(object, field, intObj); + if (status != ANI_OK) { + ANS_LOGE("Object_SetField_Ref failed, status=%{public}d, fieldName=%{public}s", + status, fieldName.c_str()); + return false; + } + return true; +} + +bool SetOptionalFieldArrayDouble(ani_env *env, ani_class cls, ani_object object, const std::string &fieldName, + const std::vector &values) +{ + ani_field field = nullptr; + ani_class arrayCls = nullptr; + ani_method arrayCtor; + ani_object arrayObj; + + ani_status status = env->Class_FindField(cls, fieldName.c_str(), &field); + if (status != ANI_OK) { + ANS_LOGE("status : %{public}d", status); + return false; + } + + status = env->FindClass("Lescompat/Array;", &arrayCls); + if (status != ANI_OK) { + ANS_LOGE("status : %{public}d", status); + return false; + } + + status = env->Class_FindMethod(arrayCls, "", "I:V", &arrayCtor); + if (status != ANI_OK) { + ANS_LOGE("status : %{public}d", status); + return false; + } + + status = env->Object_New(arrayCls, arrayCtor, &arrayObj, values.size()); + if (status != ANI_OK) { + ANS_LOGE("status : %{public}d", status); + return false; + } + + for (size_t i = 0; i < values.size(); i++) { + ani_field field_1 = nullptr; + ani_status status = env->Class_FindField(cls, fieldName.c_str(), &field_1); + if (status != ANI_OK || field_1 == nullptr) { + ANS_LOGE("Class_FindField failed or null field, status=%{public}d, fieldName=%{public}s", + status, fieldName.c_str()); + return false; + } + ani_object intObj = createDouble(env, static_cast(values[i])); + if (intObj == nullptr) { + ANS_LOGE("null intObj"); + return false; + } + status = env->Object_CallMethodByName_Void(arrayObj, "$_set", "ILstd/core/Object;:V", i, intObj); + if (status != ANI_OK) { + ANS_LOGE("status : %{public}d", status); + return false; + } + } + status = env->Object_SetField_Ref(object, field, arrayObj); + if (status != ANI_OK) { + ANS_LOGE("status : %{public}d", status); + return false; + } + + return true; +} + +bool SetOptionalFieldSlotType(ani_env *env, ani_class cls, ani_object object, const std::string &fieldName, + const Notification::NotificationConstant::SlotType& value) +{ + ani_field field = nullptr; + ani_status status = env->Class_FindField(cls, fieldName.c_str(), &field); + if (status != ANI_OK || field == nullptr) { + ANS_LOGE("Class_FindField failed or null field, status=%{public}d, fieldName=%{public}s", + status, fieldName.c_str()); + return false; + } + ani_enum_item enumItem = nullptr; + NotificationSts::SlotTypeCToEts(env, value, enumItem); + if (enumItem == nullptr) + { + ANS_LOGE("null enumItem"); + return false; + } + + status = env->Object_SetField_Ref(object, field, enumItem); + if (status != ANI_OK) { + ANS_LOGE("Object_SetField_Ref failed, status=%{public}d, fieldName=%{public}s", + status, fieldName.c_str()); + return false; + } + return true; +} + +std::string FindAnsErrMsg(const int32_t errCode) +{ + auto findMsg = ERROR_CODE_TO_MESSAGE.find(errCode); + if (findMsg == ERROR_CODE_TO_MESSAGE.end()) { + ANSR_LOGI("FindAnsErrMsg Inner error."); + return "Inner error."; + } + return findMsg->second; +} + +} +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/ani/notification_manager/src/sts_do_not_disturb_profile.cpp b/frameworks/ani/notification_manager/src/sts_do_not_disturb_profile.cpp new file mode 100644 index 0000000000000000000000000000000000000000..52472b816b1010293bf60c325bb345f85d2dc9c0 --- /dev/null +++ b/frameworks/ani/notification_manager/src/sts_do_not_disturb_profile.cpp @@ -0,0 +1,101 @@ +/* + * 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 "sts_do_not_disturb_profile.h" +#include "sts_bundle_option.h" +#include "sts_common_util.h" +#include "ans_log_wrapper.h" + +using namespace OHOS::NotificationSts; +namespace OHOS { +namespace NotificationSts { +bool UnwrapDoNotDisturbProfile(ani_env *env, ani_object param, sptr &profile) +{ + ANS_LOGD("UnwrapDoNotDisturbProfile call"); + ani_long idRef; + ani_status status = env->Object_GetPropertyByName_Long(param, "id", &idRef); + if (ANI_OK != status) { + ANS_LOGD("WrapBundleOption Object_GetField_Ref bundle fail, status: %{public}d", status); + return false; + } + ani_ref nameRef; + status = env->Object_GetPropertyByName_Ref(param, "name", &nameRef); + if (ANI_OK != status) { + ANS_LOGD("WrapBundleOption Object_GetField_Ref bundle fail, status: %{public}d", status); + return false; + } + std::string name; + if (ANI_OK != (status = GetStdString(env, reinterpret_cast(nameRef), name))) { + ANS_LOGD("WrapBundleOption GetStdString failed"); + return false; + } + profile->SetProfileId(static_cast(idRef)); + profile->SetProfileName(name); + + ani_ref trustlistRef; + status = env->Object_GetPropertyByName_Ref(param, "trustlist", &trustlistRef); + if (ANI_OK != status) { + ANS_LOGD("UnwrapDoNotDisturbProfile Object_GetPropertyByName_Ref trustlist fail, status: %{public}d", status); + return true; + } + ani_boolean isUndefined = true; + if ((status = env->Reference_IsUndefined(trustlistRef, &isUndefined)) != ANI_OK) { + ANS_LOGD("UnwrapDoNotDisturbProfile Object_GetPropertyByName_Ref status : %{public}d", status); + return true; + } + if (isUndefined) { + ANS_LOGD("UnwrapDoNotDisturbProfile trustlist is undefined"); + return true; + } + std::vector trustlist = {}; + UnwrapArrayBundleOption(env, static_cast(trustlistRef), trustlist); + if (trustlist.size() > 0) { + profile->SetProfileTrustList(trustlist); + } + return true; +} + +bool UnwrapArrayDoNotDisturbProfile(ani_env *env, ani_object arrayObj, + std::vector> &profiles) +{ + ani_status status; + ani_double length; + + status = env->Object_GetPropertyByName_Double(arrayObj, "length", &length); + if (status != ANI_OK) { + ANS_LOGD("status : %{public}d", status); + return false; + } + + sptr profile; + for (int i = 0; i < static_cast(length); i++) { + ani_ref optionRef; + status = env->Object_CallMethodByName_Ref(arrayObj, "$_get", + "I:L@ohos/notificationManager/notificationManager/DoNotDisturbProfile;", &optionRef, (ani_int)i); + if (status != ANI_OK) { + ANS_LOGD("status : %{public}d, index: %{public}d", status, i); + return false; + } + + if (!UnwrapDoNotDisturbProfile(env, static_cast(optionRef), profile)) { + ANS_LOGD("Get profile failed, index: %{public}d", i); + return false; + } + profiles.push_back(profile); + ANS_LOGD("GetProfiles index: %{public}d", i); + } + return true; +} +} +} \ No newline at end of file diff --git a/frameworks/ani/notification_manager/src/sts_notification_action_button.cpp b/frameworks/ani/notification_manager/src/sts_notification_action_button.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2242deeebc7d915b50d0a8a0ce0789dce3fad696 --- /dev/null +++ b/frameworks/ani/notification_manager/src/sts_notification_action_button.cpp @@ -0,0 +1,87 @@ +/* + * 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 "sts_notification_utils.h" +#include "sts_notification_action_button.h" +#include "sts_common_util.h" +#include "ani_common_want.h" +#include "want_params.h" +#include "want_agent.h" + +namespace OHOS { +namespace NotificationSts { +using namespace OHOS::AppExecFwk; +using namespace OHOS::AAFwk; +using WantAgent = OHOS::AbilityRuntime::WantAgent::WantAgent; + +ani_status UnwrapNotificationActionButton(ani_env *env, ani_object param, + StsActionButton &actionButton) +{ + ani_status status = ANI_ERROR; + ani_boolean isUndefind = ANI_TRUE; + std::string title; + if((status = GetPropertyString(env, param, "title", isUndefind, title)) != ANI_OK || isUndefind == ANI_TRUE) { + return ANI_INVALID_ARGS; + } + ani_ref wantAgentRef; + if ((status = env->Object_GetPropertyByName_Ref(param, "wantAgent", &wantAgentRef)) != ANI_OK) { + return status; + } + WantAgent* pWantAgent = nullptr; + UnwrapWantAgent(env, static_cast(wantAgentRef), reinterpret_cast(&pWantAgent)); + if (pWantAgent == nullptr) { + return ANI_INVALID_ARGS; + } + + std::shared_ptr wantAgent = std::make_shared(*pWantAgent); + + ani_ref extrasRef; + if (ANI_OK != (status = env->Object_GetPropertyByName_Ref(param, "extras", &extrasRef))) { + return status; + } + isUndefind = ANI_TRUE; + WantParams wantParams = {}; + if ((status = env->Reference_IsUndefined(extrasRef, &isUndefind)) == ANI_OK && isUndefind == ANI_FALSE) { + UnwrapWantParams(env, extrasRef, wantParams); + } + std::shared_ptr extras = std::make_shared(wantParams); + + std::shared_ptr userInput = nullptr; + ani_ref userInputRef; + if (ANI_OK == env->Object_GetPropertyByName_Ref(param, "userInput", &userInputRef)) + { + isUndefind = ANI_TRUE; + if (env->Reference_IsUndefined(userInputRef, &isUndefind) == ANI_OK && isUndefind == ANI_FALSE) + { + UnwrapNotificationUserInput(env, static_cast(userInputRef), userInput); + } + if (userInput == nullptr) + { + userInput = {}; + } + } + actionButton.icon = nullptr; + actionButton.title = title; + actionButton.wantAgent = wantAgent; + actionButton.extras = extras; + actionButton.semanticActionButton = SemanticActionButton::NONE_ACTION_BUTTON; + actionButton.autoCreatedReplies = true; + actionButton.mimeTypeOnlyInputs = {}; + actionButton.userInput = userInput; + actionButton.isContextual = false; + return status; +} +} +} \ No newline at end of file diff --git a/frameworks/ani/notification_manager/src/sts_notification_content.cpp b/frameworks/ani/notification_manager/src/sts_notification_content.cpp new file mode 100644 index 0000000000000000000000000000000000000000..00e42f8ba9ae371a21822800c0963d153b948fe6 --- /dev/null +++ b/frameworks/ani/notification_manager/src/sts_notification_content.cpp @@ -0,0 +1,1360 @@ +/* + * 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 "ani_common_want.h" +#include "ans_log_wrapper.h" +#include "pixel_map_ani.h" +#include "sts_common_util.h" +#include "sts_notification_enum_type.h" +#include "sts_notification_utils.h" +#include "want_params.h" +#include "ani_common_want_agent.h" + +namespace OHOS { +namespace NotificationSts { +using namespace OHOS::AppExecFwk; +using namespace OHOS::AAFwk; +using LiveViewStatus = OHOS::Notification::NotificationLiveViewContent::LiveViewStatus; + +void UnWarpNotificationProgress(ani_env *env, ani_object obj, + NotificationProgress ¬ificationProgress) +{ + ani_double maxValueAni = 0.0; + ani_boolean isUndefined = ANI_TRUE; + if(GetPropertyDoubleOrUndefined(env, obj, "maxValue", isUndefined, maxValueAni) == ANI_OK + && isUndefined == ANI_FALSE) { + notificationProgress.SetMaxValue(static_cast(maxValueAni)); + } + ani_double currentValueAni = 0.0; + if(GetPropertyDoubleOrUndefined(env, obj, "currentValue", isUndefined, currentValueAni) == ANI_OK + && isUndefined == ANI_FALSE) { + notificationProgress.SetCurrentValue(static_cast(currentValueAni)); + } + + bool isPercentage = true; + isUndefined = ANI_TRUE; + if(ANI_OK == GetPropertyBooleanOrUndefined(env, obj, "isPercentage", isUndefined, isPercentage) + && isUndefined == ANI_FALSE) { + notificationProgress.SetIsPercentage(isPercentage); + } +} + +void UnWarpNotificationTime(ani_env *env, ani_object obj, + NotificationTime ¬ificationTime) +{ + ani_boolean isUndefined = ANI_TRUE; + ani_double initialTime = 0.0; + if (GetPropertyDoubleOrUndefined(env, obj, "version", isUndefined, initialTime) == ANI_OK + && isUndefined == ANI_FALSE) { + notificationTime.SetInitialTime(static_cast(initialTime)); + } + + bool isCountDown = true; + isUndefined = ANI_TRUE; + if(ANI_OK == GetPropertyBooleanOrUndefined(env, obj, "isCountDown", isUndefined, isCountDown) + && isUndefined == ANI_FALSE) { + notificationTime.SetIsCountDown(isCountDown); + } + + bool isPaused = true; + isUndefined = ANI_TRUE; + if(ANI_OK == GetPropertyBooleanOrUndefined(env, obj, "isPaused", isUndefined, isPaused) + && isUndefined == ANI_FALSE) { + notificationTime.SetIsPaused(isPaused); + } + + bool isInTitle = true; + isUndefined = ANI_TRUE; + if(ANI_OK == GetPropertyBooleanOrUndefined(env, obj, "isInTitle", isUndefined, isInTitle) + && isUndefined == ANI_FALSE) { + notificationTime.SetIsInTitle(isInTitle); + } +} + +ani_status UnWarpNotificationIconButton(ani_env *env, ani_object obj, + NotificationIconButton &iconButton) +{ + ani_status status = ANI_ERROR; + ani_boolean isUndefined = ANI_TRUE; + std::string name = ""; + if((status = GetPropertyString(env, obj, "name", isUndefined, name)) != ANI_OK || isUndefined == ANI_TRUE) { + return ANI_INVALID_ARGS; + } + iconButton.SetName(name); + + ani_ref iconRef = {}; + if ((status = env->Object_GetPropertyByName_Ref(obj, "iconResource", &iconRef)) != ANI_OK) { + return status; + } + + ResourceManager::Resource resource; + if(ANI_OK == UnwrapResource(env, static_cast(iconRef), resource)) { + iconButton.SetIconResource(std::make_shared(resource)); + } else { + std::shared_ptr pixelMap = GetPixelMapFromEnvSp(env, static_cast(iconRef)); + if (pixelMap != nullptr) { + iconButton.SetIconImage(pixelMap); + } + } + + std::string text = ""; + isUndefined = ANI_TRUE; + if(GetPropertyString(env, obj, "text", isUndefined, text) == ANI_OK && isUndefined == ANI_FALSE) { + iconButton.SetName(text); + } + + bool hidePanel = true; + isUndefined = ANI_TRUE; + if(ANI_OK == GetPropertyBooleanOrUndefined(env, obj, "hidePanel", isUndefined, hidePanel) + && isUndefined == ANI_FALSE) { + iconButton.SetHidePanel(hidePanel); + } + + return status; +} + +ani_status GetIconButtonArrayOrUndefined(ani_env *env, + ani_object param, const char *name, std::vector &res) +{ + ani_ref arrayObj = nullptr; + ani_boolean isUndefined = true; + ani_status status; + ani_double length; + + if ((status = env->Object_GetFieldByName_Ref(param, name, &arrayObj)) != ANI_OK) { + ANS_LOGI("status : %{public}d", status); + return status; + } + if ((status = env->Reference_IsUndefined(arrayObj, &isUndefined)) != ANI_OK) { + ANS_LOGI("status : %{public}d", status); + return status; + } + if (isUndefined) { + ANS_LOGI("%{public}s : undefined", name); + return status; + } + + status = env->Object_GetPropertyByName_Double(static_cast(arrayObj), "length", &length); + if (status != ANI_OK) { + ANS_LOGI("status : %{public}d", status); + return status; + } + + for (int i = 0; i < static_cast(length); i++) { + ani_ref buttonRef; + status = env->Object_CallMethodByName_Ref(static_cast(arrayObj), + "$_get", "I:Lstd/core/Object;", &buttonRef, (ani_int)i); + if (status != ANI_OK) { + ANS_LOGI("status : %{public}d, index: %{public}d", status, i); + return status; + } + + NotificationIconButton button; + if(UnWarpNotificationIconButton(env, static_cast(buttonRef), button) == ANI_OK) { + res.push_back(button); + } + } + return status; +} + +ani_status GetPixelMapArrayByRef(ani_env *env, ani_ref param, std::vector> &pixelMaps) +{ + ani_status status = ANI_ERROR; + ani_double length; + status = env->Object_GetPropertyByName_Double(static_cast(param), "length", &length); + if (status != ANI_OK) { + ANS_LOGI("status : %{public}d", status); + return status; + } + + for (int i = 0; i < static_cast(length); i++) { + ani_ref pixelMapRef; + status = env->Object_CallMethodByName_Ref(static_cast(param), + "$_get", "I:Lstd/core/Object;", &pixelMapRef, (ani_int)i); + if (status != ANI_OK) { + ANS_LOGI("status : %{public}d, index: %{public}d", status, i); + return status; + } + + std::shared_ptr pixelMap = GetPixelMapFromEnvSp(env, static_cast(pixelMapRef)); + if (pixelMap == nullptr) { + return ANI_INVALID_ARGS; + } + pixelMaps.push_back(pixelMap); + } + return status; +} + +ani_status GetPixelMapArrayOrUndefined(ani_env *env, + ani_object param, const char *name, std::vector> &pixelMaps) +{ + ani_ref arrayObj = nullptr; + ani_boolean isUndefined = true; + ani_status status; + + if ((status = env->Object_GetFieldByName_Ref(param, name, &arrayObj)) != ANI_OK) { + ANS_LOGI("status : %{public}d", status); + return status; + } + if ((status = env->Reference_IsUndefined(arrayObj, &isUndefined)) != ANI_OK) { + ANS_LOGI("status : %{public}d", status); + return status; + } + if (isUndefined) { + ANS_LOGI("%{public}s : undefined", name); + return status; + } + if((status = GetPixelMapArrayByRef(env, arrayObj, pixelMaps)) != ANI_OK) { + return status; + } + return status; +} + +ani_status GetResourceArrayOrUndefined(ani_env *env, + ani_object param, const char *name, std::vector &res) +{ + ani_ref arrayObj = nullptr; + ani_boolean isUndefined = true; + ani_status status; + ani_double length; + + if ((status = env->Object_GetFieldByName_Ref(param, name, &arrayObj)) != ANI_OK) { + ANS_LOGI("status : %{public}d", status); + return status; + } + if ((status = env->Reference_IsUndefined(arrayObj, &isUndefined)) != ANI_OK) { + ANS_LOGI("status : %{public}d", status); + return status; + } + if (isUndefined) { + ANS_LOGI("%{public}s : undefined", name); + return status; + } + + status = env->Object_GetPropertyByName_Double(static_cast(arrayObj), "length", &length); + if (status != ANI_OK) { + ANS_LOGI("status : %{public}d", status); + return status; + } + + for (int i = 0; i < static_cast(length); i++) { + ani_ref iconRef; + status = env->Object_CallMethodByName_Ref(static_cast(arrayObj), + "$_get", "I:Lstd/core/Object;", &iconRef, (ani_int)i); + if (status != ANI_OK) { + ANS_LOGI("status : %{public}d, index: %{public}d", status, i); + return status; + } + + ResourceManager::Resource resource; + if(ANI_OK != UnwrapResource(env, static_cast(iconRef), resource)) { + ANS_LOGI("status : %{public}d, index: %{public}d", status, i); + return status; + } + res.push_back(resource); + } + return status; +} + +void UnWarpNotificationLocalLiveViewButton(ani_env *env, ani_object obj, + NotificationLocalLiveViewButton &button) +{ + std::vector names = {}; + ani_boolean isUndefined = ANI_TRUE; + if(GetStringArrayOrUndefined(env, obj, "names", isUndefined, names) == ANI_OK && isUndefined == ANI_FALSE) { + for(auto name: names) { + button.addSingleButtonName(name); + } + } + + std::vector> icons = {}; + if(ANI_OK == GetPixelMapArrayOrUndefined(env, obj, "icons", icons)) { + for(auto icon: icons) { + button.addSingleButtonIcon(icon); + } + } + std::vector resources = {}; + if(ANI_OK == GetResourceArrayOrUndefined(env, obj, "iconsResource", resources)) { + for(auto res: resources) { + std::shared_ptr pRes = std::make_shared(res); + button.addSingleButtonIconResource(pRes); + } + } +} + +void UnWarpNotificationCapsule(ani_env *env, ani_object obj, + NotificationCapsule &capsule) +{ + ani_boolean isUndefined = ANI_TRUE; + std::string title = ""; + if(GetPropertyString(env, obj, "title", isUndefined, title) == ANI_OK && isUndefined == ANI_FALSE) { + capsule.SetTitle(title); + } + + std::string backgroundColor = ""; + isUndefined = ANI_TRUE; + if(GetPropertyString(env, obj, "backgroundColor", isUndefined, backgroundColor) == ANI_OK + && isUndefined == ANI_FALSE) { + capsule.SetBackgroundColor(backgroundColor); + } + + std::string content = ""; + isUndefined = ANI_TRUE; + if(GetPropertyString(env, obj, "content", isUndefined, content) == ANI_OK && isUndefined == ANI_FALSE) { + capsule.SetContent(content); + } + + ani_double time = 0.0; + if(GetPropertyDoubleOrUndefined(env, obj, "time", isUndefined,time) == ANI_OK && isUndefined == ANI_FALSE) { + capsule.SetTime(static_cast(time)); + } + + ani_ref iconRef = {}; + if(env->Object_GetPropertyByName_Ref(obj, "icon", &iconRef) == ANI_OK) { + std::shared_ptr pixelMap = GetPixelMapFromEnvSp(env, static_cast(iconRef)); + if (pixelMap != nullptr) { + capsule.SetIcon(pixelMap); + } + } + + std::vector iconButtons = {}; + + if (GetIconButtonArrayOrUndefined(env, obj, "capsuleButtons", iconButtons) == ANI_OK) { + capsule.SetCapsuleButton(iconButtons); + } +} + +ani_status UnWarpNotificationBasicContent(ani_env *env, ani_object obj, + std::shared_ptr basicContent) +{ + ANS_LOGI("UnWarpNotificationBasicContent call"); + ani_status status = ANI_ERROR; + ani_boolean isUndefined = ANI_TRUE; + std::string title; + if((status = GetPropertyString(env, obj, "title", isUndefined, title)) != ANI_OK || isUndefined == ANI_TRUE) { + return ANI_INVALID_ARGS; + } + basicContent->SetTitle(title); + + std::string text; + isUndefined = ANI_TRUE; + if((status = GetPropertyString(env, obj, "text", isUndefined, text)) != ANI_OK || isUndefined == ANI_TRUE) { + return ANI_INVALID_ARGS; + } + basicContent->SetText(text); + + std::string additionalText; + isUndefined = ANI_TRUE; + if(GetPropertyString(env, obj, "additionalText", isUndefined, additionalText) == ANI_OK + && isUndefined == ANI_FALSE) { + basicContent->SetAdditionalText(additionalText); + } + + ani_ref lockscreenPictureRef = {}; + if (env->Object_GetPropertyByName_Ref(obj, "lockscreenPicture", &lockscreenPictureRef)) { + std::shared_ptr pixelMap = GetPixelMapFromEnvSp(env, static_cast(lockscreenPictureRef)); + if (pixelMap != nullptr) { + basicContent->SetLockScreenPicture(pixelMap); + } + } + return status; +} + +ani_status UnWarpNotificationNormalContent(ani_env *env, ani_object obj, + std::shared_ptr &normalContent) +{ + ani_status status =ANI_ERROR; + if((status = UnWarpNotificationBasicContent(env, obj, normalContent)) != ANI_OK) { + return status; + } + return status; +} + +ani_status UnWarpNotificationLongTextContent(ani_env *env, ani_object obj, + std::shared_ptr &longTextContent) +{ + ani_status status =ANI_ERROR; + if((status = UnWarpNotificationBasicContent(env, obj, longTextContent)) != ANI_OK) { + return status; + } + + ani_boolean isUndefined = ANI_TRUE; + std::string longText; + if((status = GetPropertyString(env, obj, "longText", isUndefined, longText)) != ANI_OK + || isUndefined == ANI_TRUE) { + return ANI_INVALID_ARGS; + } + longTextContent->SetLongText(longText); + + std::string briefText; + isUndefined = ANI_TRUE; + if((status = GetPropertyString(env, obj, "briefText", isUndefined, briefText)) != ANI_OK + || isUndefined == ANI_TRUE) { + return ANI_INVALID_ARGS; + } + longTextContent->SetBriefText(briefText); + + std::string expandedTitle; + isUndefined = ANI_TRUE; + if((status = GetPropertyString(env, obj, "expandedTitle", isUndefined, expandedTitle)) != ANI_OK + || isUndefined == ANI_TRUE) { + return ANI_INVALID_ARGS; + } + longTextContent->SetExpandedTitle(expandedTitle); + + return status; +} + +ani_status UnWarpNotificationMultiLineContent(ani_env *env, ani_object obj, + std::shared_ptr &multiLineContent) +{ + ani_status status =ANI_ERROR; + if((status = UnWarpNotificationBasicContent(env, obj, multiLineContent)) != ANI_OK) { + return status; + } + + ani_boolean isUndefined = ANI_TRUE; + std::string longTitle; + if((status = GetPropertyString(env, obj, "longTitle", isUndefined, longTitle)) != ANI_OK + || isUndefined == ANI_TRUE) { + return ANI_INVALID_ARGS; + } + multiLineContent->SetExpandedTitle(longTitle); + + std::string briefText; + isUndefined = ANI_TRUE; + if((status = GetPropertyString(env, obj, "briefText", isUndefined, briefText)) != ANI_OK + || isUndefined == ANI_TRUE) { + return ANI_INVALID_ARGS; + } + multiLineContent->SetBriefText(briefText); + + std::vector lines = {}; + isUndefined = ANI_TRUE; + if((status = GetStringArrayOrUndefined(env, obj, "lines", isUndefined, lines)) != ANI_OK + || isUndefined == ANI_TRUE) { + return ANI_INVALID_ARGS; + } + for(auto line : lines) { + multiLineContent->AddSingleLine(line); + } + return status; +} + +ani_status UnWarpNotificationPictureContent(ani_env *env, ani_object obj, + std::shared_ptr &pictureContent) +{ + ani_status status =ANI_ERROR; + if((status = UnWarpNotificationBasicContent(env, obj, pictureContent)) != ANI_OK) { + return status; + } + + std::string expandedTitle; + ani_boolean isUndefined = ANI_TRUE; + if((status = GetPropertyString(env, obj, "expandedTitle", isUndefined, expandedTitle)) != ANI_OK + || isUndefined == ANI_TRUE) { + return ANI_INVALID_ARGS; + } + pictureContent->SetExpandedTitle(expandedTitle); + + std::string briefText; + isUndefined = ANI_TRUE; + if((status = GetPropertyString(env, obj, "briefText", isUndefined, briefText)) != ANI_OK + || isUndefined == ANI_TRUE) { + return ANI_INVALID_ARGS; + } + pictureContent->SetBriefText(briefText); + + ani_ref pictureRef = {}; + if ((status = env->Object_GetPropertyByName_Ref(obj, "picture", &pictureRef)) != ANI_OK) { + return status; + } + std::shared_ptr pixelMap = GetPixelMapFromEnvSp(env, static_cast(pictureRef)); + if (pixelMap == nullptr) { + return ANI_INVALID_ARGS; + } + pictureContent->SetBigPicture(pixelMap); + + return status; +} + +ani_status GetKeyString(ani_env *env, ani_object obj, int index, ani_string &str) +{ + ani_status status = ANI_ERROR; + ani_ref stringEntryRef; + status = env->Object_CallMethodByName_Ref(obj, + "$_get", "I:Lstd/core/Object;", &stringEntryRef, (ani_int)index); + if (status != ANI_OK) { + ANS_LOGI("status : %{public}d, index: %{public}d", status, index); + return status; + } + str = static_cast(stringEntryRef); + return status; +} + +ani_status GetPixelMapByKeys(ani_env *env, ani_object obj, std::vector keys, + std::map>> &pictureMap) +{ + ani_status status = ANI_ERROR; + for(auto anikey : keys) { + ani_ref picturesArrayRef; + if (ANI_OK != (status = env->Object_CallMethodByName_Ref(obj, "$_get", nullptr, &picturesArrayRef, anikey))) { + return status; + } + std::vector> pixelMaps = {}; + if((status = GetPixelMapArrayByRef(env, picturesArrayRef, pixelMaps)) != ANI_OK) { + return status; + } + std::string str = ""; + if((status = GetStdString(env, anikey, str)) != ANI_OK) { + return status; + } + pictureMap[str] = pixelMaps; + } + return status; +} + +ani_status GetPictureInfoMap(ani_env *env, ani_object obj, + std::map>> pictureMap) +{ + ani_status status = ANI_ERROR; + ani_class cls = nullptr; + if ((status = env->FindClass("Lnotification/notificationContent/RecordTools;", &cls)) != ANI_OK) { + return status; + } + if (cls == nullptr) { + return ANI_INVALID_TYPE; + } + ani_static_method keysMethod = nullptr; + status = env->Class_FindStaticMethod(cls, "GetKeys", nullptr, &keysMethod); + if (status != ANI_OK) { + return status; + } + ani_ref keysStrArrayRef = nullptr; + status = env->Class_CallStaticMethod_Ref(cls, keysMethod, &keysStrArrayRef, obj); + if (status != ANI_OK) { + return status; + } + ani_boolean isUndefined = ANI_TRUE; + if ((status = env->Reference_IsUndefined(keysStrArrayRef, &isUndefined)) != ANI_OK) { + return status; + } + if (isUndefined) { + return ANI_INVALID_ARGS; + } + ani_double length; + status = env->Object_GetPropertyByName_Double(static_cast(keysStrArrayRef), "length", &length); + if (status != ANI_OK) { + return status; + } + ani_string strAni = {}; + std::vector keys = {}; + for (int i = 0; i < static_cast(length); i++) { + if((status = GetKeyString(env, static_cast(keysStrArrayRef), i, strAni)) != ANI_OK) { + return status; + } + keys.push_back(strAni); + } + status = GetPixelMapByKeys(env, obj, keys, pictureMap); + return status; +} + +ani_status UnWarpNotificationLiveViewContent(ani_env *env, ani_object obj, + std::shared_ptr &liveViewContent) +{ + ani_status status =ANI_ERROR; + if((status = UnWarpNotificationBasicContent(env, obj, liveViewContent)) != ANI_OK) { + return status; + } + + ani_ref statusRef; + if((status = env->Object_GetPropertyByName_Ref(obj, "status", &statusRef)) != ANI_OK) { + return status; + } + LiveViewStatus liveViewStatus = LiveViewStatus::LIVE_VIEW_CREATE; + if(!EnumConvertAniToNative(env, static_cast(statusRef), liveViewStatus)) { + return ANI_INVALID_ARGS; + } + liveViewContent->SetLiveViewStatus(liveViewStatus); + + ani_double versionAni = 0.0; + ani_boolean isUndefined = ANI_TRUE; + if (GetPropertyDoubleOrUndefined(env, obj, "version", isUndefined, versionAni) == ANI_OK + && isUndefined == ANI_FALSE) { + liveViewContent->SetVersion(static_cast(versionAni)); + } + + ani_ref extraInfoRef; + isUndefined = ANI_TRUE; + if (ANI_OK == (status = env->Object_GetPropertyByName_Ref(obj, "extraInfo", &extraInfoRef)) + && env->Reference_IsUndefined(extraInfoRef, &isUndefined) == ANI_OK && isUndefined == ANI_FALSE) { + WantParams wantParams = {}; + if(UnwrapWantParams(env, extraInfoRef, wantParams)) { + std::shared_ptr extraInfo = std::make_shared(wantParams); + liveViewContent->SetExtraInfo(extraInfo); + } + } + + ani_ref pictureInfoRef; + isUndefined = ANI_TRUE; + if (ANI_OK == env->Object_GetPropertyByName_Ref(obj, "pictureInfo", &pictureInfoRef) + && env->Reference_IsUndefined(pictureInfoRef, &isUndefined) == ANI_OK && isUndefined == ANI_FALSE) { + std::map>> pictureMap; + if(GetPictureInfoMap(env, static_cast(pictureInfoRef), pictureMap) == ANI_OK) { + liveViewContent->SetPicture(pictureMap); + } + } + + bool isLocalUpdateOnly = true; + isUndefined = ANI_TRUE; + if(ANI_OK == GetPropertyBooleanOrUndefined(env, obj, "isLocalUpdateOnly", isUndefined, isLocalUpdateOnly) + && isUndefined == ANI_FALSE) { + liveViewContent->SetIsOnlyLocalUpdate(isLocalUpdateOnly); + } + return status; +} + +ani_status UnWarpNotificationLocalLiveViewContent(ani_env *env, ani_object obj, + std::shared_ptr &localLiveViewContent) +{ + ani_status status =ANI_ERROR; + if((status = UnWarpNotificationBasicContent(env, obj, localLiveViewContent)) != ANI_OK) { + return status; + } + + ani_double typeCode = 0.0; + ani_boolean isUndefined = ANI_TRUE; + if((status = GetPropertyDoubleOrUndefined(env, obj, "typeCode", isUndefined, typeCode)) != ANI_OK + || isUndefined == ANI_TRUE) { + return ANI_INVALID_ARGS; + } + localLiveViewContent->SetType(static_cast(typeCode)); + + ani_ref capsuleRef = {}; + if(env->Object_GetPropertyByName_Ref(obj, "capsule", &capsuleRef) == ANI_OK) { + NotificationCapsule capsule; + UnWarpNotificationCapsule(env, static_cast(capsuleRef), capsule); + localLiveViewContent->SetCapsule(capsule); + } + + ani_ref buttonRef = {}; + if(env->Object_GetPropertyByName_Ref(obj, "button", &buttonRef) == ANI_OK) { + NotificationLocalLiveViewButton button; + UnWarpNotificationLocalLiveViewButton(env, static_cast(buttonRef), button); + localLiveViewContent->SetButton(button); + } + + std::vector buttons = {}; + if(GetIconButtonArrayOrUndefined(env, obj, "cardButtons", buttons) == ANI_OK) { + localLiveViewContent->SetCardButton(buttons); + } + + ani_ref timeRef = {}; + if(env->Object_GetPropertyByName_Ref(obj, "time", &timeRef) == ANI_OK) { + NotificationTime notificationTime; + UnWarpNotificationTime(env, static_cast(timeRef), notificationTime); + localLiveViewContent->SetTime(notificationTime); + } + + ani_ref progressRef = {}; + if(env->Object_GetPropertyByName_Ref(obj, "progress", &progressRef) == ANI_OK) { + NotificationProgress notificationProgress; + UnWarpNotificationProgress(env, static_cast(progressRef), notificationProgress); + localLiveViewContent->SetProgress(notificationProgress); + } + + ani_ref liveViewTypeRef = {}; + if(env->Object_GetPropertyByName_Ref(obj, "liveViewType", &liveViewTypeRef) == ANI_OK) { + LiveViewTypes liveViewTypes = LiveViewTypes::LIVE_VIEW_ACTIVITY; + if(LiveViewTypesEtsToC(env, static_cast(liveViewTypeRef), liveViewTypes)) { + localLiveViewContent->SetLiveViewType(liveViewTypes); + } + } + + return status; +} + +ani_object GetWantAgentArrayAniObject(ani_env *env, std::vector> wantAgents) +{ + ani_status status = ANI_ERROR; + ani_class arrayCls = nullptr; + ani_method arrayCtor; + ani_object arrayObj; + status = env->FindClass("Lescompat/Array;", &arrayCls); + if (status != ANI_OK) { + ANS_LOGE("status : %{public}d", status); + return nullptr; + } + status = env->Class_FindMethod(arrayCls, "", "I:V", &arrayCtor); + if (status != ANI_OK) { + ANS_LOGE("status : %{public}d", status); + return nullptr; + } + status = env->Object_New(arrayCls, arrayCtor, &arrayObj, wantAgents.size()); + if (status != ANI_OK) { + ANS_LOGE("status : %{public}d", status); + return nullptr; + } + // need to do + ani_size index = 0; + for (auto &wantAgent : wantAgents) { + //need to do Convert wantAgent to ani object + ani_object item = AppExecFwk::WrapWantAgent(env, wantAgent.get()); + RETURN_NULL_IF_NULL(item); + if(ANI_OK != env->Object_CallMethodByName_Void(arrayObj, "$_set", "ILstd/core/Object;:V", index, item)){ + std::cerr << "Object_CallMethodByName_Void $_set Faild " << std::endl; + return nullptr; + } + index ++; + } + return arrayObj; +} + +ani_object SetResourceObject(ani_env *env, const std::shared_ptr &resource) +{ + ani_class resourceCls = nullptr; + ani_object resourceObject = nullptr; + RETURN_NULL_IF_FALSE(CreateClassObjByClassName(env, + "Lnotification/notificationContent/ResourceInner;", resourceCls, resourceObject)); + // bundleName: string; + ani_string stringValue = nullptr; + RETURN_NULL_IF_FALSE(GetAniString(env, resource->bundleName, stringValue)); + RETURN_NULL_IF_FALSE(CallSetter(env, resourceCls, resourceObject, "bundleName", stringValue)); + // moduleName: string; + RETURN_NULL_IF_FALSE(GetAniString(env, resource->moduleName, stringValue)); + RETURN_NULL_IF_FALSE(CallSetter(env, resourceCls, resourceObject, "moduleName", stringValue)); + // id: number; + RETURN_NULL_IF_FALSE(CallSetter(env, resourceCls, resourceObject, "id", resource->id)); + return resourceObject; +} + +ani_object ConvertNotificationIconButtonToAniObject(ani_env *env, const NotificationIconButton &button) +{ + ani_class iconButtonCls = nullptr; + ani_object iconButtonObject = nullptr; + RETURN_NULL_IF_FALSE(CreateClassObjByClassName(env, + "Lnotification/notificationContent/NotificationIconButtonInner;", iconButtonCls, iconButtonObject)); + // name: string + ani_string stringValue = nullptr; + RETURN_NULL_IF_FALSE(GetAniString(env, button.GetName(), stringValue)); + RETURN_NULL_IF_FALSE(CallSetter(env, iconButtonCls, iconButtonObject, "name", stringValue)); + // text?: string; + RETURN_NULL_IF_FALSE(GetAniString(env, button.GetText(), stringValue)); + RETURN_NULL_IF_FALSE(CallSetterOptional(env, iconButtonCls, iconButtonObject, "text", stringValue)); + // hidePanel?: boolean; + RETURN_NULL_IF_FALSE(CallSetterOptional( + env, iconButtonCls, iconButtonObject, "hidePanel", BoolToAniBoolean(button.GetHidePanel()))); + // iconResource: IconType; type IconType = Resource | image.PixelMap; + std::shared_ptr icon = button.GetIconImage(); + if (icon) { + ani_object pixelMapObject = Media::PixelMapAni::CreatePixelMap(env, icon); + if (pixelMapObject == nullptr) { + ANS_LOGE("CreatePixelMap failed, pixelMapObject is nullptr"); + return nullptr; + } + RETURN_NULL_IF_FALSE(CallSetter(env, iconButtonCls, iconButtonObject, "iconResource", pixelMapObject)); + } else { + ani_object resourceObject = SetResourceObject(env, button.GetIconResource()); + if (resourceObject == nullptr) { + ANS_LOGE("SetResourceObject failed, resourceObject is nullptr"); + return nullptr; + } + RETURN_NULL_IF_FALSE(CallSetter(env, iconButtonCls, iconButtonObject, "iconResource", resourceObject)); + } + return iconButtonObject; +} + +bool SetTime(ani_env *env, const NotificationTime &time, bool isInitialTimeExist, ani_object &timeObject) +{ + ani_class timeClass = nullptr; + RETURN_FALSE_IF_FALSE(CreateClassObjByClassName(env, + "Lnotification/notificationContent/NotificationTimeInner;", timeClass, timeObject)); + // initialTime?: number; + if (isInitialTimeExist) { + RETURN_FALSE_IF_FALSE(CallSetterOptional(env, timeClass, timeObject, "initialTime", + time.GetInitialTime())); + } + // isCountDown?: boolean; + RETURN_FALSE_IF_FALSE(CallSetterOptional(env, timeClass, timeObject, "isCountDown", + BoolToAniBoolean(time.GetIsCountDown()))); + // isPaused?: boolean; + RETURN_FALSE_IF_FALSE(CallSetterOptional(env, timeClass, timeObject, "isPaused", + BoolToAniBoolean(time.GetIsPaused()))); + // isInTitle?: boolean; + RETURN_FALSE_IF_FALSE(CallSetterOptional(env, timeClass, timeObject, "isInTitle", + BoolToAniBoolean(time.GetIsInTitle()))); + return true; +} + +ani_object ConvertVectorToAniArrayPixelMap(ani_env *env, const std::vector> &pixelMaps) +{ + RETURN_NULL_IF_NULL(env); + if (pixelMaps.empty()) { + return nullptr; + } + + ani_class arrayCls = nullptr; + ani_status status = env->FindClass("Lescompat/Array;", &arrayCls); + if (status != ANI_OK) { + ANS_LOGE("FindClass failed %{public}d", status); + return nullptr; + } + + ani_method arrayCtor; + status = env->Class_FindMethod(arrayCls, "", "I:V", &arrayCtor); + if (status != ANI_OK) { + ANS_LOGE("Class_FindMethod failed %{public}d", status); + return nullptr; + } + + ani_size length = pixelMaps.size(); + ani_object arrayObj; + status = env->Object_New(arrayCls, arrayCtor, &arrayObj, length); + if (status != ANI_OK) { + ANS_LOGE("Object_New failed %{public}d", status); + return nullptr; + } + ani_size i = 0; + for (auto &pixelMap : pixelMaps) { + ani_object pixelMapObject = Media::PixelMapAni::CreatePixelMap(env, pixelMap); + if (pixelMapObject == nullptr) { + ANS_LOGE("CreatePixelMap failed, pixelMapObject is nullptr"); + return nullptr; + } + status = env->Object_CallMethodByName_Void(arrayObj, "$_set", "ILstd/core/Object;:V", i, pixelMapObject); + if (status != ANI_OK) { + ANS_LOGE("Object_CallMethodByName_Void failed %{public}d", status); + return nullptr; + } + i++; + } + return arrayObj; +} + +ani_object ConvertVectorToAniArrayResource(ani_env *env, + const std::vector> &resources) +{ + if (resources.empty()) { + ANS_LOGE("resources is empty"); + return nullptr; + } + ani_class arrayCls = nullptr; + ani_status status = env->FindClass("Lescompat/Array;", &arrayCls); + if (status != ANI_OK) { + ANS_LOGE("FindClass failed %{public}d", status); + return nullptr; + } + + ani_method arrayCtor; + status = env->Class_FindMethod(arrayCls, "", "I:V", &arrayCtor); + if (status != ANI_OK) { + ANS_LOGE("Class_FindMethod failed %{public}d", status); + return nullptr; + } + + ani_size length = resources.size(); + ani_object arrayObj; + status = env->Object_New(arrayCls, arrayCtor, &arrayObj, length); + if (status != ANI_OK) { + ANS_LOGE("Object_New failed %{public}d", status); + return nullptr; + } + ani_size i = 0; + for (auto &resource : resources) { + ani_object resourceObject = SetResourceObject(env, resource); + if (resourceObject == nullptr) { + ANS_LOGE("SetResourceObject failed, resourceObject is nullptr"); + return nullptr; + } + status = env->Object_CallMethodByName_Void(arrayObj, "$_set", "ILstd/core/Object;:V", i, resourceObject); + if (status != ANI_OK) { + ANS_LOGE("Object_CallMethodByName_Void failed %{public}d", status); + return nullptr; + } + i++; + } + return arrayObj; +} + +bool SetButton(ani_env *env, const NotificationLocalLiveViewButton &button, ani_object &buttonObject) +{ + ani_class buttonClass = nullptr; + RETURN_FALSE_IF_FALSE(CreateClassObjByClassName(env, + "Lnotification/notificationContent/NotificationButtonInner;", buttonClass, buttonObject)); + // names?: Array; + std::vector names = button.GetAllButtonNames(); + ani_object namesObjectArray = ConvertVectorToAniArrayString(env, names); + if (namesObjectArray == nullptr) { + ANS_LOGE("namesObjectArray is nullptr"); + return false; + } + RETURN_FALSE_IF_FALSE(CallSetterOptional(env, buttonClass, buttonObject, "names", namesObjectArray)); + // icons?: Array; + std::vector> icons = button.GetAllButtonIcons(); + ani_object iconsObjectArray = ConvertVectorToAniArrayPixelMap(env, icons); + if (iconsObjectArray == nullptr) { + ANS_LOGE("iconsObjectArray is nullptr"); + return false; + } + RETURN_FALSE_IF_FALSE(CallSetterOptional(env, buttonClass, buttonObject, "icons", iconsObjectArray)); + // iconsResource?: Array; + std::vector> iconsResource = button.GetAllButtonIconResource(); + ani_object resourceObjectArray = ConvertVectorToAniArrayResource(env, iconsResource); + if (resourceObjectArray == nullptr) { + ANS_LOGE("resourceObjectArray is nullptr"); + return false; + } + RETURN_FALSE_IF_FALSE(CallSetterOptional(env, buttonClass, buttonObject, "iconsResource", resourceObjectArray)); + return true; +} + +bool SetProgress(ani_env *env, const NotificationProgress &progress, ani_object &progressObject) +{ + ani_class progressClass = nullptr; + RETURN_FALSE_IF_FALSE(CreateClassObjByClassName(env, + "Lnotification/notificationContent/NotificationProgressInner;", progressClass, progressObject)); + // maxValue?: number; + RETURN_FALSE_IF_FALSE(CallSetterOptional(env, progressClass, progressObject, "maxValue", + progress.GetMaxValue())); + // currentValue?: number; + RETURN_FALSE_IF_FALSE(CallSetterOptional(env, progressClass, progressObject, "currentValue", + progress.GetCurrentValue())); + // isPercentage?: boolean; + RETURN_FALSE_IF_FALSE(CallSetterOptional(env, progressClass, progressObject, "isPercentage", + BoolToAniBoolean(progress.GetIsPercentage()))); + return true; +} + +ani_object SetCardButton(ani_env *env, const std::vector buttons) +{ + ani_status status = ANI_ERROR; + ani_class arrayCls = nullptr; + ani_method arrayCtor; + ani_object arrayObj; + status = env->FindClass("Lescompat/Array;", &arrayCls); + if (status != ANI_OK) { + ANS_LOGE("status : %{public}d", status); + return nullptr; + } + status = env->Class_FindMethod(arrayCls, "", "I:V", &arrayCtor); + if (status != ANI_OK) { + ANS_LOGE("status : %{public}d", status); + return nullptr; + } + status = env->Object_New(arrayCls, arrayCtor, &arrayObj, buttons.size()); + if (status != ANI_OK) { + ANS_LOGE("status : %{public}d", status); + return nullptr; + } + ani_size index = 0; + for (auto &button : buttons) { + ani_object item = ConvertNotificationIconButtonToAniObject(env, button); + RETURN_NULL_IF_NULL(item); + if(ANI_OK != env->Object_CallMethodByName_Void(arrayObj, "$_set", "ILstd/core/Object;:V", index, item)){ + std::cerr << "Object_CallMethodByName_Void $_set Faild " << std::endl; + return nullptr; + } + index ++; + } + return arrayObj; +} + +bool SetCapsule(ani_env *env, const NotificationCapsule &capsule, ani_object &capsuleObject) +{ + ani_class capsuleClass = nullptr; + RETURN_FALSE_IF_FALSE(CreateClassObjByClassName(env, + "Lnotification/notificationContent/NotificationCapsuleInner;", capsuleClass, capsuleObject)); + // title?: string; + ani_string stringValue = nullptr; + if(GetAniString(env, capsule.GetTitle(), stringValue)) { + CallSetterOptional(env, capsuleClass, capsuleObject, "title", stringValue); + } + // icon?: image.PixelMap; + std::shared_ptr icon = capsule.GetIcon(); + if (icon) { + ani_object pixelMapObject = Media::PixelMapAni::CreatePixelMap(env, icon); + if (pixelMapObject == nullptr) { + ANS_LOGE("CreatePixelMap failed, pixelMapObject is nullptr"); + } else { + CallSetterOptional(env, capsuleClass, capsuleObject, "icon", pixelMapObject); + } + } + // backgroundColor?: string; + if(GetAniString(env, capsule.GetBackgroundColor(), stringValue)) { + CallSetterOptional(env, capsuleClass, capsuleObject, "backgroundColor", stringValue); + } + //content?: string; + if(GetAniString(env, capsule.GetContent(), stringValue)) { + CallSetterOptional(env, capsuleClass, capsuleObject, "content", stringValue); + } + // time?: number; + CallSetterOptional(env, capsuleClass, capsuleObject, "time", capsule.GetTime()); + // capsuleButtons?: Array; + std::vector buttons = capsule.GetCapsuleButton(); + ani_object buttonsObjectArray = SetCardButton(env, buttons); + if (buttonsObjectArray != nullptr) { + CallSetterOptional(env, capsuleClass, capsuleObject, "capsuleButtons", buttonsObjectArray); + } + return true; +} + +bool SetNotificationBasicContent( + ani_env* env, ani_class contentCls, const NotificationBasicContent *basicContent, ani_object &object) +{ + ANS_LOGD("enter"); + if (basicContent == nullptr) { + ANS_LOGE("basicContent is null"); + return false; + } + ani_string aniStr; + if(GetAniString(env, basicContent->GetTitle(), aniStr)) { + CallSetterOptional(env, contentCls, object, "title", aniStr); + } + if(GetAniString(env, basicContent->GetText(), aniStr)) { + CallSetterOptional(env, contentCls, object, "text", aniStr); + } + if(GetAniString(env, basicContent->GetAdditionalText(), aniStr)) { + CallSetterOptional(env, contentCls, object, "additionalText", aniStr); + } + ani_object lockScreenPicObj = CreatePixelMap(env, basicContent->GetLockScreenPicture()); + if (lockScreenPicObj != nullptr) { + CallSetter(env, contentCls, object, "lockScreenPicture", lockScreenPicObj); + } + return true; +} + +bool SetNotificationLongTextContent( + ani_env* env, ani_class contentCls, NotificationBasicContent *basicContent, ani_object &object) +{ + ANS_LOGD("enter SetNotificationLongTextContent"); + if (basicContent == nullptr) { + ANS_LOGE("basicContent is null"); + return false; + } + NotificationLongTextContent *content = static_cast(basicContent); + if (content == nullptr) { + ANS_LOGE("longTextContent is null"); + return false; + } + SetNotificationBasicContent(env, contentCls, content, object); + + ani_string aniStr; + if(GetAniString(env, content->GetLongText(), aniStr)) { + CallSetterOptional(env, contentCls, object, "longText", aniStr); + } + if(GetAniString(env, content->GetBriefText(), aniStr)) { + CallSetterOptional(env, contentCls, object, "briefText", aniStr); + } + if(GetAniString(env, content->GetExpandedTitle(), aniStr)) { + CallSetterOptional(env, contentCls, object, "expandedTitle", aniStr); + } + return true; +} + +bool SetNotificationPictureContent( + ani_env* env, ani_class contentCls, NotificationBasicContent *basicContent, ani_object &object) +{ + ANS_LOGD("enter SetNotificationPictureContent"); + if (basicContent == nullptr) { + ANS_LOGE("basicContent is null"); + return false; + } + NotificationPictureContent *content = static_cast(basicContent); + if (content == nullptr) { + ANS_LOGE("longTextContent is null"); + return false; + } + SetNotificationBasicContent(env, contentCls, content, object); + + ani_string aniStr; + if(GetAniString(env, content->GetBriefText(), aniStr)) { + CallSetterOptional(env, contentCls, object, "briefText", aniStr); + } + if(GetAniString(env, content->GetExpandedTitle(), aniStr)) { + CallSetterOptional(env, contentCls, object, "expandedTitle", aniStr); + } + ani_object pictureObj = CreatePixelMap(env, content->GetBigPicture()); + if (pictureObj != nullptr) { + CallSetter(env, contentCls, object, "picture", pictureObj); + } + return true; +} + +bool SetNotificationMultiLineContent( + ani_env* env, ani_class contentCls, NotificationBasicContent *basicContent, ani_object &object) +{ + ANS_LOGD("enter SetNotificationMultiLineContent"); + if (basicContent == nullptr) { + ANS_LOGE("basicContent is null"); + return false; + } + NotificationMultiLineContent *content = static_cast(basicContent); + if (content == nullptr) { + ANS_LOGE("longTextContent is null"); + return false; + } + SetNotificationBasicContent(env, contentCls, content, object); + + ani_string aniStr; + if(GetAniString(env, content->GetBriefText(), aniStr)) { + CallSetterOptional(env, contentCls, object, "briefText", aniStr); + } + if(GetAniString(env, content->GetExpandedTitle(), aniStr)) { + CallSetterOptional(env, contentCls, object, "longTitle", aniStr); + } + std::vector allLines = content->GetAllLines(); + ani_object allLinesObject = ConvertVectorToAniArrayString(env, allLines); + CallSetter(env, contentCls, object, "lines", allLinesObject); + //need to do : lineWantAgents: Array GetLineWantAgents + ani_object lineWantAgentsObject = GetWantAgentArrayAniObject(env, content->GetLineWantAgents()); + CallSetter(env, contentCls, object, "lineWantAgents", lineWantAgentsObject); + return true; +} + +bool SetNotificationLocalLiveViewContent( + ani_env* env, ani_class contentCls, NotificationBasicContent *basicContent, ani_object &object) +{ + ANS_LOGD("enter SetNotificationLocalLiveViewContent"); + if (basicContent == nullptr) { + ANS_LOGE("basicContent is null"); + return false; + } + NotificationLocalLiveViewContent *content = static_cast(basicContent); + if (content == nullptr) { + ANS_LOGE("longTextContent is null"); + return false; + } + SetNotificationBasicContent(env, contentCls, content, object); + + CallSetterOptional(env, contentCls, object, "typeCode", content->GetType()); + + if (content->isFlagExist(NotificationLocalLiveViewContent::LiveViewContentInner::CAPSULE)) { + ani_object capsuleObject = nullptr; + if(SetCapsule(env, content->GetCapsule(), capsuleObject) && capsuleObject != nullptr) { + CallSetter(env, contentCls, object, "capsule", capsuleObject); + } + } + if (content->isFlagExist(NotificationLocalLiveViewContent::LiveViewContentInner::BUTTON)) { + // need to do : SetButton(env, localLiveViewContent->GetButton(), button) + // button: NotificationLocalLiveViewButton + ani_object buttonObject = nullptr; + if(SetButton(env, content->GetButton(), buttonObject) && buttonObject != nullptr) { + CallSetter(env, contentCls, object, "button", buttonObject); + } + } + if (content->isFlagExist(NotificationLocalLiveViewContent::LiveViewContentInner::CARD_BUTTON)) { + std::vector buttons = content->GetCardButton(); + ani_object buttonsObjectArray = SetCardButton(env, buttons); + if (buttonsObjectArray != nullptr) { + CallSetterOptional(env, contentCls, object, "cardButtons", buttonsObjectArray); + } + } + + ani_enum_item enumItem = nullptr; + if(LiveViewTypesCToEts(env, content->GetLiveViewType(), enumItem) && enumItem != nullptr) { + CallSetter(env, contentCls, object, "liveViewType", enumItem); + } + + if (content->isFlagExist(NotificationLocalLiveViewContent::LiveViewContentInner::PROGRESS)) { + ani_object progressObject = nullptr; + if(SetProgress(env, content->GetProgress(), progressObject) && progressObject != nullptr) { + CallSetter(env, contentCls, object, "progress", progressObject); + } + } + + if (content->isFlagExist(NotificationLocalLiveViewContent::LiveViewContentInner::TIME)) { + bool flag = content->isFlagExist( + NotificationLocalLiveViewContent::LiveViewContentInner::INITIAL_TIME); + ani_object timeObject = nullptr; + if(SetTime(env, content->GetTime(), flag, timeObject) && timeObject != nullptr) { + CallSetter(env, contentCls, object, "time", timeObject); + } + + } + return true; +} + +bool GetAniPictrueInfo(ani_env *env, std::map>> pictureMap, + ani_object &pictureInfoObj) +{ + ani_class recordCls; + ani_method ctor; + if (ANI_OK != env->FindClass("Lescompat/Record;", &recordCls)) { + return false; + } + + if (ANI_OK != env->Class_FindMethod(recordCls, "", nullptr, &ctor)) { + return false; + } + + if (ANI_OK != env->Object_New(recordCls, ctor, &pictureInfoObj)) { + return false; + } + for (const auto& [key, value] : pictureMap) { + ani_string aniKey = GetAniString(env, key); + ani_object aniPictrueArray = ConvertVectorToAniArrayPixelMap(env, value); + if (aniKey == nullptr || aniPictrueArray == nullptr) { + return false; + } + if (ANI_OK != env->Object_CallMethodByName_Void(pictureInfoObj, "$_set", + "Lstd/core/Object;Lstd/core/Object;:V", aniKey, aniPictrueArray)) { + return false; + } + } + return true; +} + +bool SetNotificationLiveViewContent( + ani_env* env, ani_class contentCls, NotificationBasicContent *basicContent, ani_object &object) +{ + ANS_LOGD("enter SetNotificationLocalLiveViewContent"); + if (basicContent == nullptr) { + ANS_LOGE("basicContent is null"); + return false; + } + NotificationLiveViewContent *content = static_cast(basicContent); + if (content == nullptr) { + ANS_LOGE("longTextContent is null"); + return false; + } + + ani_object lockScreenPicObj = CreatePixelMap(env, content->GetLockScreenPicture()); + if (lockScreenPicObj != nullptr) { + CallSetter(env, contentCls, object, "lockScreenPicture", lockScreenPicObj); + } + + ani_enum_item enumItem = nullptr; + if(LiveViewStatusCToEts(env, content->GetLiveViewStatus(), enumItem) && enumItem != nullptr) { + CallSetter(env, contentCls, object, "status", enumItem); + } + + CallSetterOptional(env, contentCls, object, "version", static_cast(content->GetVersion())); + + std::shared_ptr extraInfoData = content->GetExtraInfo(); + if (extraInfoData != nullptr) { + ani_ref extraInfoObj = WrapWantParams(env, *extraInfoData); + if (extraInfoObj != nullptr) { + CallSetter(env, contentCls, object, "extraInfo", extraInfoObj); + } + } + // pictureInfo?: {[key, string]: Array} + if (content->GetPicture().empty()) { + ANS_LOGD("No pictures in live view."); + return true; + } + ani_object pictureInfoObj = nullptr; + if (GetAniPictrueInfo(env, content->GetPicture(), pictureInfoObj) && pictureInfoObj != nullptr) { + CallSetter(env, contentCls, object, "pictureInfo", pictureInfoObj); + } + return true; + + return true; +} + +bool SetNotificationContent(ani_env* env, std::shared_ptr content, ani_object &object) +{ + ani_class cls; + RETURN_FALSE_IF_FALSE(!CreateClassObjByClassName(env, + "Lnotification/notificationContent/NotificationContentInner;", cls, object)); + // notificationContentType?: notificationManager.ContentType; + ani_enum_item contentTypeItem {}; + RETURN_FALSE_IF_FALSE(ContentTypeCToEts(env, content->GetContentType(), contentTypeItem)); + RETURN_FALSE_IF_FALSE(CallSetterOptional(env, cls, object, "notificationContentType", contentTypeItem)); + STSContentType stsContentType = STSContentType::NOTIFICATION_CONTENT_BASIC_TEXT; + RETURN_FALSE_IF_FALSE(StsContentTypeUtils::CToSts(content->GetContentType(), stsContentType)); + std::shared_ptr basicContent = content->GetNotificationContent(); + if (basicContent == nullptr) { + ANS_LOGE("content is null"); + return false; + } + ani_object aniContext; + ani_class clsContent; + switch (stsContentType) { + case STSContentType::NOTIFICATION_CONTENT_BASIC_TEXT: // normal?: NotificationBasicContent + RETURN_FALSE_IF_FALSE(!CreateClassObjByClassName(env, + "Lnotification/notificationContent/NotificationBasicContentInner;", clsContent, aniContext)); + RETURN_FALSE_IF_NULL(clsContent); + RETURN_FALSE_IF_NULL(aniContext); + RETURN_FALSE_IF_FALSE(SetNotificationBasicContent(env, clsContent, basicContent.get(), aniContext)); + RETURN_FALSE_IF_FALSE(CallSetter(env, cls, object, "normal", aniContext)); + break; + case STSContentType::NOTIFICATION_CONTENT_LONG_TEXT: // longText?: NotificationLongTextContent + RETURN_FALSE_IF_FALSE(!CreateClassObjByClassName(env, + "Lnotification/notificationContent/NotificationLongTextContentInner;", clsContent, aniContext)); + RETURN_FALSE_IF_NULL(clsContent); + RETURN_FALSE_IF_NULL(aniContext); + RETURN_FALSE_IF_FALSE(SetNotificationLongTextContent(env, clsContent, basicContent.get(), aniContext)); + RETURN_FALSE_IF_FALSE(CallSetter(env, cls, object, "longText", aniContext)); + break; + case STSContentType::NOTIFICATION_CONTENT_PICTURE: // picture?: NotificationPictureContent + RETURN_FALSE_IF_FALSE(!CreateClassObjByClassName(env, + "Lnotification/notificationContent/NotificationPictureContentInner;", clsContent, aniContext)); + RETURN_FALSE_IF_NULL(clsContent); + RETURN_FALSE_IF_NULL(aniContext); + RETURN_FALSE_IF_FALSE(SetNotificationPictureContent(env, clsContent, basicContent.get(), aniContext)); + RETURN_FALSE_IF_FALSE(CallSetter(env, cls, object, "picture", aniContext)); + break; + // need to do + //case STSContentType::NOTIFICATION_CONTENT_CONVERSATION: // conversation?: NotificationConversationalContent + //ret = SetNotificationConversationalContent(env, basicContent.get(), contentResult); + // break; + case STSContentType::NOTIFICATION_CONTENT_MULTILINE: // multiLine?: NotificationMultiLineContent + RETURN_FALSE_IF_FALSE(!CreateClassObjByClassName(env, + "Lnotification/notificationContent/NotificationMultiLineContentInner;", clsContent, aniContext)); + RETURN_FALSE_IF_NULL(clsContent); + RETURN_FALSE_IF_NULL(aniContext); + RETURN_FALSE_IF_FALSE(SetNotificationMultiLineContent(env, clsContent, basicContent.get(), aniContext)); + RETURN_FALSE_IF_FALSE(CallSetter(env, cls, object, "multiLine", aniContext)); + break; + case STSContentType::NOTIFICATION_CONTENT_SYSTEM_LIVE_VIEW: // systemLiveView?: NotificationLocalLiveViewContent + RETURN_FALSE_IF_FALSE(!CreateClassObjByClassName(env, + "Lnotification/notificationContent/NotificationSystemLiveViewContentInner;", clsContent, aniContext)); + RETURN_FALSE_IF_NULL(clsContent); + RETURN_FALSE_IF_NULL(aniContext); + RETURN_FALSE_IF_FALSE(SetNotificationLocalLiveViewContent(env, clsContent, basicContent.get(), aniContext)); + RETURN_FALSE_IF_FALSE(CallSetter(env, cls, object, "systemLiveView", aniContext)); + break; + case STSContentType::NOTIFICATION_CONTENT_LIVE_VIEW: // liveView?: NotificationLiveViewContent + RETURN_FALSE_IF_FALSE(!CreateClassObjByClassName(env, + "Lnotification/notificationContent/NotificationLiveViewContentInner;", clsContent, aniContext)); + RETURN_FALSE_IF_NULL(clsContent); + RETURN_FALSE_IF_NULL(aniContext); + RETURN_FALSE_IF_FALSE(SetNotificationLiveViewContent(env, clsContent, basicContent.get(), aniContext)); + RETURN_FALSE_IF_FALSE(CallSetter(env, cls, object, "liveView", aniContext)); + break; + default: + ANS_LOGE("ContentType is does not exist"); + return false; + } + return true; +} + +bool SetNotificationRequestByNotificationContent(ani_env* env, ani_class cls, + const OHOS::Notification::NotificationRequest *request, ani_object &object) +{ + if (request == nullptr) { + ANS_LOGE("request is nullptr"); + return false; + } + + std::shared_ptr content = request->GetContent(); + ani_object contentObj; + RETURN_FALSE_IF_FALSE(SetNotificationContent(env, content, contentObj)); + RETURN_FALSE_IF_FALSE(contentObj == nullptr); + RETURN_FALSE_IF_FALSE(CallSetter(env, cls, object, "content", contentObj)); + return true; +} +} +} \ No newline at end of file diff --git a/frameworks/ani/notification_manager/src/sts_notification_enum_type.cpp b/frameworks/ani/notification_manager/src/sts_notification_enum_type.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fb68d2bd722de19e279801d185320f400e593109 --- /dev/null +++ b/frameworks/ani/notification_manager/src/sts_notification_enum_type.cpp @@ -0,0 +1,263 @@ +/* + * 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 "sts_notification_enum_type.h" + +#include "sts_notification_utils.h" +namespace OHOS { +namespace NotificationSts { +bool StsSlotTypeUtils::StsToC(const STSSlotType inType, SlotType &outType) +{ + switch (inType) { + case STSSlotType::SOCIAL_COMMUNICATION: + outType = SlotType::SOCIAL_COMMUNICATION; + break; + case STSSlotType::SERVICE_INFORMATION: + outType = SlotType::SERVICE_REMINDER; + break; + case STSSlotType::CONTENT_INFORMATION: + outType = SlotType::CONTENT_INFORMATION; + break; + case STSSlotType::LIVE_VIEW: + outType = SlotType::LIVE_VIEW; + break; + case STSSlotType::CUSTOMER_SERVICE: + outType = SlotType::CUSTOMER_SERVICE; + break; + case STSSlotType::EMERGENCY_INFORMATION: + outType = SlotType::EMERGENCY_INFORMATION; + break; + case STSSlotType::UNKNOWN_TYPE: + case STSSlotType::OTHER_TYPES: + outType = SlotType::OTHER; + break; + default: + ANS_LOGE("SlotType %{public}d is an invalid value", inType); + return false; + } + return true; +} + +bool StsSlotTypeUtils::CToSts(const SlotType inType, STSSlotType &outType) +{ + switch (inType) { + case SlotType::CUSTOM: + outType = STSSlotType::UNKNOWN_TYPE; + break; + case SlotType::SOCIAL_COMMUNICATION: + outType = STSSlotType::SOCIAL_COMMUNICATION; + break; + case SlotType::SERVICE_REMINDER: + outType = STSSlotType::SERVICE_INFORMATION; + break; + case SlotType::CONTENT_INFORMATION: + outType = STSSlotType::CONTENT_INFORMATION; + break; + case SlotType::LIVE_VIEW: + outType = STSSlotType::LIVE_VIEW; + break; + case SlotType::CUSTOMER_SERVICE: + outType = STSSlotType::CUSTOMER_SERVICE; + break; + case SlotType::EMERGENCY_INFORMATION: + outType = STSSlotType::EMERGENCY_INFORMATION; + break; + case SlotType::OTHER: + outType = STSSlotType::OTHER_TYPES; + break; + default: + ANS_LOGE("SlotType %{public}d is an invalid value", inType); + return false; + } + return true; +} + +bool StsLiveViewStatusUtils::StsToC(const STSLiveViewStatus inType, LiveViewStatus &outType) +{ + switch (inType) { + case STSLiveViewStatus::LIVE_VIEW_CREATE: + outType = LiveViewStatus::LIVE_VIEW_CREATE; + break; + case STSLiveViewStatus::LIVE_VIEW_INCREMENTAL_UPDATE: + outType = LiveViewStatus::LIVE_VIEW_INCREMENTAL_UPDATE; + break; + case STSLiveViewStatus::LIVE_VIEW_END: + outType = LiveViewStatus::LIVE_VIEW_END; + break; + case STSLiveViewStatus::LIVE_VIEW_FULL_UPDATE: + outType = LiveViewStatus::LIVE_VIEW_FULL_UPDATE; + break; + default: + ANS_LOGE("LiveViewStatus %{public}d is an invalid value", inType); + return false; + } + return true; +} + +bool StsLiveViewStatusUtils::CToSts(const LiveViewStatus inType, STSLiveViewStatus &outType) +{ + switch (inType) { + case LiveViewStatus::LIVE_VIEW_CREATE: + outType = STSLiveViewStatus::LIVE_VIEW_CREATE; + break; + case LiveViewStatus::LIVE_VIEW_INCREMENTAL_UPDATE: + outType = STSLiveViewStatus::LIVE_VIEW_INCREMENTAL_UPDATE; + break; + case LiveViewStatus::LIVE_VIEW_END: + outType = STSLiveViewStatus::LIVE_VIEW_END; + break; + case LiveViewStatus::LIVE_VIEW_FULL_UPDATE: + outType = STSLiveViewStatus::LIVE_VIEW_FULL_UPDATE; + break; + default: + ANS_LOGE("LiveViewStatus %{public}d is an invalid value", inType); + return false; + } + return true; +} + +bool SlotTypeEtsToC(ani_env *env, ani_enum_item enumItem, SlotType &slotType) +{ + STSSlotType stsSlotType = STSSlotType::UNKNOWN_TYPE; + EnumConvertAniToNative(env, enumItem, stsSlotType); + StsSlotTypeUtils::StsToC(stsSlotType, slotType); + return true; +} + +bool SlotTypeCToEts(ani_env *env, SlotType slotType, ani_enum_item &enumItem) +{ + STSSlotType stsSlotType = STSSlotType::UNKNOWN_TYPE; + StsSlotTypeUtils::CToSts(slotType, stsSlotType); + EnumConvertNativeToAni(env, + "L@ohos/notificationManager/notificationManager/SlotType;", stsSlotType, enumItem); + return true; +} + + +bool StsContentTypeUtils::StsToC(const STSContentType inType, ContentType &outType) +{ + switch (inType) { + case STSContentType::NOTIFICATION_CONTENT_BASIC_TEXT: + outType = ContentType::BASIC_TEXT; + break; + case STSContentType::NOTIFICATION_CONTENT_LONG_TEXT: + outType = ContentType::LONG_TEXT; + break; + case STSContentType::NOTIFICATION_CONTENT_MULTILINE: + outType = ContentType::MULTILINE; + break; + case STSContentType::NOTIFICATION_CONTENT_PICTURE: + outType = ContentType::PICTURE; + break; + case STSContentType::NOTIFICATION_CONTENT_CONVERSATION: + outType = ContentType::CONVERSATION; + break; + case STSContentType::NOTIFICATION_CONTENT_SYSTEM_LIVE_VIEW: + outType = ContentType::LOCAL_LIVE_VIEW; + break; + case STSContentType::NOTIFICATION_CONTENT_LIVE_VIEW: + outType = ContentType::LIVE_VIEW; + break; + default: + ANS_LOGE("ContentType %{public}d is an invalid value", inType); + return false; + } + return true; +} + +bool StsContentTypeUtils::CToSts(const ContentType inType, STSContentType &outType) +{ + switch (inType) { + case ContentType::BASIC_TEXT: + outType = STSContentType::NOTIFICATION_CONTENT_BASIC_TEXT; + break; + case ContentType::LONG_TEXT: + outType = STSContentType::NOTIFICATION_CONTENT_LONG_TEXT; + break; + case ContentType::MULTILINE: + outType = STSContentType::NOTIFICATION_CONTENT_MULTILINE; + break; + case ContentType::PICTURE: + outType = STSContentType::NOTIFICATION_CONTENT_PICTURE; + break; + case ContentType::CONVERSATION: + outType = STSContentType::NOTIFICATION_CONTENT_CONVERSATION; + break; + case ContentType::LOCAL_LIVE_VIEW: + outType = STSContentType::NOTIFICATION_CONTENT_SYSTEM_LIVE_VIEW; + break; + case ContentType::LIVE_VIEW: + outType = STSContentType::NOTIFICATION_CONTENT_LIVE_VIEW; + break; + default: + ANS_LOGE("ContentType %{public}d is an invalid value", inType); + return false; + } + return true; +} + +bool LiveViewTypesEtsToC(ani_env *env, ani_enum_item enumItem, LiveViewTypes &liveViewTypes) +{ + return EnumConvertAniToNative(env, enumItem, liveViewTypes); +} + +bool LiveViewTypesCToEts(ani_env *env, LiveViewTypes liveViewTypes, ani_enum_item &enumItem) +{ + return EnumConvertNativeToAni(env, + "Lnotification/notificationContent/#LiveViewTypes", liveViewTypes, enumItem); +} + +bool LiveViewStatusEtsToC(ani_env *env, ani_enum_item enumItem, LiveViewStatus &liveViewStatus) +{ + STSLiveViewStatus stsLiveViewStatus = STSLiveViewStatus::LIVE_VIEW_CREATE; + if(EnumConvertAniToNative(env, enumItem, stsLiveViewStatus)) { + StsLiveViewStatusUtils::StsToC(stsLiveViewStatus, liveViewStatus); + return true; + } + return false; +} + +bool LiveViewStatusCToEts(ani_env *env, LiveViewStatus liveViewStatus, ani_enum_item &enumItem) +{ + STSLiveViewStatus stsLiveViewStatus = STSLiveViewStatus::LIVE_VIEW_CREATE; + StsLiveViewStatusUtils::CToSts(liveViewStatus, stsLiveViewStatus); + if(EnumConvertNativeToAni(env, + "Lnotification/notificationContent/#LiveViewStatus", stsLiveViewStatus, enumItem)) { + return true; + } + return false; +} + +bool ContentTypeEtsToC(ani_env *env, ani_enum_item enumItem, ContentType &contentType) +{ + STSContentType stsContentType = STSContentType::NOTIFICATION_CONTENT_BASIC_TEXT; + if(EnumConvertAniToNative(env, enumItem, stsContentType)) { + StsContentTypeUtils::StsToC(stsContentType, contentType); + return true; + } + return false; +} + +bool ContentTypeCToEts(ani_env *env, ContentType contentType, ani_enum_item &enumItem) +{ + STSContentType stsContentType = STSContentType::NOTIFICATION_CONTENT_BASIC_TEXT; + StsContentTypeUtils::CToSts(contentType, stsContentType); + if(EnumConvertNativeToAni(env, + "L@ohos/notificationManager/notificationManager/#ContentType", stsContentType, enumItem)) { + return true; + } + return false; +} +} +} \ No newline at end of file diff --git a/frameworks/ani/notification_manager/src/sts_notification_flags.cpp b/frameworks/ani/notification_manager/src/sts_notification_flags.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cb4be48b1c899775cd9ccc49a65a5004eacb6ad1 --- /dev/null +++ b/frameworks/ani/notification_manager/src/sts_notification_flags.cpp @@ -0,0 +1,54 @@ +/* + * 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 "notification_constant.h" +#include "sts_notification_enum_type.h" +#include "ans_log_wrapper.h" +#include "sts_notification_utils.h" + +namespace OHOS { +namespace NotificationSts { +using FlagStatus = OHOS::Notification::NotificationConstant::FlagStatus; +void UnwrapNotificationFlags(ani_env *env, ani_object aniObj, NotificationFlags& flags) +{ + ani_ref soundEnabledRef; + FlagStatus soundEnabled {FlagStatus::NONE}; + if (ANI_OK == env->Object_CallMethodByName_Ref(aniObj, + "soundEnabled", + ":L@ohos/notification/notificationFlags/NotificationFlagStatus;", + &soundEnabledRef)) { + if (EnumConvertAniToNative(env, static_cast(soundEnabledRef), soundEnabled)) { + flags.SetSoundEnabled(soundEnabled); + } + } + + ani_ref vibrationEnabledRef; + FlagStatus vibrationEnabled {FlagStatus::NONE}; + if (ANI_OK == env->Object_CallMethodByName_Ref(aniObj, + "vibrationEnabled", + ":L@ohos/notification/notificationFlags/NotificationFlagStatus;", + &vibrationEnabledRef)) { + if (EnumConvertAniToNative(env, static_cast(vibrationEnabledRef), vibrationEnabled)) { + flags.SetVibrationEnabled(vibrationEnabled); + } + } + + ani_int reminderFlagsRef; + if (ANI_OK == env->Object_CallMethodByName_Int(aniObj, "reminderFlags", nullptr, &reminderFlagsRef)) { + flags.SetReminderFlags(reminderFlagsRef); + } +} +} +} \ No newline at end of file diff --git a/frameworks/ani/notification_manager/src/sts_notification_manager.cpp b/frameworks/ani/notification_manager/src/sts_notification_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7e65e47ed3d4afc4b1ebec7e18913b4cb385d432 --- /dev/null +++ b/frameworks/ani/notification_manager/src/sts_notification_manager.cpp @@ -0,0 +1,659 @@ +/* + * 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 "ans_log_wrapper.h" +#include "sts_notification_manager.h" +#include "sts_common_util.h" +#include "sts_bundle_option.h" +#include "notification_bundle_option.h" +#include "notification_helper.h" +#include "sts_notification_enum_type.h" +#include "sts_notification_slot.h" +#include "notification_slot.h" +#include "notification_constant.h" +#include "uri.h" +#include "inner_errors.h" +#include "sts_do_not_disturb_profile.h" +#include "sts_error_utils.h" +#include "ans_inner_errors.h" +#include "sts_notification_request.h" + +using namespace OHOS::NotificationSts; +namespace OHOS { +namespace NotificationManagerSts { + +static void DisplayBadge(ani_env *env, ani_object obj, ani_boolean enable) +{ + ANS_LOGD("sts DisplayBadge call"); + int returncode = -1; + Notification::NotificationBundleOption option; + bool bFlag = UnwrapBundleOption(env, obj, option); + ANS_LOGD("sts DisplayBadge option bundleName: %{public}s, uid: %{public}d, bFlag: %{public}d", option.GetBundleName().c_str(), + option.GetUid(), bFlag); + if(bFlag) { + returncode = Notification::NotificationHelper::SetShowBadgeEnabledForBundle(option, AniBooleanToBool(enable)); + } else { + OHOS::AbilityRuntime::ThrowStsError(env, OHOS::Notification::ERROR_INTERNAL_ERROR, + FindAnsErrMsg(OHOS::Notification::ERROR_INTERNAL_ERROR)); + ANS_LOGE("sts DisplayBadge ERROR_INTERNAL_ERROR"); + return; + } + int externalCode = CJSystemapi::Notification::ErrorToExternal(returncode); + if (externalCode != ERR_OK) { + OHOS::AbilityRuntime::ThrowStsError(env, externalCode, FindAnsErrMsg(externalCode)); + ANS_LOGE("sts DisplayBadge error, errorCode: %{public}d", externalCode); + return; + } + ANS_LOGD("sts DisplayBadge end, ret: %{public}d", externalCode); +} + +static ani_boolean IsBadgeDisplayed(ani_env *env, ani_object obj) +{ + ANS_LOGD("sts IsBadgeDisplayed call"); + int returncode = -1; + bool isDisplayed = false; + if (obj == nullptr) { + returncode = Notification::NotificationHelper::GetShowBadgeEnabled(isDisplayed); + } else { + Notification::NotificationBundleOption option; + bool bFlag = UnwrapBundleOption(env, obj, option); + ANS_LOGD("sts IsBadgeDisplayed option bundleName: %{public}s, uid: %{public}d, bFlag: %{public}d", option.GetBundleName().c_str(), + option.GetUid(), bFlag); + if(bFlag) { + returncode = Notification::NotificationHelper::GetShowBadgeEnabledForBundle(option, isDisplayed); + } else { + OHOS::AbilityRuntime::ThrowStsError(env, OHOS::Notification::ERROR_INTERNAL_ERROR, + FindAnsErrMsg(OHOS::Notification::ERROR_INTERNAL_ERROR)); + ANS_LOGE("sts IsBadgeDisplayed ERROR_INTERNAL_ERROR"); + return BoolToAniBoolean(false); + } + } + + int externalCode = CJSystemapi::Notification::ErrorToExternal(returncode); + if (externalCode != ERR_OK) { + OHOS::AbilityRuntime::ThrowStsError(env, externalCode, FindAnsErrMsg(externalCode)); + ANS_LOGE("sts IsBadgeDisplayed error, errorCode: %{public}d", externalCode); + return BoolToAniBoolean(false); + } + ANS_LOGD("sts IsBadgeDisplayed end, isDisplayed: %{public}d, returncode: %{public}d", isDisplayed, + externalCode); + return BoolToAniBoolean(isDisplayed); +} + +static ani_double GetActiveNotificationCount(ani_env *env) +{ + ANS_LOGD("sts GetActiveNotificationCount call"); + uint64_t num = 0; + OHOS::Notification::NotificationHelper::GetActiveNotificationNums(num); + ANS_LOGD("sts GetActiveNotificationCount end, num: %{public}llu", num); + ani_double retNum = static_cast(num); + return retNum; +} + +static ani_boolean isNotificationEnabled([[maybe_unused]]ani_env *env, ani_object jsUserId, ani_object jsBundleOption) +{ + int32_t userId = 0; + bool allowed = false; + int32_t ret = 0; + int externalCode = 0; + ani_boolean isUserIdUndefined = ANI_FALSE; + ani_boolean isBundleUndefined = ANI_FALSE; + + ANS_LOGD("isNotificationEnabled enter"); + + if ((env->Reference_IsUndefined(jsUserId, &isUserIdUndefined) != ANI_OK) || + (env->Reference_IsUndefined(jsBundleOption, &isBundleUndefined) != ANI_OK)) { + ANS_LOGI("isNotificationEnabled Reference_IsUndefined error"); + externalCode = CJSystemapi::Notification::ERROR_INTERNAL_ERROR; + OHOS::AbilityRuntime::ThrowStsError(env, externalCode, FindAnsErrMsg(externalCode)); + return BoolToAniBoolean(allowed); + } + + ANS_LOGD("isNotificationEnabled isUserIdUndefined = %{public}d isBundleUndefined = %{public}d", + isUserIdUndefined, isBundleUndefined); + + if (!isUserIdUndefined) { + ANS_LOGD("isNotificationEnabled ==>> isUserIdUndefined"); + if (ANI_OK !=env->Object_CallMethodByName_Int(jsUserId, "intValue", nullptr, &userId)) { + ANS_LOGI("isNotificationEnabled Object_CallMethodByName_Int Fail"); + externalCode = CJSystemapi::Notification::ERROR_INTERNAL_ERROR; + OHOS::AbilityRuntime::ThrowStsError(env, externalCode, FindAnsErrMsg(externalCode)); + return BoolToAniBoolean(allowed); + } + + ANS_LOGD("isNotificationEnabled IsAllowedNotify userId = %{public}d", userId); + ret = Notification::NotificationHelper::IsAllowedNotify(userId, allowed); + } else if (!isBundleUndefined) { + ANS_LOGD("isNotificationEnabled ==>> isBundleUndefined"); + Notification::NotificationBundleOption option; + if (!UnwrapBundleOption(env, jsBundleOption, option)) { + ANS_LOGI("isNotificationEnabled:: isBundleUndefined. UnwrapBundleOption ERROR"); + externalCode = CJSystemapi::Notification::ERROR_INTERNAL_ERROR; + OHOS::AbilityRuntime::ThrowStsError(env, externalCode, FindAnsErrMsg(externalCode)); + return BoolToAniBoolean(allowed); + } + ANS_LOGD("uid = %{public}d, bundle = %{public}s", option.GetUid(), option.GetBundleName().c_str()); + ret = Notification::NotificationHelper::IsAllowedNotify(option, allowed); + } else { + ANS_LOGD("isNotificationEnabled ==>> no parameter"); + ret = Notification::NotificationHelper::IsAllowedNotify(allowed); + } + ANS_LOGI("isNotificationEnabled IsAllowedNotify ret = %{public}d allowed = %{public}d", ret, allowed); + + if (ret != ANI_OK) { + int err = CJSystemapi::Notification::ErrorToExternal(ret); + OHOS::AbilityRuntime::ThrowStsError(env, err, FindAnsErrMsg(err)); + allowed = false; + } else { + allowed ? (allowed = true) : (allowed = false); + } + return BoolToAniBoolean(allowed); +} + +static ani_int GetSlotFlagsByBundle(ani_env *env, ani_object obj) +{ + ANS_LOGD("sts getSlotFlagsByBundle call"); + Notification::NotificationBundleOption option; + bool bFlag = UnwrapBundleOption(env, obj, option); + if (!bFlag) { + OHOS::AbilityRuntime::ThrowStsError(env, OHOS::Notification::ERROR_INTERNAL_ERROR, + FindAnsErrMsg(OHOS::Notification::ERROR_INTERNAL_ERROR)); + ANS_LOGE("sts getSlotFlagsByBundle ERROR_INTERNAL_ERROR"); + return ERROR_INTERNAL_ERROR; + } + uint32_t slotFlags = 0; + int returncode = Notification::NotificationHelper::GetNotificationSlotFlagsAsBundle(option, slotFlags); + int externalCode = CJSystemapi::Notification::ErrorToExternal(returncode); + if (externalCode != 0) { + OHOS::AbilityRuntime::ThrowStsError(env, externalCode, FindAnsErrMsg(externalCode)); + ANS_LOGE("sts getSlotFlagsByBundle error, errorCode: %{public}d", externalCode); + return ERROR_INTERNAL_ERROR; + } + ANS_LOGI("sts getSlotFlagsByBundle end, slotFlags: %{public}d, ret: %{public}d", slotFlags, externalCode); + return slotFlags; +} + +static void SetSlotFlagsByBundle(ani_env *env, ani_object obj) +{ + ANS_LOGD("sts setSlotFlagsByBundle call"); + Notification::NotificationBundleOption option; + bool bFlag = UnwrapBundleOption(env, obj, option); + if (!bFlag) { + OHOS::AbilityRuntime::ThrowStsError(env, OHOS::Notification::ERROR_INTERNAL_ERROR, + FindAnsErrMsg(OHOS::Notification::ERROR_INTERNAL_ERROR)); + ANS_LOGE("sts setSlotFlagsByBundle ERROR_INTERNAL_ERROR"); + return; + } + uint32_t slotFlags = 0; + int returncode = Notification::NotificationHelper::SetNotificationSlotFlagsAsBundle(option, slotFlags); + int externalCode = CJSystemapi::Notification::ErrorToExternal(returncode); + if (externalCode != 0) { + OHOS::AbilityRuntime::ThrowStsError(env, externalCode, FindAnsErrMsg(externalCode)); + ANS_LOGE("sts setSlotFlagsByBundle error, errorCode: %{public}d", externalCode); + return; + } + ANS_LOGD("sts setSlotFlagsByBundle end, ret: %{public}d", externalCode); + return; +} + +static void SetNotificationEnable(ani_env *env, ani_object bundleOption, ani_boolean enable) +{ + ANS_LOGD("setNotificationEnable enter "); + Notification::NotificationBundleOption option; + bool bFlag = UnwrapBundleOption(env, bundleOption, option); + ANS_LOGD("setNotificationEnable option bundleName: %{public}s, uid: %{public}d, bFlag: %{public}d", + option.GetBundleName().c_str(), option.GetUid(), bFlag); + std::string deviceId {""}; + int returncode = -1; + if(bFlag) { + returncode = Notification::NotificationHelper::SetNotificationsEnabledForSpecifiedBundle(option, deviceId, + AniBooleanToBool(enable)); + } else { + OHOS::AbilityRuntime::ThrowStsError(env, OHOS::Notification::ERROR_INTERNAL_ERROR, + FindAnsErrMsg(OHOS::Notification::ERROR_INTERNAL_ERROR)); + ANS_LOGE("setNotificationEnable ERROR_INTERNAL_ERROR"); + return; + } + int externalCode = CJSystemapi::Notification::ErrorToExternal(returncode); + if (externalCode != 0) { + OHOS::AbilityRuntime::ThrowStsError(env, externalCode, FindAnsErrMsg(externalCode)); + ANS_LOGE("setNotificationEnable error, errorCode: %{public}d", externalCode); + return; + } + ANS_LOGD("setNotificationEnable end, externalCode: %{public}d", externalCode); +} + +static ani_boolean IsNotificationSlotEnabled(ani_env *env, ani_object bundleOption, ani_enum_item type) +{ + ANS_LOGD("isNotificationSlotEnabledSync enter"); + Notification::NotificationBundleOption option; + + bool bFlag = UnwrapBundleOption(env, bundleOption, option); + if(bFlag != true) { + OHOS::AbilityRuntime::ThrowStsError(env, OHOS::Notification::ERROR_INTERNAL_ERROR, + FindAnsErrMsg(OHOS::Notification::ERROR_INTERNAL_ERROR)); + ANS_LOGE("unwrapBundleOption error ERROR_INTERNAL_ERROR"); + return BoolToAniBoolean(false); + } + ANS_LOGD("setNotificationEnable option bundleName: %{public}s, uid: %{public}d, bFlag: %{public}d", + option.GetBundleName().c_str(), option.GetUid(), bFlag); + + + Notification::NotificationConstant::SlotType slotType = Notification::NotificationConstant::SlotType::OTHER; + bFlag = NotificationSts::SlotTypeEtsToC(env, type, slotType); + if(bFlag != true) { + OHOS::AbilityRuntime::ThrowStsError(env, OHOS::Notification::ERROR_INTERNAL_ERROR, + FindAnsErrMsg(OHOS::Notification::ERROR_INTERNAL_ERROR)); + ANS_LOGE("slotTypeEtsToC error ERROR_INTERNAL_ERROR"); + return BoolToAniBoolean(false); + } + + bool isEnable = false; + int returncode = Notification::NotificationHelper::GetEnabledForBundleSlot(option, slotType, isEnable); + int externalCode = CJSystemapi::Notification::ErrorToExternal(returncode); + if (externalCode != 0) { + OHOS::AbilityRuntime::ThrowStsError(env, externalCode, FindAnsErrMsg(externalCode)); + ANS_LOGE("isNotificationSlotEnabledSync error, errorCode: %{public}d", externalCode); + return BoolToAniBoolean(false); + } + ANS_LOGD("isNotificationSlotEnabledSync end, isEnable: %{public}d, externalCode: %{public}d", isEnable, externalCode); + return isEnable ? ANI_TRUE : ANI_FALSE; +} + +static void CancelWithId(ani_env* env, ani_double id) +{ + ANS_LOGD("sts CancelWithId call, id:%{public}lf", id); + int32_t ret = Notification::NotificationHelper::CancelNotification(static_cast(id)); + int externalCode = CJSystemapi::Notification::ErrorToExternal(ret); + if (externalCode != ERR_OK) { + OHOS::AbilityRuntime::ThrowStsError(env, externalCode, FindAnsErrMsg(externalCode)); + ANS_LOGE("sts CancelWithId error, errorCode: %{public}d", externalCode); + return; + } + ANS_LOGD("sts CancelWithId end, externalCode: %{public}d", externalCode); +} + +static void CancelWithIdOptinalLabel(ani_env* env, ani_double id, ani_string label) +{ + ANS_LOGD("sts CancelWithIdOptinalLabel call, id:%{public}lf", id); + ani_boolean isUndefined = ANI_FALSE; + env->Reference_IsUndefined(label, &isUndefined); + int32_t ret = -1; + if(isUndefined) { + ANS_LOGE("sts CancelWithIdOptinalLabel the label is undefined"); + ret = Notification::NotificationHelper::CancelNotification(static_cast(id)); + } else { + std::string labelStr; + if (ANI_OK != GetStdString(env, label, labelStr)) { + OHOS::AbilityRuntime::ThrowStsError(env, OHOS::Notification::ERROR_INTERNAL_ERROR, + FindAnsErrMsg(OHOS::Notification::ERROR_INTERNAL_ERROR)); + ANS_LOGE("sts CancelWithIdOptinalLabel ERROR_INTERNAL_ERROR"); + return; + } + ANS_LOGD("sts CancelWithIdOptinalLabel id:%{public}lf label:%{public}s", id, labelStr.c_str()); + ret = Notification::NotificationHelper::CancelNotification(labelStr, id); + } + int externalCode = CJSystemapi::Notification::ErrorToExternal(ret); + if (externalCode != ERR_OK) { + OHOS::AbilityRuntime::ThrowStsError(env, externalCode, FindAnsErrMsg(externalCode)); + ANS_LOGE("sts CancelWithIdOptinalLabel error, errorCode: %{public}d", externalCode); + return; + } + ANS_LOGD("sts CancelWithIdOptinalLabel end, externalCode: %{public}d", externalCode); +} + +static void CancelWithIdLabel(ani_env* env, ani_double id, ani_string label) +{ + ANS_LOGD("sts CancelWithIdLabel call, id:%{public}lf", id); + std::string labelStr; + if (ANI_OK != GetStdString(env, label, labelStr)) { + OHOS::AbilityRuntime::ThrowStsError(env, OHOS::Notification::ERROR_INTERNAL_ERROR, + FindAnsErrMsg(OHOS::Notification::ERROR_INTERNAL_ERROR)); + ANS_LOGE("sts CancelWithIdLabel ERROR_INTERNAL_ERROR"); + return; + } + ANS_LOGD("sts CancelWithIdLabel id:%{public}lf label:%{public}s", id, labelStr.c_str()); + int32_t ret = Notification::NotificationHelper::CancelNotification(labelStr, static_cast(id)); + int externalCode = CJSystemapi::Notification::ErrorToExternal(ret); + if (externalCode != ERR_OK) { + OHOS::AbilityRuntime::ThrowStsError(env, externalCode, FindAnsErrMsg(externalCode)); + ANS_LOGE("sts CancelWithIdLabel error, errorCode: %{public}d", externalCode); + return; + } + ANS_LOGD("sts CancelWithIdLabel end, externalCode: %{public}d", externalCode); +} + +static void CancelWithBundle(ani_env* env, ani_object bundleObj, ani_double id) +{ + ANS_LOGD("sts CancelWithBundle call, id: %{public}lf", id); + int returncode = -1; + Notification::NotificationBundleOption option; + bool bFlag = UnwrapBundleOption(env, bundleObj, option); + ANS_LOGD("sts CancelWithBundle option bundleName: %{public}s, uid: %{public}d, bFlag: %{public}d", option.GetBundleName().c_str(), + option.GetUid(), bFlag); + if(bFlag) { + returncode = Notification::NotificationHelper::CancelAsBundleWithAgent(option, static_cast(id)); + } else { + OHOS::AbilityRuntime::ThrowStsError(env, OHOS::Notification::ERROR_INTERNAL_ERROR, + FindAnsErrMsg(OHOS::Notification::ERROR_INTERNAL_ERROR)); + ANS_LOGE("sts CancelWithBundle ERROR_INTERNAL_ERROR"); + return; + } + int externalCode = CJSystemapi::Notification::ErrorToExternal(returncode); + if (externalCode != ERR_OK) { + OHOS::AbilityRuntime::ThrowStsError(env, externalCode, FindAnsErrMsg(externalCode)); + ANS_LOGE("sts CancelWithBundle error, errorCode: %{public}d", externalCode); + return; + } + ANS_LOGD("sts CancelWithBundle end, ret: %{public}d", externalCode); +} + +static void CancelAll(ani_env* env) +{ + ANS_LOGD("sts CancelAll call"); + int32_t ret = Notification::NotificationHelper::CancelAllNotifications(); + int externalCode = CJSystemapi::Notification::ErrorToExternal(ret); + if (externalCode != ERR_OK) { + OHOS::AbilityRuntime::ThrowStsError(env, externalCode, FindAnsErrMsg(externalCode)); + ANS_LOGE("sts CancelAll error, errorCode: %{public}d", externalCode); + return; + } + ANS_LOGD("sts CancelAll end, ret: %{public}d", externalCode); +} + +static ani_ref GetSlotsByBundle(ani_env *env, ani_object bundleOption) +{ + ANS_LOGD("sts GetSlotsByBundle enter"); + int returncode = -1; + std::vector> slots; + Notification::NotificationBundleOption option; + bool bFlag = UnwrapBundleOption(env, bundleOption, option); + ANS_LOGD("sts GetSlotsByBundle option bundleName: %{public}s, uid: %{public}d, bFlag: %{public}d", option.GetBundleName().c_str(), + option.GetUid(), bFlag); + if(bFlag) { + returncode = Notification::NotificationHelper::GetNotificationSlotsForBundle(option, slots); + } else { + OHOS::AbilityRuntime::ThrowStsError(env, OHOS::Notification::ERROR_INTERNAL_ERROR, + FindAnsErrMsg(OHOS::Notification::ERROR_INTERNAL_ERROR)); + ANS_LOGE("sts GetSlotsByBundle ERROR_INTERNAL_ERROR"); + return nullptr; + } + + int externalCode = CJSystemapi::Notification::ErrorToExternal(returncode); + if (externalCode != ERR_OK) { + OHOS::AbilityRuntime::ThrowStsError(env, externalCode, FindAnsErrMsg(externalCode)); + ANS_LOGE("sts GetSlotsByBundle error, errorCode: %{public}d", externalCode); + return nullptr; + } + ani_object outAniObj; + WrapNotificationSlotArray(env, slots, outAniObj); + ANS_LOGD("sts GetSlotsByBundle end, ret: %{public}d", externalCode); + return outAniObj; +} + +static void AddDoNotDisturbProfile(ani_env *env, ani_object obj) +{ + ANS_LOGD("sts addDoNotDisturbProfile call"); + std::vector> profiles; + bool bFlag = UnwrapArrayDoNotDisturbProfile(env, obj, profiles); + if (!bFlag) { + OHOS::AbilityRuntime::ThrowStsError(env, OHOS::Notification::ERROR_INTERNAL_ERROR, + FindAnsErrMsg(OHOS::Notification::ERROR_INTERNAL_ERROR)); + ANS_LOGE("sts addDoNotDisturbProfile ERROR_INTERNAL_ERROR"); + return; + } + int returncode = Notification::NotificationHelper::AddDoNotDisturbProfiles(profiles); + int externalCode = CJSystemapi::Notification::ErrorToExternal(returncode); + if (externalCode != 0) { + OHOS::AbilityRuntime::ThrowStsError(env, externalCode, FindAnsErrMsg(externalCode)); + ANS_LOGE("sts addDoNotDisturbProfile error, errorCode: %{public}d", externalCode); + return; + } + ANS_LOGD("sts addDoNotDisturbProfile end, ret: %{public}d", externalCode); + return; +} + +static void RemoveDoNotDisturbProfile(ani_env *env, ani_object obj) +{ + ANS_LOGD("sts removeDoNotDisturbProfile call"); + std::vector> profiles; + bool bFlag = UnwrapArrayDoNotDisturbProfile(env, obj, profiles); + if (!bFlag) { + OHOS::AbilityRuntime::ThrowStsError(env, OHOS::Notification::ERROR_INTERNAL_ERROR, + FindAnsErrMsg(OHOS::Notification::ERROR_INTERNAL_ERROR)); + ANS_LOGE("sts removeDoNotDisturbProfile ERROR_INTERNAL_ERROR"); + return; + } + int returncode = Notification::NotificationHelper::RemoveDoNotDisturbProfiles(profiles); + int externalCode = CJSystemapi::Notification::ErrorToExternal(returncode); + if (externalCode != 0) { + OHOS::AbilityRuntime::ThrowStsError(env, externalCode, FindAnsErrMsg(externalCode)); + ANS_LOGE("sts removeDoNotDisturbProfile error, errorCode: %{public}d", externalCode); + return; + } + ANS_LOGD("sts removeDoNotDisturbProfile end, ret: %{public}d", externalCode); + return; +} + +static void SetNotificationEnableSlot(ani_env *env, ani_object bundleOption, ani_enum_item type, ani_boolean enable, + ani_object isForceControl) +{ + ANS_LOGD("setNotificationEnableSlot enter "); + ani_boolean isUndefined = false; + ani_boolean res = 0.0; + Notification::NotificationBundleOption option; + bool bFlag = UnwrapBundleOption(env, bundleOption, option); + if(bFlag != true) { + OHOS::AbilityRuntime::ThrowStsError(env, OHOS::Notification::ERROR_INTERNAL_ERROR, + FindAnsErrMsg(OHOS::Notification::ERROR_INTERNAL_ERROR)); + ANS_LOGE("unwrapBundleOption error ERROR_INTERNAL_ERROR"); + return; + } + ANS_LOGD("setNotificationEnableSlot option bundleName: %{public}s, uid: %{public}d, bFlag: %{public}d", + option.GetBundleName().c_str(), option.GetUid(), bFlag); + Notification::NotificationConstant::SlotType slotType = Notification::NotificationConstant::SlotType::OTHER; + bFlag = NotificationSts::SlotTypeEtsToC(env, type, slotType); + if(bFlag != true) { + OHOS::AbilityRuntime::ThrowStsError(env, OHOS::Notification::ERROR_INTERNAL_ERROR, + FindAnsErrMsg(OHOS::Notification::ERROR_INTERNAL_ERROR)); + ANS_LOGE("slotTypeEtsToC error ERROR_INTERNAL_ERROR"); + return; + } + env->Reference_IsUndefined(isForceControl, &isUndefined); + int returncode = 0; + if(isUndefined) { + bool forceControl = false; + returncode = Notification::NotificationHelper::SetEnabledForBundleSlot(option, slotType, AniBooleanToBool(enable), + forceControl); + ANS_LOGD("setNotificationEnableSlot end, returncode: %{public}d", + CJSystemapi::Notification::ErrorToExternal(returncode)); + return; + } else { + if (ANI_OK !=env->Object_CallMethodByName_Boolean(isForceControl, "booleanValue", nullptr, &res)){ + ANS_LOGD("setNotificationEnableSlot Object_CallMethodByName_Boolean Fail"); + } + } + returncode = Notification::NotificationHelper::SetEnabledForBundleSlot(option, slotType, AniBooleanToBool(enable), + AniBooleanToBool(res)); + int externalCode = CJSystemapi::Notification::ErrorToExternal(returncode); + if (externalCode != 0) { + OHOS::AbilityRuntime::ThrowStsError(env, externalCode, FindAnsErrMsg(externalCode)); + ANS_LOGE("setNotificationEnableSlot error, errorCode: %{public}d", externalCode); + return; + } + ANS_LOGD("setNotificationEnableSlot end, externalCode: %{public}d", externalCode); +} + +static void SetNotificationEnableSlotByOld(ani_env *env, ani_object bundleOption, ani_enum_item type, ani_boolean enable) +{ + ANS_LOGD("setNotificationEnableSlotByOld enter "); + Notification::NotificationBundleOption option; + bool bFlag = UnwrapBundleOption(env, bundleOption, option); + if(bFlag != true) { + OHOS::AbilityRuntime::ThrowStsError(env, OHOS::Notification::ERROR_INTERNAL_ERROR, + FindAnsErrMsg(OHOS::Notification::ERROR_INTERNAL_ERROR)); + ANS_LOGE("unwrapBundleOption error ERROR_INTERNAL_ERROR"); + return; + } + ANS_LOGD("setNotificationEnableSlotByOld option bundleName: %{public}s, uid: %{public}d, bFlag: %{public}d", + option.GetBundleName().c_str(), option.GetUid(), bFlag); + + Notification::NotificationConstant::SlotType slotType = Notification::NotificationConstant::SlotType::OTHER; + bFlag = NotificationSts::SlotTypeEtsToC(env, type, slotType); + if(bFlag != true) { + OHOS::AbilityRuntime::ThrowStsError(env, OHOS::Notification::ERROR_INTERNAL_ERROR, + FindAnsErrMsg(OHOS::Notification::ERROR_INTERNAL_ERROR)); + ANS_LOGE("slotTypeEtsToC error ERROR_INTERNAL_ERROR"); + return; + } + bool isForceControl = false; + int returncode = Notification::NotificationHelper::SetEnabledForBundleSlot(option, slotType, AniBooleanToBool(enable), + isForceControl); + int externalCode = CJSystemapi::Notification::ErrorToExternal(returncode); + if (externalCode != 0) { + OHOS::AbilityRuntime::ThrowStsError(env, externalCode, FindAnsErrMsg(externalCode)); + ANS_LOGE("setNotificationEnableSlotByOld error, errorCode: %{public}d", externalCode); + return; + } + ANS_LOGD("setNotificationEnableSlotByOld end, externalCode: %{public}d", externalCode); +} + +static ani_object NativeGetAllActiveNotifications(ani_env *env, [[maybe_unused]]ani_class aniClass) +{ + std::vector> notifications; + int32_t ret = NotificationHelper::GetAllActiveNotifications(notifications); + if (ret!= ERR_OK) { + ANS_LOGE("GetAllActiveNotifications failed, ret = %{public}d", ret); + return nullptr; + } + + ani_object arrayObject = NotificationSts::ConvertNotificationArrayToAni(env, notifications); + if (arrayObject == nullptr) { + ANS_LOGE("ConvertNotificationArrayToAni failed"); + return nullptr; + } + return arrayObject; +} + +static void NativePublish(ani_env *env, [[maybe_unused]]ani_class aniClass, ani_object obj) +{ + std::shared_ptr notificationRequest = std::make_shared(); + if (UnWarpNotificationRequest(env, obj, notificationRequest) != ANI_OK) { + ANS_LOGE("UnWarpNotificationRequest failed"); + return; + } + int32_t ret = NotificationHelper::PublishNotification(*notificationRequest); + if (ret != 0) { + ANS_LOGE("PublishNotification failed, return ret = %{public}d", ret); + } + ANS_LOGD("NativePublish leave"); +} + +static void NativePublishIncludeUserId(ani_env *env, [[maybe_unused]]ani_class aniClass, ani_object obj, + ani_double userId) +{ + //NotificationRequest request; + std::shared_ptr notificationRequest = std::make_shared(); + if (UnWarpNotificationRequest(env, obj, notificationRequest) != ANI_OK) { + ANS_LOGE("UnWarpNotificationRequest failed"); + return; + } + notificationRequest->SetOwnerUserId(static_cast(userId)); + int32_t ret = NotificationHelper::PublishNotification(*notificationRequest); + if (ret != 0) { + ANS_LOGE("PublishNotification failed, return ret = %{public}d", ret); + } + ANS_LOGD("NativePublishIncludeUserId leave"); + +} + +void StsNotificationManagerRegistryInit(ani_env *env) +{ + ANS_LOGD("StsNotificationManagerRegistryInit call"); + ani_status status = ANI_ERROR; + if (env->ResetError() != ANI_OK) { + ANS_LOGD("ResetError failed"); + } + + ani_namespace ns; + status = env->FindNamespace("L@ohos/notificationManager/notificationManager;", &ns); + if (status != ANI_OK) { + ANS_LOGD("FindNamespace notificationManager failed status : %{public}d", status); + return; + } + + std::array kitFunctions = { + ani_native_function {"nativeDisplayBadge", nullptr, reinterpret_cast(DisplayBadge)}, + ani_native_function {"nativeIsBadgeDisplayed", nullptr, reinterpret_cast(IsBadgeDisplayed)}, + ani_native_function {"nativeGetActiveNotificationCount", ":D", + reinterpret_cast(GetActiveNotificationCount)}, + ani_native_function {"nativeIsNotificationEnabled", nullptr, reinterpret_cast(isNotificationEnabled)}, + ani_native_function {"nativegetSlotFlagsByBundle", nullptr, reinterpret_cast(GetSlotFlagsByBundle)}, + ani_native_function {"nativesetSlotFlagsByBundle", nullptr, reinterpret_cast(SetSlotFlagsByBundle)}, + ani_native_function {"nativeSetNotificationEnable", nullptr, reinterpret_cast(SetNotificationEnable)}, + ani_native_function {"nativeIsNotificationSlotEnabled", nullptr, + reinterpret_cast(IsNotificationSlotEnabled)}, + ani_native_function {"nativeCancelWithId", nullptr, reinterpret_cast(CancelWithId)}, + ani_native_function {"nativeCancelWithIdLabel", nullptr, reinterpret_cast(CancelWithIdLabel)}, + ani_native_function {"nativeCancelWithIdOptionalLabel", nullptr, reinterpret_cast(CancelWithIdOptinalLabel)}, + ani_native_function {"nativeCancelWithBundle", nullptr, reinterpret_cast(CancelWithBundle)}, + ani_native_function {"nativeCancelAll", nullptr, reinterpret_cast(CancelAll)}, + ani_native_function {"nativeGetSlotsByBundle", nullptr, reinterpret_cast(GetSlotsByBundle)}, + ani_native_function {"nativeaddDoNotDisturbProfile", nullptr, reinterpret_cast(AddDoNotDisturbProfile)}, + ani_native_function {"nativeremoveDoNotDisturbProfile", nullptr, reinterpret_cast(RemoveDoNotDisturbProfile)}, + ani_native_function {"nativeSetNotificationEnableSlot", nullptr, reinterpret_cast(SetNotificationEnableSlot)}, + ani_native_function {"nativeSetNotificationEnableSlotByOld", nullptr, + reinterpret_cast(SetNotificationEnableSlotByOld)}, + ani_native_function {"nativeGetAllActiveNotifications", nullptr, + reinterpret_cast(NativeGetAllActiveNotifications)}, + ani_native_function {"nativePublishIncludeUserId", nullptr, reinterpret_cast(NativePublishIncludeUserId)}, + ani_native_function {"nativePublish", nullptr, reinterpret_cast(NativePublish)}, + + }; + + status = env->Namespace_BindNativeFunctions(ns, kitFunctions.data(), kitFunctions.size()); + if (status != ANI_OK) { + ANS_LOGD("Namespace_BindNativeFunctions failed status : %{public}d", status); + } + + if (env->ResetError() != ANI_OK) { + ANS_LOGD("ResetError failed"); + } + + ANS_LOGD("StsNotificationManagerRegistryInit end"); +} + +} +} + + +extern "C" { +ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) +{ + ANS_LOGD("ANI_Constructor"); + ani_env *env = nullptr; + ani_status status = ANI_ERROR; + status = vm->GetEnv(ANI_VERSION_1, &env); + if (status != ANI_OK) { + ANS_LOGD("GetEnv failed status : %{public}d", status); + return ANI_NOT_FOUND; + } + + OHOS::NotificationManagerSts::StsNotificationManagerRegistryInit(env); + *result = ANI_VERSION_1; + ANS_LOGD("ANI_Constructor finish"); + return ANI_OK; +} +} \ No newline at end of file diff --git a/frameworks/ani/notification_manager/src/sts_notification_request.cpp b/frameworks/ani/notification_manager/src/sts_notification_request.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c1894b2c556da20e01c1cb410bbb48365b401a36 --- /dev/null +++ b/frameworks/ani/notification_manager/src/sts_notification_request.cpp @@ -0,0 +1,1282 @@ +/* + * 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 "sts_notification_utils.h" +#include "sts_common_util.h" +#include "sts_notification_enum_type.h" +#include "ani_common_want.h" +#include "want_params.h" +#include "want_agent.h" +#include "sts_notification_request.h" +#include "notification_distributed_options.h" +#include "notification_constant.h" +#include "notification.h" +#include "pixel_map_ani.h" +#include "notification_template.h" +#include "ans_convert_enum.h" +#include "ani_common_want_agent.h" + +namespace OHOS { +namespace NotificationSts { +using namespace OHOS::AppExecFwk; +using namespace OHOS::AAFwk; +using WantAgent = OHOS::AbilityRuntime::WantAgent::WantAgent; + +bool SetNotificationRequestByString(ani_env* env, ani_class cls, const OHOS::Notification::NotificationRequest *request, + ani_object &object) +{ + if (request == nullptr) { + ANS_LOGE("request is nullptr"); + return false; + } + ani_string stringValue = nullptr; + // classification?: string + if (GetAniString(env, request->GetClassification(), stringValue)) { + CallSetterOptional(env, cls, object, "classification", stringValue); + } + // need to do ets中没有找到statusBarText属性 + // statusBarText?: string + // if (StringToAniStr(env, request->GetStatusBarText(), stringValue)) { + // RETURN_FALSE_IF_FALSE(CallSetterOptional(env, cls, object, STATUS_BAR_TEXT, stringValue)); + // } + // label?: string + if (GetAniString(env, request->GetLabel(), stringValue)) { + CallSetterOptional(env, cls, object, "label", stringValue); + } + // groupName?: string + if (GetAniString(env, request->GetGroupName(), stringValue)) { + CallSetterOptional(env, cls, object, "groupName", stringValue); + } + // readonly creatorBundleName?: string + if (GetAniString(env, request->GetCreatorBundleName(), stringValue)) { + CallSetterOptional(env, cls, object, "creatorBundleName", stringValue); + } + // readonly sound?: string + if (GetAniString(env, request->GetSound(), stringValue)) { + CallSetterOptional(env, cls, object, "sound", stringValue); + } + // readonly appInstanceKey?: string + if (GetAniString(env, request->GetAppInstanceKey(), stringValue)) { + CallSetterOptional(env, cls, object, "appInstanceKey", stringValue); + } + return true; +} + +bool SetNotificationRequestByNumber(ani_env* env, ani_class cls, const OHOS::Notification::NotificationRequest *request, + ani_object &object) +{ + if (request == nullptr) { + ANS_LOGE("request is nullptr"); + return false; + } + // id?: number + CallSetterOptional(env, cls, object, "id", request->GetNotificationId()); + // slotType?: SlotType + ani_enum_item slotTypeItem {}; + if(SlotTypeCToEts(env, request->GetSlotType(), slotTypeItem)) { + CallSetterOptional(env, cls, object, "slotType", slotTypeItem); + } + + // deliveryTime?: number + CallSetterOptional(env, cls, object, "deliveryTime", request->GetDeliveryTime()); + // autoDeletedTime?: number + CallSetterOptional(env, cls, object, "autoDeletedTime", request->GetAutoDeletedTime()); + // color ?: number + CallSetterOptional(env, cls, object, "color", request->GetColor()); + // badgeIconStyle ?: number + CallSetterOptional(env, cls, object, "badgeIconStyle", + static_cast(request->GetBadgeIconStyle())); + // readonly creatorUid?: number + CallSetterOptional(env, cls, object, "creatorUid", request->GetCreatorUid()); + // readonly creatorPid?: number + CallSetterOptional(env, cls, object, "creatorPid", request->GetCreatorPid()); + // badgeNumber?: number + CallSetterOptional(env, cls, object, "badgeNumber", request->GetBadgeNumber()); + // readonly creatorInstanceKey?: number + CallSetterOptional(env, cls, object, "creatorInstanceKey", request->GetCreatorInstanceKey()); + return true; +} + +bool SetNotificationRequestByBool(ani_env* env, ani_class cls, const OHOS::Notification::NotificationRequest *request, + ani_object &object) +{ + if (request == nullptr) { + ANS_LOGE("request is nullptr"); + return false; + } + // isOngoing?: boolean + CallSetterOptional(env, cls, object, "isOngoing", BoolToAniBoolean(request->IsInProgress())); + // isUnremovable?: boolean + CallSetterOptional(env, cls, object, "isUnremovable", BoolToAniBoolean(request->IsUnremovable())); + // tapDismissed?: boolean + CallSetterOptional(env, cls, object, "tapDismissed", BoolToAniBoolean(request->IsTapDismissed())); + // colorEnabled?: boolean + CallSetterOptional(env, cls, object, "colorEnabled", BoolToAniBoolean(request->IsColorEnabled())); + // isAlertOnce?: boolean + CallSetterOptional(env, cls, object, "isAlertOnce", BoolToAniBoolean(request->IsAlertOneTime())); + // isStopwatch?: boolean + CallSetterOptional(env, cls, object, "isStopwatch", BoolToAniBoolean(request->IsShowStopwatch())); + // isCountDown?: boolean + CallSetterOptional(env, cls, object, "isCountDown", BoolToAniBoolean(request->IsCountdownTimer())); + // isFloatingIcon?: boolean + CallSetterOptional(env, cls, object, "isFloatingIcon", BoolToAniBoolean(request->IsFloatingIcon())); + // showDeliveryTime?: boolean + CallSetterOptional(env, cls, object, "showDeliveryTime", BoolToAniBoolean(request->IsShowDeliveryTime())); + // updateOnly?: boolean + CallSetterOptional(env, cls, object, "updateOnly", BoolToAniBoolean(request->IsUpdateOnly())); + return true; +} + +ani_object ConvertNotificationActionButtonToAniObject(ani_env* env, + const std::shared_ptr &actionButton) +{ + if (actionButton == nullptr) { + ANS_LOGE("actionButton is null"); + return nullptr; + } + ani_object iconButtonObject = nullptr; + ani_class iconButtonCls = nullptr; + RETURN_NULL_IF_FALSE(CreateClassObjByClassName(env, + "Lnotification/notificationActionButton/NotificationActionButtonInner;", iconButtonCls, iconButtonObject)); + // title: string; + ani_string stringValue = nullptr; + RETURN_NULL_IF_FALSE(GetAniString(env, actionButton->GetTitle(), stringValue)); + RETURN_NULL_IF_FALSE(CallSetterOptional(env, iconButtonCls, iconButtonObject, "title", stringValue)); + // wantAgent: WantAgent; + std::shared_ptr agent = actionButton->GetWantAgent(); + if (agent == nullptr) { + ANS_LOGI("agent is null"); + return nullptr; + } else { + ani_object wantAgent = AppExecFwk::WrapWantAgent(env, agent.get()); + RETURN_NULL_IF_FALSE(CallSetterOptional(env, iconButtonCls, iconButtonObject, "wantAgent", wantAgent)); + } + + // need to do + // extras?: Record; napi中没有处理它的过程???但有一个icon?: image.PixelMap处理 napi��û�д������Ĺ��̣���֪���Ǹ�ɶ�ģ� + //napi位置:notification_distributed_notification_service-OpenHarmony_feature_20250328\frameworks\js\napi\src\common_convert_request.cpp 419行 + + // need to do + //TODO(δת������) + + // userInput?: NotificationUserInput -> inputKey: string; + ani_object userInputObject = nullptr; + ani_class userInputCls = nullptr; + RETURN_NULL_IF_FALSE(CreateClassObjByClassName(env, + "Lnotification/notificationUserInput/NotificationUserInputInner;", userInputCls, userInputObject)); + std::shared_ptr userInput = actionButton->GetUserInput(); + RETURN_NULL_IF_FALSE(GetAniString(env, userInput->GetInputKey(), stringValue)); + RETURN_NULL_IF_FALSE(CallSetterOptional(env, userInputCls, userInputObject, "inputKey", stringValue)); + RETURN_NULL_IF_FALSE(CallSetter(env, iconButtonCls, iconButtonObject, "userInput", userInputObject)); + + return iconButtonObject; +} + +ani_object SetNotificationActionButtonArray(ani_env* env, + const std::vector> &actionButtons) +{ + if (actionButtons.empty()) { + ANS_LOGE("actionButtons is empty"); + return nullptr; + } + ani_class arrayCls = nullptr; + ani_method arrayCtor; + ani_object arrayObj; + ani_status status = env->FindClass("Lescompat/Array;", &arrayCls); + if (status != ANI_OK) { + ANS_LOGE("status : %{public}d", status); + return nullptr; + } + status = env->Class_FindMethod(arrayCls, "", "I:V", &arrayCtor); + if (status != ANI_OK) { + ANS_LOGE("status : %{public}d", status); + return nullptr; + } + status = env->Object_New(arrayCls, arrayCtor, &arrayObj, actionButtons.size()); + if (status != ANI_OK) { + ANS_LOGE("status : %{public}d", status); + return nullptr; + } + ani_size index = 0; + for (auto &button : actionButtons) { + ani_object item = ConvertNotificationActionButtonToAniObject(env, button); + RETURN_NULL_IF_NULL(item); + if(ANI_OK != env->Object_CallMethodByName_Void(arrayObj, "$_set", "ILstd/core/Object;:V", index, item)){ + std::cerr << "Object_CallMethodByName_Void $_set Faild " << std::endl; + return nullptr; + } + index ++; + } + return arrayObj; +} + +ani_object SetNotificationTemplateInfo(ani_env* env, const std::shared_ptr &templ) +{ + if (templ == nullptr) { + ANS_LOGE("templ is null"); + return nullptr; + } + ani_object templateObject = nullptr; + ani_class templateCls = nullptr; + RETURN_NULL_IF_FALSE(CreateClassObjByClassName(env, + "Lnotification/notificationTemplate/NotificationTemplateInner;", templateCls, templateObject)); + // name: string; + ani_string stringValue = nullptr; + RETURN_NULL_IF_FALSE(GetAniString(env, templ->GetTemplateName(), stringValue)); + RETURN_NULL_IF_FALSE(CallSetter(env, templateCls, templateObject, "name", stringValue)); + // data: Record; + std::shared_ptr data = templ->GetTemplateData(); + if (data) { + ani_ref valueRef = OHOS::AppExecFwk::WrapWantParams(env, *data); + RETURN_NULL_IF_FALSE(CallSetterOptional(env, templateCls, templateObject, "data", valueRef)); + } + return templateObject; +} + +bool SetNotificationFlags(ani_env* env, const std::shared_ptr &flags, ani_object &flagsObject) +{ + if (flags == nullptr) { + ANS_LOGE("flags is null"); + return false; + } + + ani_class flagsCls = nullptr; + RETURN_FALSE_IF_FALSE(CreateClassObjByClassName(env, + "Lnotification/notificationFlags/NotificationFlagsInner;", flagsCls, flagsObject)); + // readonly soundEnabled?: NotificationFlagStatus; + int32_t soundEnabled = static_cast(flags->IsSoundEnabled()); + ani_enum_item enumItem = nullptr; + RETURN_FALSE_IF_FALSE(EnumConvertNativeToAni(env, "Lnotification/notificationFlags/NotificationFlagStatus;", + soundEnabled, enumItem)); + RETURN_FALSE_IF_FALSE(CallSetter(env, flagsCls, flagsObject, "soundEnabled", enumItem)); + // readonly vibrationEnabled?: NotificationFlagStatus; + int32_t vibrationEnabled = static_cast(flags->IsVibrationEnabled()); + RETURN_FALSE_IF_FALSE(EnumConvertNativeToAni(env, "Lnotification/notificationFlags/NotificationFlagStatus;", + vibrationEnabled, enumItem)); + RETURN_FALSE_IF_FALSE(CallSetter(env, flagsCls, flagsObject, "vibrationEnabled", enumItem)); + // readonly reminderFlags?: number; + uint32_t reminderFlags = flags->GetReminderFlags(); + RETURN_FALSE_IF_FALSE(CallSetterOptional(env, flagsCls, flagsObject, "reminderFlags", reminderFlags)); + return true; +} + +bool SetAgentBundle(ani_env* env, + const std::shared_ptr &agentBundle, ani_object &agentBundleObject) +{ + if (agentBundle == nullptr) { + ANS_LOGE("agentBundle is null"); + return false; + } + ani_class agentBundleCls = nullptr; + RETURN_FALSE_IF_FALSE(CreateClassObjByClassName(env, + "Lnotification/NotificationCommonDef/BundleOptionInner;", agentBundleCls, agentBundleObject)); + // bundle: string; + ani_string stringValue = nullptr; + RETURN_FALSE_IF_FALSE(GetAniString(env, agentBundle->GetBundleName(), stringValue)); + RETURN_FALSE_IF_FALSE(CallSetter(env, agentBundleCls, agentBundleObject, "bundle", stringValue)); + // uid?: number; + uint32_t uid = agentBundle->GetUid(); + RETURN_FALSE_IF_FALSE(CallSetterOptional(env, agentBundleCls, agentBundleObject, "uid", uid)); + return true; +} + +bool SetNotificationUnifiedGroupInfo(ani_env* env, + const std::shared_ptr &groupInfo, ani_object &groupInfoObject) +{ + if (groupInfo == nullptr) { + ANS_LOGE("groupInfo is null"); + return false; + } + ani_class groupInfoCls = nullptr; + RETURN_FALSE_IF_FALSE(CreateClassObjByClassName(env, + "Lnotification/notificationRequest/UnifiedGroupInfoInner;", groupInfoCls, groupInfoObject)); + // key?: string; + ani_string stringValue = nullptr; + if (GetAniString(env, groupInfo->GetKey(), stringValue)) { + CallSetterOptional(env, groupInfoCls, groupInfoObject, "key", stringValue); + } + // title?: string; + if (GetAniString(env, groupInfo->GetTitle(), stringValue)) { + CallSetterOptional(env, groupInfoCls, groupInfoObject, "title", stringValue); + } + // content?: string; + if (GetAniString(env, groupInfo->GetContent(), stringValue)) { + CallSetterOptional(env, groupInfoCls, groupInfoObject, "content", stringValue); + } + // sceneName?: string; + if (GetAniString(env, groupInfo->GetSceneName(), stringValue)) { + CallSetterOptional(env, groupInfoCls, groupInfoObject, "sceneName", stringValue); + } + // extraInfo?: Record; + std::shared_ptr extraInfo = groupInfo->GetExtraInfo(); + if (extraInfo) { + ani_ref valueRef = OHOS::AppExecFwk::WrapWantParams(env, *extraInfo); + CallSetterOptional(env, groupInfoCls, groupInfoObject, "extraInfo", valueRef); + } + return true; +} + +bool SetNotificationRequestByCustom(ani_env* env, ani_class cls, const OHOS::Notification::NotificationRequest *request, + ani_object &object) +{ + if (request == nullptr) { + ANS_LOGE("request is nullptr"); + return false; + } + // content: NotificationContent + RETURN_FALSE_IF_FALSE(SetNotificationRequestByNotificationContent(env, cls, request, object)); + // extraInfo?: {[key:string] : any} + std::shared_ptr additionalData = request->GetAdditionalData(); + if (additionalData) { + ani_ref extraInfo = OHOS::AppExecFwk::WrapWantParams(env, *additionalData); + RETURN_FALSE_IF_FALSE(CallSetterOptional(env, cls, object, "extraInfo", extraInfo)); + } + + // actionButtons?: Array + std::vector> actionButtons = request->GetActionButtons(); + ani_object actionButtonsArrayObj = SetNotificationActionButtonArray(env, actionButtons); + if (actionButtonsArrayObj != nullptr) { + RETURN_FALSE_IF_FALSE(CallSetterOptional(env, cls, object, "actionButtons", actionButtonsArrayObj)); + } + // template?: NotificationTemplate + std::shared_ptr templ = request->GetTemplate(); + if (templ) { + ani_object templateObject = SetNotificationTemplateInfo(env, templ); + if (templateObject != nullptr) { + RETURN_FALSE_IF_FALSE(CallSetter(env, cls, object, "template", templateObject)); + } + } + // readonly notificationFlags?: NotificationFlags + std::shared_ptr flags = request->GetFlags(); + if (flags) { + ani_object flagsObject = nullptr; + if (SetNotificationFlags(env, flags, flagsObject) && flagsObject != nullptr) { + CallSetter(env, cls, object, "notificationFlags", flagsObject); + } + } + // readonly agentBundle?: agentBundle + std::shared_ptr agentBundle = request->GetAgentBundle(); + if (agentBundle) { + ani_object agentBundleObject = nullptr; + if (SetAgentBundle(env, agentBundle, agentBundleObject) && agentBundleObject != nullptr) { + CallSetter(env, cls, object, "agentBundle", agentBundleObject); + } + } + // unifiedGroupInfo?: unifiedGroupInfo + std::shared_ptr groupInfo = request->GetUnifiedGroupInfo(); + if (groupInfo) { + ani_object infoObject = nullptr; + if(SetNotificationUnifiedGroupInfo(env, groupInfo, infoObject) && infoObject != nullptr) { + CallSetter(env, cls, object, "unifiedGroupInfo", infoObject); + } + } + return true; +} + +void UnWarpDistributedOptions(ani_env *env, ani_object obj, StsDistributedOptions distributedOptions) +{ + bool isDistributed = false; + ani_boolean isUndefined = ANI_TRUE; + if(ANI_OK == GetPropertyBooleanOrUndefined(env, obj, "isDistributed", isUndefined, isDistributed) + && isUndefined == ANI_FALSE) { + distributedOptions.isDistributed = isDistributed; + } + + std::vector supportDisplayDevices = {}; + isUndefined = ANI_TRUE; + if(GetStringArrayOrUndefined(env, obj, "supportDisplayDevices", isUndefined, supportDisplayDevices) == ANI_OK + && isUndefined == ANI_FALSE) { + distributedOptions.supportDisplayDevices = supportDisplayDevices; + } + + std::vector supportOperateDevices = {}; + isUndefined = ANI_TRUE; + if(GetStringArrayOrUndefined(env, obj, "supportOperateDevices", isUndefined, supportOperateDevices) == ANI_OK + && isUndefined == ANI_FALSE) { + distributedOptions.supportOperateDevices = supportOperateDevices; + } + + ani_double remindType = 0.0; + isUndefined = ANI_TRUE; + if(ANI_OK == GetPropertyDoubleOrUndefined(env, obj, "remindType", isUndefined, remindType) + && isUndefined == ANI_FALSE) { + distributedOptions.remindType = static_cast(remindType); + } +} + +void GetNotificationRequestByBooleanOne(ani_env *env, ani_object obj, + std::shared_ptr &request) +{ + bool mbool = false; + ani_boolean isUndefined = ANI_TRUE; + + if(ANI_OK == GetPropertyBooleanOrUndefined(env, obj, "isOngoing", isUndefined, mbool) + && isUndefined == ANI_FALSE) { + request->SetInProgress(mbool); + } + + isUndefined = ANI_TRUE; + if(ANI_OK == GetPropertyBooleanOrUndefined(env, obj, "isUnremovable", isUndefined, mbool) + && isUndefined == ANI_FALSE) { + request->SetUnremovable(mbool); + } + + isUndefined = ANI_TRUE; + if(ANI_OK == GetPropertyBooleanOrUndefined(env, obj, "updateOnly", isUndefined, mbool) + && isUndefined == ANI_FALSE) { + request->SetUpdateOnly(mbool); + } + + isUndefined = ANI_TRUE; + if(ANI_OK == GetPropertyBooleanOrUndefined(env, obj, "tapDismissed", isUndefined, mbool) + && isUndefined == ANI_FALSE) { + request->SetTapDismissed(mbool); + } + + isUndefined = ANI_TRUE; + if(ANI_OK == GetPropertyBooleanOrUndefined(env, obj, "colorEnabled", isUndefined, mbool) + && isUndefined == ANI_FALSE) { + request->SetColorEnabled(mbool); + } + + isUndefined = ANI_TRUE; + if(ANI_OK == GetPropertyBooleanOrUndefined(env, obj, "isAlertOnce", isUndefined, mbool) + && isUndefined == ANI_FALSE) { + request->SetAlertOneTime(mbool); + } + + isUndefined = ANI_TRUE; + if(ANI_OK == GetPropertyBooleanOrUndefined(env, obj, "isStopwatch", isUndefined, mbool) + && isUndefined == ANI_FALSE) { + request->SetShowStopwatch(mbool); + } +} + +void GetNotificationRequestByBooleanTwo(ani_env *env, ani_object obj, + std::shared_ptr &request) +{ + bool mbool = false; + ani_boolean isUndefined = ANI_TRUE; + if(ANI_OK == GetPropertyBooleanOrUndefined(env, obj, "isCountDown", isUndefined, mbool) + && isUndefined == ANI_FALSE) { + request->SetCountdownTimer(mbool); + } + + isUndefined = ANI_TRUE; + if(ANI_OK == GetPropertyBooleanOrUndefined(env, obj, "isFloatingIcon", isUndefined, mbool) + && isUndefined == ANI_FALSE) { + request->SetFloatingIcon(mbool); + } + + isUndefined = ANI_TRUE; + if(ANI_OK == GetPropertyBooleanOrUndefined(env, obj, "showDeliveryTime", isUndefined, mbool) + && isUndefined == ANI_FALSE) { + request->SetShowDeliveryTime(mbool); + } + + isUndefined = ANI_TRUE; + if(ANI_OK == GetPropertyBooleanOrUndefined(env, obj, "isRemoveAllowed", isUndefined, mbool) + && isUndefined == ANI_FALSE) { + request->SetRemoveAllowed(mbool); + } + + isUndefined = ANI_TRUE; + if(ANI_OK == GetPropertyBooleanOrUndefined(env, obj, "forceDistributed", isUndefined, mbool) + && isUndefined == ANI_FALSE) { + request->SetForceDistributed(mbool); + } + + isUndefined = ANI_TRUE; + if(ANI_OK == GetPropertyBooleanOrUndefined(env, obj, "notDistributed", isUndefined, mbool) + && isUndefined == ANI_FALSE) { + request->SetNotDistributed(mbool); + } +} + +void GetNotificationRequestByBoolean(ani_env *env, ani_object obj, + std::shared_ptr &request) +{ + GetNotificationRequestByBooleanOne(env, obj, request); + GetNotificationRequestByBooleanTwo(env, obj, request); +} + +void GetNotificationRequestByString(ani_env *env, ani_object obj, + std::shared_ptr &request) { + std::string mString = ""; + ani_boolean isUndefined = ANI_TRUE; + + if (ANI_OK == GetPropertyString(env, obj, "classification", isUndefined, mString) && isUndefined == ANI_FALSE) { + request->SetClassification(mString); + } + + if (ANI_OK == GetPropertyString(env, obj, "appMessageId", isUndefined, mString) && isUndefined == ANI_FALSE) { + request->SetAppMessageId(mString); + } + + if (ANI_OK == GetPropertyString(env, obj, "label", isUndefined, mString) && isUndefined == ANI_FALSE) { + request->SetLabel(mString); + } + + if (ANI_OK == GetPropertyString(env, obj, "groupName", isUndefined, mString) && isUndefined == ANI_FALSE) { + request->SetGroupName(mString); + } + + if (ANI_OK == GetPropertyString(env, obj, "sound", isUndefined, mString) && isUndefined == ANI_FALSE) { + request->SetSound(mString); + } +} + +void GetNotificationRequestByNumber(ani_env *env, ani_object obj, + std::shared_ptr &request) { + ani_double mDouble = 0.0; + ani_boolean isUndefined = ANI_TRUE; + + if(ANI_OK == GetPropertyDoubleOrUndefined(env, obj, "id", isUndefined, mDouble) && isUndefined == ANI_FALSE) { + request->SetNotificationId(static_cast(mDouble)); + } else { + request->SetNotificationId(0); + } + + if(ANI_OK == GetPropertyDoubleOrUndefined(env, obj, "deliveryTime", isUndefined, mDouble) + && isUndefined == ANI_FALSE) { + request->SetDeliveryTime(static_cast(mDouble)); + } + + if(ANI_OK == GetPropertyDoubleOrUndefined(env, obj, "autoDeletedTime", isUndefined, mDouble) + && isUndefined == ANI_FALSE) { + request->SetAutoDeletedTime(static_cast(mDouble)); + } + + if(ANI_OK == GetPropertyDoubleOrUndefined(env, obj, "color", isUndefined, mDouble) + && isUndefined == ANI_FALSE) { + request->SetColor(static_cast(mDouble)); + } + + if(ANI_OK == GetPropertyDoubleOrUndefined(env, obj, "badgeIconStyle", isUndefined, mDouble) + && isUndefined == ANI_FALSE) { + int32_t style = static_cast(mDouble); + request->SetBadgeIconStyle(static_cast(style)); + } + + if(ANI_OK == GetPropertyDoubleOrUndefined(env, obj, "badgeNumber", isUndefined, mDouble) + && isUndefined == ANI_FALSE) { + request->SetBadgeNumber(static_cast(mDouble)); + } + + if(ANI_OK == GetPropertyDoubleOrUndefined(env, obj, "notificationControlFlags", isUndefined, mDouble) + && isUndefined == ANI_FALSE) { + request->SetNotificationControlFlags(static_cast(mDouble)); + } +} + +bool GetNotificationContent(ani_env *env, ani_object obj, ContentType outType, + std::shared_ptr &request) +{ + ani_ref contentRef = {}; + switch (outType) { + case ContentType::BASIC_TEXT: + { + if(env->Object_GetPropertyByName_Ref(obj, "normal", &contentRef) != ANI_OK) { + return false; + } + std::shared_ptr normalContent = std::make_shared(); + UnWarpNotificationNormalContent(env, static_cast(contentRef), normalContent); + request->SetContent(std::make_shared(normalContent)); + break; + } + case ContentType::LONG_TEXT: + { + if(env->Object_GetPropertyByName_Ref(obj, "longText", &contentRef) != ANI_OK) { + return false; + } + std::shared_ptr longTextContent + = std::make_shared(); + UnWarpNotificationLongTextContent(env, static_cast(contentRef), longTextContent); + request->SetContent(std::make_shared(longTextContent)); + break; + } + case ContentType::PICTURE: + { + if(env->Object_GetPropertyByName_Ref(obj, "picture", &contentRef) != ANI_OK) { + return false; + } + std::shared_ptr pictureContent + = std::make_shared(); + UnWarpNotificationPictureContent(env, static_cast(contentRef), pictureContent); + request->SetContent(std::make_shared(pictureContent)); + break; + } + case ContentType::MULTILINE: + { + if(env->Object_GetPropertyByName_Ref(obj, "multiLine", &contentRef) != ANI_OK) { + return false; + } + std::shared_ptr multiLineContent + = std::make_shared(); + UnWarpNotificationMultiLineContent(env, static_cast(contentRef), multiLineContent); + request->SetContent(std::make_shared(multiLineContent)); + break; + } + case ContentType::LOCAL_LIVE_VIEW: + { + if(env->Object_GetPropertyByName_Ref(obj, "systemLiveView", &contentRef) != ANI_OK) { + return false; + } + std::shared_ptr localLiveView + = std::make_shared(); + UnWarpNotificationLocalLiveViewContent(env, static_cast(contentRef), localLiveView); + request->SetContent(std::make_shared(localLiveView)); + break; + } + case ContentType::LIVE_VIEW: + { + if(env->Object_GetPropertyByName_Ref(obj, "liveView", &contentRef) != ANI_OK) { + return false; + } + std::shared_ptr liveViewContent + = std::make_shared(); + UnWarpNotificationLiveViewContent(env, static_cast(contentRef), liveViewContent); + request->SetContent(std::make_shared(liveViewContent)); + break; + } + case ContentType::CONVERSATION: + // need to add + break; + default: + break; + } + return true; +} + +ani_status GetNotificationContent(ani_env *env, ani_object obj, + std::shared_ptr &request) +{ + ani_status status = ANI_ERROR; + ani_ref notificationContentRef = {}; + if((status = env->Object_GetPropertyByName_Ref(obj, "content", ¬ificationContentRef))!= ANI_OK) { + return status; + } + ani_ref contentTypeRef; + if((status = env->Object_GetPropertyByName_Ref(static_cast(notificationContentRef), + "notificationContentType", &contentTypeRef)) != ANI_OK) { + return status; + } + ani_boolean isUndefined = ANI_TRUE; + if ((status = env->Reference_IsUndefined(contentTypeRef, &isUndefined)) != ANI_OK) { + return status; + } + if (isUndefined == ANI_TRUE) { + return ANI_INCORRECT_REF; + } + ContentType type; + if(!ContentTypeEtsToC(env, static_cast(contentTypeRef), type)) { + return ANI_INVALID_ARGS; + } + + if(!GetNotificationContent(env, static_cast(notificationContentRef), type, request)) { + return ANI_INVALID_ARGS; + } + return status; +} + +void GetNotificationSlotType(ani_env *env, ani_object obj, std::shared_ptr &request) +{ + ani_status status = ANI_ERROR; + ani_ref slotTypeRef = {}; + if((status = env->Object_GetPropertyByName_Ref(obj, "notificationSlotType", &slotTypeRef))!= ANI_OK) { + return; + } + SlotType type = SlotType::OTHER; + if(!SlotTypeEtsToC(env, static_cast(slotTypeRef), type)) { + return; + } + request->SetSlotType(type); +} + +void GetNotificationRemovalWantAgent(ani_env *env, ani_object obj, + std::shared_ptr &request) +{ + ani_status status = ANI_ERROR; + ani_ref wantAgentRef = {}; + if((status = env->Object_GetPropertyByName_Ref(obj, "removalWantAgent", &wantAgentRef))!= ANI_OK) { + return; + } + WantAgent* pWantAgent = nullptr; + UnwrapWantAgent(env, static_cast(wantAgentRef), reinterpret_cast(&pWantAgent)); + if (pWantAgent == nullptr) { + return; + } + + std::shared_ptr wantAgent = std::make_shared(*pWantAgent); + request->SetRemovalWantAgent(wantAgent); +} + +void GetNotificationWantAgent(ani_env *env, ani_object obj, std::shared_ptr &request) +{ + ani_status status = ANI_ERROR; + ani_ref wantAgentRef = {}; + if((status = env->Object_GetPropertyByName_Ref(obj, "wantAgent", &wantAgentRef))!= ANI_OK) { + return; + } + WantAgent* pWantAgent = nullptr; + UnwrapWantAgent(env, static_cast(wantAgentRef), reinterpret_cast(&pWantAgent)); + if (pWantAgent == nullptr) { + return; + } + + std::shared_ptr wantAgent = std::make_shared(*pWantAgent); + request->SetWantAgent(wantAgent); +} + +void GetNotificationExtraInfo(ani_env *env, ani_object obj, std::shared_ptr &request) +{ + ani_status status = ANI_ERROR; + ani_ref extraInfoRef = {}; + if((status = env->Object_GetPropertyByName_Ref(obj, "extraInfo", &extraInfoRef))!= ANI_OK) { + return; + } + ani_boolean isUndefind = ANI_TRUE; + WantParams wantParams = {}; + if ((status = env->Reference_IsUndefined(extraInfoRef, &isUndefind)) == ANI_OK && isUndefind == ANI_FALSE) { + UnwrapWantParams(env, extraInfoRef, wantParams); + std::shared_ptr extras = std::make_shared(wantParams); + request->SetAdditionalData(extras); + } +} + +ani_status GetNotificationActionButtonArrayOrUndefined(ani_env *env, ani_object param, + const char *name, std::vector> &res) +{ + ani_ref arrayObj = nullptr; + ani_boolean isUndefined = true; + ani_status status; + ani_double length; + StsActionButton actionButton; + + if ((status = env->Object_GetFieldByName_Ref(param, name, &arrayObj)) != ANI_OK) { + ANS_LOGI("status : %{public}d", status); + return status; + } + if ((status = env->Reference_IsUndefined(arrayObj, &isUndefined)) != ANI_OK) { + ANS_LOGI("status : %{public}d", status); + return status; + } + if (isUndefined) { + ANS_LOGI("%{public}s : undefined", name); + return ANI_INVALID_ARGS; + } + + status = env->Object_GetPropertyByName_Double(static_cast(arrayObj), "length", &length); + if (status != ANI_OK) { + ANS_LOGI("status : %{public}d", status); + return status; + } + + for (int i = 0; i < static_cast(length); i++) { + ani_ref buttonRef; + status = env->Object_CallMethodByName_Ref(static_cast(arrayObj), + "$_get", "I:Lstd/core/Object;", &buttonRef, (ani_int)i); + if (status != ANI_OK) { + ANS_LOGI("status : %{public}d, index: %{public}d", status, i); + return status; + } + status = UnwrapNotificationActionButton(env, static_cast(buttonRef), actionButton); + if (status != ANI_OK) { + ANS_LOGI("ActionButton failed, index: %{public}d", i); + return status; + } + std::shared_ptr button + = NotificationActionButton::Create(actionButton.icon, + actionButton.title, actionButton.wantAgent, actionButton.extras, + actionButton.semanticActionButton, actionButton.autoCreatedReplies, actionButton.mimeTypeOnlyInputs, + actionButton.userInput, actionButton.isContextual); + res.push_back(button); + } + return status; +} + +void GetNotificationActionButtons(ani_env *env, ani_object obj, std::shared_ptr &request) +{ + std::vector> buttons = {}; + ani_status status = GetNotificationActionButtonArrayOrUndefined(env, obj, "actionButtons", buttons); + if (status == ANI_OK) { + for(auto button: buttons) { + request->AddActionButton(button); + } + } +} + +void GetNotificationSmallIcon(ani_env *env, ani_object obj, std::shared_ptr &request) +{ + ani_status status = ANI_ERROR; + ani_ref smallIconRef = {}; + if((status = env->Object_GetPropertyByName_Ref(obj, "smallIcon", &smallIconRef))!= ANI_OK) { + return; + } + ani_boolean isUndefind = ANI_TRUE; + if ((status = env->Reference_IsUndefined(smallIconRef, &isUndefind)) == ANI_OK && isUndefind == ANI_FALSE) { + std::shared_ptr pixelMap = GetPixelMapFromEnvSp(env, static_cast(smallIconRef)); + if (pixelMap != nullptr) { + request->SetLittleIcon(pixelMap); + } + } +} + +void GetNotificationLargeIcon(ani_env *env, ani_object obj, std::shared_ptr &request) +{ + ani_status status = ANI_ERROR; + ani_ref largeIconRef = {}; + if((status = env->Object_GetPropertyByName_Ref(obj, "largeIcon", &largeIconRef))!= ANI_OK) { + return; + } + ani_boolean isUndefind = ANI_TRUE; + if ((status = env->Reference_IsUndefined(largeIconRef, &isUndefind)) == ANI_OK && isUndefind == ANI_FALSE) { + std::shared_ptr pixelMap = GetPixelMapFromEnvSp(env, static_cast(largeIconRef)); + if (pixelMap != nullptr) { + request->SetBigIcon(pixelMap); + } + } +} + +void GetNotificationOverlayIcon(ani_env *env, ani_object obj, std::shared_ptr &request) +{ + ani_status status = ANI_ERROR; + ani_ref overlayIconRef = {}; + if((status = env->Object_GetPropertyByName_Ref(obj, "overlayIcon", &overlayIconRef))!= ANI_OK) { + return; + } + ani_boolean isUndefind = ANI_TRUE; + if ((status = env->Reference_IsUndefined(overlayIconRef, &isUndefind)) == ANI_OK && isUndefind == ANI_FALSE) { + std::shared_ptr pixelMap = GetPixelMapFromEnvSp(env, static_cast(overlayIconRef)); + if (pixelMap != nullptr) { + request->SetOverlayIcon(pixelMap); + } + } +} + +void GetNotificationRequestDistributedOptions(ani_env *env, ani_object obj, + std::shared_ptr &request) +{ + ani_status status = ANI_ERROR; + ani_ref optionRef = {}; + if((status = env->Object_GetPropertyByName_Ref(obj, "distributedOptionRef", &optionRef))!= ANI_OK) { + return; + } + ani_boolean isUndefind = ANI_TRUE; + if ((status = env->Reference_IsUndefined(optionRef, &isUndefind)) == ANI_OK && isUndefind == ANI_FALSE) { + StsDistributedOptions options; + UnWarpDistributedOptions(env, static_cast(optionRef), options); + request->SetDistributed(options.isDistributed); + request->SetDevicesSupportDisplay(options.supportDisplayDevices); + request->SetDevicesSupportOperate(options.supportOperateDevices); + } +} + +void GetNotificationTemplate(ani_env *env, ani_object obj, + std::shared_ptr &request) +{ + ani_status status = ANI_ERROR; + ani_ref templateRef = {}; + if((status = env->Object_GetPropertyByName_Ref(obj, "template", &templateRef))!= ANI_OK) { + return; + } + ani_boolean isUndefind = ANI_TRUE; + if ((status = env->Reference_IsUndefined(templateRef, &isUndefind)) == ANI_OK && isUndefind == ANI_FALSE) { + OHOS::Notification::NotificationTemplate tmplate; + UnwrapNotificationTemplate(env, static_cast(templateRef), tmplate); + request->SetTemplate(std::make_shared(tmplate)); + } +} + +void GetNotificationUnifiedGroupInfo(ani_env *env, ani_object obj, + std::shared_ptr &request) +{ + ani_status status = ANI_ERROR; + ani_ref infoRef = {}; + if((status = env->Object_GetPropertyByName_Ref(obj, "template", &infoRef))!= ANI_OK) { + return; + } + ani_boolean isUndefind = ANI_TRUE; + if ((status = env->Reference_IsUndefined(infoRef, &isUndefind)) != ANI_OK || isUndefind == ANI_TRUE) { + return; + } + + std::shared_ptr unifiedGroupInfo = std::make_shared(); + std::string mString = ""; + isUndefind = ANI_TRUE; + if (ANI_OK == GetPropertyString(env, static_cast(infoRef), "key", isUndefind, mString) + && isUndefind == ANI_FALSE) { + unifiedGroupInfo->SetKey(mString); + } + + if (ANI_OK == GetPropertyString(env, static_cast(infoRef), "title", isUndefind, mString) + && isUndefind == ANI_FALSE) { + unifiedGroupInfo->SetTitle(mString); + } + + if (ANI_OK == GetPropertyString(env, static_cast(infoRef), "content", isUndefind, mString) + && isUndefind == ANI_FALSE) { + unifiedGroupInfo->SetContent(mString); + } + + if (ANI_OK == GetPropertyString(env, static_cast(infoRef), "sceneName", isUndefind, mString) + && isUndefind == ANI_FALSE) { + unifiedGroupInfo->SetSceneName(mString); + } + + ani_ref extraInfoRef = {}; + if((status = env->Object_GetPropertyByName_Ref(static_cast(infoRef), "extraInfo", &extraInfoRef)) + != ANI_OK) { + return; + } + isUndefind = ANI_TRUE; + if ((status = env->Reference_IsUndefined(extraInfoRef, &isUndefind)) == ANI_OK && isUndefind == ANI_FALSE) { + WantParams wantParams = {}; + UnwrapWantParams(env, extraInfoRef, wantParams); + std::shared_ptr extras = std::make_shared(wantParams); + unifiedGroupInfo->SetExtraInfo(extras); + } + request->SetUnifiedGroupInfo(unifiedGroupInfo); +} + +void GetNotificationBundleOption(ani_env *env, ani_object obj, + std::shared_ptr &request) +{ + ani_status status = ANI_ERROR; + ani_ref optionRef = {}; + if((status = env->Object_GetPropertyByName_Ref(obj, "representativeBundle", &optionRef))!= ANI_OK) { + return; + } + ani_boolean isUndefind = ANI_TRUE; + if ((status = env->Reference_IsUndefined(optionRef, &isUndefind)) != ANI_OK || isUndefind == ANI_TRUE) { + return; + } + OHOS::Notification::NotificationBundleOption option; + if(ANI_OK == UnwrapBundleOption(env, static_cast(optionRef), option)) { + request->SetBundleOption(std::make_shared(option)); + } +} + +ani_status GetNotificationRequestByCustom(ani_env *env, ani_object obj, + std::shared_ptr ¬ificationRequest) +{ + ani_status status = ANI_ERROR; + if((status = GetNotificationContent(env, obj, notificationRequest)) != ANI_OK) { + return status; + } + + GetNotificationSlotType(env, obj, notificationRequest); + GetNotificationWantAgent(env, obj, notificationRequest); + GetNotificationExtraInfo(env, obj, notificationRequest); + GetNotificationRemovalWantAgent(env, obj, notificationRequest); + GetNotificationActionButtons(env, obj, notificationRequest); + GetNotificationSmallIcon(env, obj, notificationRequest); + GetNotificationLargeIcon(env, obj, notificationRequest); + GetNotificationOverlayIcon(env, obj, notificationRequest); + GetNotificationRequestDistributedOptions(env, obj, notificationRequest); + GetNotificationTemplate(env, obj, notificationRequest); + GetNotificationUnifiedGroupInfo(env, obj, notificationRequest); + GetNotificationBundleOption(env, obj, notificationRequest); + // need to do GetNotificationMaxScreenWantAgent 没看明白 + /* + // maxScreenWantAgent?: WantAgent + if (GetNotificationMaxScreenWantAgent(env, value, request) == nullptr) { + return nullptr; + } + */ + + return status; +} + +ani_status UnWarpNotificationRequest(ani_env *env, ani_object obj, + std::shared_ptr ¬ificationRequest) +{ + ani_status status = ANI_ERROR; + GetNotificationRequestByNumber(env, obj, notificationRequest); + GetNotificationRequestByString(env, obj, notificationRequest); + GetNotificationRequestByBoolean(env, obj, notificationRequest); + status = GetNotificationRequestByCustom(env, obj, notificationRequest); + return status; +} + +bool SetNotificationRequestByPixelMap(ani_env* env, ani_class cls, const NotificationRequest *request, + ani_object &object) +{ + if (request == nullptr) { + ANS_LOGE("request is nullptr"); + return false; + } + // smallIcon?: image.PixelMap + std::shared_ptr littleIcon = request->GetLittleIcon(); + if (littleIcon) { + ani_object smallIconResult = Media::PixelMapAni::CreatePixelMap(env, littleIcon); + if (smallIconResult == nullptr) { + ANS_LOGE("CreatePixelMap failed,, smallIconResult is nullptr "); + return false; + } + CallSetterOptional(env, cls, object, "smallIcon", smallIconResult); + } + // largeIcon?: image.PixelMap + std::shared_ptr largeIcon = request->GetBigIcon(); + if (largeIcon) { + ani_object largeIconResult = Media::PixelMapAni::CreatePixelMap(env, largeIcon); + if (largeIconResult == nullptr) { + ANS_LOGE("CreatePixelMap failed, largeIconResult is nullptr"); + return false; + } + CallSetterOptional(env, cls, object, "largeIcon", largeIconResult); + } + // overlayIcon?: image.PixelMap + std::shared_ptr overlayIcon = request->GetOverlayIcon(); + if (overlayIcon) { + ani_object overlayIconResult = Media::PixelMapAni::CreatePixelMap(env, overlayIcon); + if (overlayIconResult == nullptr) { + ANS_LOGE("CreatePixelMap failed, overlayIconResult is nullptr"); + return false; + } + CallSetterOptional(env, cls, object, "overlayIcon", overlayIconResult); + } + return true; +} + +bool SetNotificationRequestByWantAgent(ani_env* env, ani_class cls, + const OHOS::Notification::NotificationRequest *request, ani_object &object) +{ + if (request == nullptr) { + ANS_LOGE("request is nullptr"); + return false; + } + // wantAgent?: WantAgent + std::shared_ptr agent = request->GetWantAgent(); + if (agent) { + ani_object wantAgent = AppExecFwk::WrapWantAgent(env, agent.get()); + RETURN_FALSE_IF_FALSE(CallSetterOptional(env, cls, object, "wantAgent", wantAgent)); + } else { + RETURN_FALSE_IF_FALSE(CallSetterNull(env, cls, object, "wantAgent")); + } + // removalWantAgent?: WantAgent + std::shared_ptr removalAgent = request->GetRemovalWantAgent(); + if (removalAgent) { + ani_object wantAgent = AppExecFwk::WrapWantAgent(env, removalAgent.get()); + RETURN_FALSE_IF_FALSE(CallSetterOptional(env, cls, object, "removalWantAgent", wantAgent)); + } else { + RETURN_FALSE_IF_FALSE(CallSetterNull(env, cls, object, "removalWantAgent")); + } + // maxScreenWantAgent?: WantAgent + std::shared_ptr maxScreenAgent = request->GetMaxScreenWantAgent(); + if (maxScreenAgent) { + ani_object wantAgent = AppExecFwk::WrapWantAgent(env, maxScreenAgent.get()); + RETURN_FALSE_IF_FALSE(CallSetterOptional(env, cls, object, "maxScreenWantAgent", wantAgent)); + } else { + RETURN_FALSE_IF_FALSE(CallSetterNull(env, cls, object, "maxScreenWantAgent")); + } + return true; +} + +bool WarpNotificationRequest(ani_env *env, const OHOS::Notification::NotificationRequest *notificationRequest, + ani_class &cls, ani_object &outAniObj) +{ + if (notificationRequest == nullptr) { + ANS_LOGE("notification is null"); + return false; + } + if(!CreateClassObjByClassName(env, + "Lnotification/notificationRequest/NotificationRequestInner;", cls, outAniObj)) { + return false; + } + if(!SetNotificationRequestByBool(env, cls, notificationRequest, outAniObj)) { + return false; + } + if(!SetNotificationRequestByString(env, cls, notificationRequest, outAniObj)) { + return false; + } + if(!SetNotificationRequestByNumber(env, cls, notificationRequest, outAniObj)) { + return false; + } + // need to do + if (!SetNotificationRequestByWantAgent(env, cls, notificationRequest, outAniObj)) { + return false; + } + if (!SetNotificationRequestByPixelMap(env, cls, notificationRequest, outAniObj)) { + return false; + } + if(SetNotificationRequestByCustom(env, cls, notificationRequest, outAniObj)) { + return false; + } + return true; +} + +bool DeviceRemindTypeCToEts(const NotificationConstant::RemindType &inType, NotificationNapi::DeviceRemindType &outType) +{ + switch (inType) { + case NotificationConstant::RemindType::DEVICE_IDLE_DONOT_REMIND: + outType = NotificationNapi::DeviceRemindType::IDLE_DONOT_REMIND; + break; + case NotificationConstant::RemindType::DEVICE_IDLE_REMIND: + outType = NotificationNapi::DeviceRemindType::IDLE_REMIND; + break; + case NotificationConstant::RemindType::DEVICE_ACTIVE_DONOT_REMIND: + outType = NotificationNapi::DeviceRemindType::ACTIVE_DONOT_REMIND; + break; + case NotificationConstant::RemindType::DEVICE_ACTIVE_REMIND: + outType = NotificationNapi::DeviceRemindType::ACTIVE_REMIND; + break; + default: + ANS_LOGE("DeviceRemindType %{public}d is an invalid value", inType); + return false; + } + return true; +} + +bool SetNotificationByDistributedOptions(ani_env *env, const OHOS::Notification::Notification *notification, + ani_class cls, ani_object &outAniObj) +{ + if (notification == nullptr) { + ANS_LOGE("notification is null"); + return false; + } + NotificationDistributedOptions options = notification->GetNotificationRequest().GetNotificationDistributedOptions(); + // isDistributed?: boolean; + if (notification->GetDeviceId().empty()) { + CallSetterOptional(env, cls, outAniObj, "isDistributed", + BoolToAniBoolean(false)); + } else { + CallSetterOptional(env, cls, outAniObj, "isDistributed", + BoolToAniBoolean(options.IsDistributed())); + } + // readonly remindType?: number; + enum NotificationNapi::DeviceRemindType outType = NotificationNapi::DeviceRemindType::IDLE_DONOT_REMIND; + if (!DeviceRemindTypeCToEts(notification->GetRemindType(), outType)) { + return false; + } + CallSetterOptional(env, cls, outAniObj, "remindType", static_cast(outType)); + // supportDisplayDevices?: Array; + std::vector displayDevices = options.GetDevicesSupportDisplay(); + ani_object devicesObjectArray = ConvertVectorToAniArrayString(env, displayDevices); + if (devicesObjectArray == nullptr) { + ANS_LOGE("devicesObjectArray is nullptr"); + return false; + } + CallSetterOptional(env, cls, outAniObj, "supportDisplayDevices", devicesObjectArray); + // supportOperateDevices?: Array; + std::vector operateDevices = options.GetDevicesSupportOperate(); + ani_object operateObjectArray = ConvertVectorToAniArrayString(env, operateDevices); + if (operateObjectArray == nullptr) { + ANS_LOGE("operateObjectArray is nullptr"); + return false; + } + CallSetterOptional(env, cls, outAniObj, "supportOperateDevices", operateObjectArray); + return true; +} + +ani_object ConvertNotificationToAni(ani_env* env, const OHOS::Notification::Notification *notification) +{ + if (notification == nullptr) { + ANS_LOGE("notification is null"); + return nullptr; + } + ani_class requestcls = nullptr; + ani_object requestObj = nullptr; + NotificationRequest request = notification->GetNotificationRequest(); + if (!WarpNotificationRequest(env, &request, requestcls, requestObj)) { + return nullptr; + } + // readonly hashCode?: string; + ani_string stringValue = nullptr; + if (GetAniString(env, notification->GetKey(), stringValue)) { + CallSetterOptional(env, requestcls, requestObj, "hashCode", stringValue); + } + // readonly creatorUserId?: number; + CallSetterOptional(env, requestcls, requestObj, "creatorUserId", notification->GetRecvUserId()); + // distributedOption?: DistributedOptions; + ani_object distributedObj = nullptr; + ani_class distributedCls = nullptr; + if(!CreateClassObjByClassName(env, + "Lnotification/notificationRequest/DistributedOptionsInner;", distributedCls, distributedObj)) { + return nullptr; + } + if (!SetNotificationByDistributedOptions(env, notification, distributedCls, distributedObj)) { + return nullptr; + } + CallSetterOptional(env, requestcls, requestObj, "distributedOption", distributedObj); + // isRemoveAllowed?: boolean; + CallSetterOptional(env, requestcls, requestObj, "isRemoveAllowed", + BoolToAniBoolean(notification->IsRemoveAllowed())); + // readonly source?: number; + int32_t source = static_cast(notification->GetSourceType()); + CallSetterOptional(env, requestcls, requestObj, "source", source); + // readonly deviceId?: string; + if (GetAniString(env, notification->GetDeviceId(), stringValue)) { + CallSetterOptional(env, requestcls, requestObj, "deviceId", stringValue); + } + // notificationControlFlags?: number; + CallSetterOptional(env, requestcls, requestObj, "notificationControlFlags", + notification->GetNotificationRequest().GetNotificationControlFlags()); + // isFloatingIcon?: boolean; + CallSetterOptional(env, requestcls, requestObj, "isFloatingIcon", + BoolToAniBoolean(notification->IsFloatingIcon())); + // readonly creatorBundleName?: string; + if (GetAniString(env, notification->GetBundleName(), stringValue)) { + CallSetterOptional(env, requestcls, requestObj, "creatorBundleName", stringValue); + } + // readonly creatorUid?: number; + CallSetterOptional(env, requestcls, requestObj, "creatorUid", + notification->GetNotificationRequest().GetOwnerUid()); + // readonly creatorPid?: number; + CallSetterOptional(env, requestcls, requestObj, "creatorPid", notification->GetPid()); + return requestObj; +} + +ani_object ConvertNotificationArrayToAni(ani_env* env, + const std::vector> ¬ifications) +{ + ani_class arrayCls = nullptr; + ani_method arrayCtor; + ani_object arrayObj; + ani_status status = ANI_ERROR; + status = env->FindClass("Lescompat/Array;", &arrayCls); + if (status != ANI_OK) { + ANS_LOGE("status : %{public}d", status); + return nullptr; + } + + status = env->Class_FindMethod(arrayCls, "", "I:V", &arrayCtor); + if (status != ANI_OK) { + ANS_LOGE("status : %{public}d", status); + return nullptr; + } + + status = env->Object_New(arrayCls, arrayCtor, &arrayObj, notifications.size()); + if (status != ANI_OK) { + ANS_LOGE("status : %{public}d", status); + return nullptr; + } + ani_size index = 0; + for (auto ¬ification : notifications) { + if (notification == nullptr) { + ANS_LOGE("notification is nullptr"); + return nullptr; + } + ani_object item = ConvertNotificationToAni(env, notification.GetRefPtr()); + RETURN_NULL_IF_NULL(item); + if(ANI_OK != env->Object_CallMethodByName_Void(arrayObj, "$_set", "ILstd/core/Object;:V", index, item)){ + std::cerr << "Object_CallMethodByName_Void $_set Faild " << std::endl; + return nullptr; + } + index ++; + } + return arrayObj; +} +} // name space NotificationSts +} // name space OHOS diff --git a/frameworks/ani/notification_manager/src/sts_notification_slot.cpp b/frameworks/ani/notification_manager/src/sts_notification_slot.cpp new file mode 100644 index 0000000000000000000000000000000000000000..de950745558e05412a8daf7022e24f5fad807271 --- /dev/null +++ b/frameworks/ani/notification_manager/src/sts_notification_slot.cpp @@ -0,0 +1,119 @@ +/* + * 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 +#include "sts_common_util.h" +#include "ans_log_wrapper.h" +#include "sts_notification_slot.h" + +//using namespace OHOS::NotificationSts; +namespace OHOS { +namespace NotificationSts { + +bool WrapNotificationSlot(ani_env *env, sptr slot, ani_object &outAniObj) +{ + ANS_LOGD("WrapNotificationSlot call"); + if (slot == nullptr) { + ANS_LOGE("WrapNotificationSlot slot is null"); + return false; + } + ani_class cls; + if (!CreateClassObjByClassName(env, NotificationSlotClassName, cls, outAniObj)) { + ANS_LOGE("WrapNotificationSlot CreateClassObjByClassName fail"); + return false; + } + if (!SetOptionalFieldSlotType(env, cls, outAniObj, "notificationType", slot->GetType())) { + ANS_LOGE("WrapNotificationSlot Set notificationType fail"); + return false; + } + if (!SetFieldString(env, cls, outAniObj, "desc", slot->GetDescription())) { + ANS_LOGE("WrapNotificationSlot Set desc fail"); + return false; + } + if (!SetOptionalFieldBoolean(env, cls, outAniObj, "badgeFlag", slot->IsShowBadge())) { + ANS_LOGE("WrapNotificationSlot Set badgeFlag fail"); + return false; + } + if (!SetOptionalFieldBoolean(env, cls, outAniObj, "bypassDnd", slot->IsEnableBypassDnd())) { + ANS_LOGE("WrapNotificationSlot Set bypassDnd fail"); + return false; + } + if (!SetOptionalFieldDouble(env, cls, outAniObj, "lockscreenVisibility", static_cast(slot->GetLockScreenVisibleness()))) { + ANS_LOGE("WrapNotificationSlot Set lockscreenVisibility fail"); + return false; + } + if (!SetOptionalFieldBoolean(env, cls, outAniObj, "vibrationEnabled", slot->CanVibrate())) { + ANS_LOGE("WrapNotificationSlot Set vibrationEnabled fail"); + return false; + } + if (!SetFieldString(env, cls, outAniObj, "sound", slot->GetSound().ToString().c_str())) { + ANS_LOGE("WrapNotificationSlot Set sound fail"); + return false; + } + if (!SetOptionalFieldBoolean(env, cls, outAniObj, "lightEnabled", slot->CanEnableLight())) { + ANS_LOGE("WrapNotificationSlot Set lightEnabled fail"); + return false; + } + if (!SetOptionalFieldDouble(env, cls, outAniObj, "lightColor", static_cast(slot->GetLedLightColor()))) { + ANS_LOGE("WrapNotificationSlot Set lightColor fail"); + return false; + } + if (!SetOptionalFieldArrayDouble(env, cls, outAniObj, "vibrationValues", slot->GetVibrationStyle())) + { + ANS_LOGE("WrapNotificationSlot Set vibrationValues fail"); + return false; + } + if (!SetOptionalFieldBoolean(env, cls, outAniObj, "enabled", slot->GetEnable())) { + ANS_LOGE("WrapNotificationSlot Set enabled fail"); + return false; + } + if (!SetOptionalFieldDouble(env, cls, outAniObj, "reminderMode", static_cast(slot->GetReminderMode()))) { + ANS_LOGE("WrapNotificationSlot Set reminderMode fail"); + return false; + } + if (!SetOptionalFieldDouble(env, cls, outAniObj, "authorizedStatus", static_cast(slot->GetAuthorizedStatus()))) { + ANS_LOGE("WrapNotificationSlot Set authorizedStatus fail"); + return false; + } + ANS_LOGD("WrapNotificationSlot end"); + return true; +} + +bool WrapNotificationSlotArray(ani_env *env, const std::vector>& slots, ani_object &outAniObj) +{ + ANS_LOGD("WrapNotificationSlotArray call"); + outAniObj = newArrayClass(env, slots.size()); + if (outAniObj == nullptr) { + ANS_LOGE("WrapNotificationSlotArray outAniObj is null, newArrayClass Faild"); + return false; + } + int index = 0; + for (auto &it : slots) { + ani_object infoObj; + if (!WrapNotificationSlot(env, it, infoObj)) { + ANS_LOGE("WrapNotificationSlotArray WrapNotificationSlot Faild"); + return false; + } + ANI_FAILED_AND_RETURN(env->Object_CallMethodByName_Void(outAniObj, + "$_set", "ILstd/core/Object;:V", index, infoObj)); + index++; + } + + ANS_LOGD("WrapNotificationSlotArray end"); + return true; +} + +} +} \ No newline at end of file diff --git a/frameworks/ani/notification_manager/src/sts_notification_template.cpp b/frameworks/ani/notification_manager/src/sts_notification_template.cpp new file mode 100644 index 0000000000000000000000000000000000000000..47ee412e1603784f58b05a96b849b13aa20bc283 --- /dev/null +++ b/frameworks/ani/notification_manager/src/sts_notification_template.cpp @@ -0,0 +1,50 @@ +/* + * 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 "sts_notification_utils.h" + +#include "sts_common_util.h" +#include "ani_common_want.h" +#include "want_params.h" + +namespace OHOS { +namespace NotificationSts { +using namespace OHOS::AppExecFwk; +using namespace OHOS::AAFwk; +ani_status UnwrapNotificationTemplate(ani_env *env, ani_object aniObj, OHOS::Notification::NotificationTemplate& tmplate) +{ + ani_status status = ANI_ERROR; + ani_ref nameRef; + if (ANI_OK != (status = env->Object_CallMethodByName_Ref(aniObj, "name",":Lstd/core/String;", &nameRef))) { + return status; + } + std::string nameStr = ""; + if (ANI_OK != (status = GetStdString(env, static_cast(nameRef), nameStr))) { + return status; + } + ani_ref dataRef; + if (ANI_OK != (status = env->Object_GetPropertyByName_Ref(aniObj, "data", &dataRef))) { + return status; + } + WantParams wantParams; + if(!UnwrapWantParams(env, dataRef, wantParams)) { + return ANI_ERROR; + } + tmplate.SetTemplateName(nameStr); + tmplate.SetTemplateData(std::make_shared(wantParams)); + return status; +} +} +} diff --git a/frameworks/ani/notification_manager/src/sts_notification_user_input.cpp b/frameworks/ani/notification_manager/src/sts_notification_user_input.cpp new file mode 100644 index 0000000000000000000000000000000000000000..da67cd5d75c116c1ae57fa1a618763324c871310 --- /dev/null +++ b/frameworks/ani/notification_manager/src/sts_notification_user_input.cpp @@ -0,0 +1,34 @@ +/* + * 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 "sts_notification_utils.h" +#include "sts_common_util.h" + +namespace OHOS { +namespace NotificationSts { +ani_status UnwrapNotificationUserInput(ani_env *env, ani_object param, std::shared_ptr &userInput) +{ + ani_status status = ANI_ERROR; + std::string inputKey; + ani_boolean isUndefined = ANI_TRUE; + if((status = GetPropertyString(env, param, "inputKey", isUndefined, inputKey)) != ANI_OK + || isUndefined == ANI_TRUE) { + return ANI_INVALID_ARGS; + } + userInput = NotificationUserInput::Create(inputKey); + return status; +} +} +} \ No newline at end of file diff --git a/frameworks/ani/notification_manager/src/sts_notification_utils.cpp b/frameworks/ani/notification_manager/src/sts_notification_utils.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bf4baf847c4886e0a340dfe8cbd6e525214102f3 --- /dev/null +++ b/frameworks/ani/notification_manager/src/sts_notification_utils.cpp @@ -0,0 +1,116 @@ +/* + * 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 "sts_notification_utils.h" +#include "sts_common_util.h" +#include "pixel_map_ani.h" + +namespace OHOS { +namespace NotificationSts { + +void UnwrapWantAgent(ani_env *env, ani_object agent, void** result) +{ + ANS_LOGI("called"); + if (agent == nullptr) { + ANS_LOGI("agent null"); + return; + } + ani_long param_value; + ani_status status = ANI_ERROR; + ani_class cls = nullptr; + ani_method method {}; + if ((status = env->FindClass("Lstd/core/Long;", &cls)) != ANI_OK) { + ANS_LOGI("status : %{public}d", status); + return; + } + if ((status = env->Class_FindMethod(cls, "unboxed", nullptr, &method)) != ANI_OK) { + ANS_LOGI("status : %{public}d", status); + return; + } + if ((status = env->Object_CallMethod_Long(agent, method, ¶m_value)) != ANI_OK) { + ANS_LOGI("status : %{public}d", status); + return; + } + *result = reinterpret_cast(param_value); +} + +ani_object CreatePixelMap([[maybe_unused]] ani_env* env, std::shared_ptr pixelMap) +{ + if (pixelMap == nullptr) { + return nullptr; + } + std::unique_ptr pPixelMapAni = std::make_unique(); + pPixelMapAni->nativePixelMap_ = pixelMap; + static const char* className = "L@ohos/multimedia/image/image/PixelMapInner;"; + ani_class cls; + if (ANI_OK != env->FindClass(className, &cls)) { + ANS_LOGE("Not found L@ohos/multimedia/image/image/PixelMapInner"); + return nullptr; + } + ani_method ctor; + if (ANI_OK != env->Class_FindMethod(cls, "", "J:V", &ctor)) { + ANS_LOGE("Not found ani_method"); + return nullptr; + } + ani_object aniValue; + if (ANI_OK != env->Object_New(cls, ctor, &aniValue, reinterpret_cast(pPixelMapAni.release()))) { + ANS_LOGE("New Context Fail"); + } + return aniValue; +} + +std::shared_ptr GetPixelMapFromEnvSp([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object obj) +{ + ani_status ret; + ani_long nativeObj {}; + if ((ret = env->Object_GetFieldByName_Long(obj, "nativeObj", &nativeObj)) != ANI_OK) { + ANS_LOGI("[GetPixelMapFromEnv] Object_GetField_Long fetch failed"); + return nullptr; + } + PixelMapAni* pixelmapAni = reinterpret_cast(nativeObj); + if (!pixelmapAni) { + ANS_LOGI("[GetPixelMapFromEnv] pixelmapAni nullptr"); + return nullptr; + } + return pixelmapAni->nativePixelMap_; +} + +ani_status UnwrapResource(ani_env *env, ani_object obj, ResourceManager::Resource resource) +{ + ani_status status = ANI_ERROR; + std::string bundleName = ""; + ani_boolean isUndefined = ANI_TRUE; + if((status = GetPropertyString(env, obj, "bundleName", isUndefined, bundleName)) != ANI_OK + || isUndefined == ANI_TRUE) { + return ANI_INVALID_ARGS; + } + resource.bundleName = bundleName; + + std::string moduleName = ""; + if((status = GetPropertyString(env, obj, "moduleName", isUndefined, moduleName)) != ANI_OK + || isUndefined == ANI_TRUE) { + return ANI_INVALID_ARGS; + } + resource.moduleName = moduleName; + + ani_double idAni = 0.0; + if((status = GetPropertyDoubleOrUndefined(env, obj, "id", isUndefined, idAni)) != ANI_OK + || isUndefined == ANI_TRUE) { + return ANI_INVALID_ARGS; + } + resource.id = static_cast(idAni); + return status; +} +} +} \ No newline at end of file