From d9057970deaeb1025cacef94fd32011b30bcb40e Mon Sep 17 00:00:00 2001 From: zhang_hao_zheng Date: Thu, 12 Jun 2025 11:52:34 +0800 Subject: [PATCH 01/11] add EventHub.ets Signed-off-by: zhang_hao_zheng Change-Id: I90757b5337c86ebb53563c181da530626b12b931 --- frameworks/ets/ani/eventhub/BUILD.gn | 104 ++++++++ .../ets/ani/eventhub/include/ets_event_hub.h | 27 +++ .../ets/ani/eventhub/src/ets_hybridgref.cpp | 91 +++++++ .../ets/ani/eventhub/src/ts_hybridgref.cpp | 201 ++++++++++++++++ frameworks/ets/ets/application/EventHub.ets | 227 ++++++------------ frameworks/js/napi/app/context/context.js | 86 ++++++- 6 files changed, 585 insertions(+), 151 deletions(-) create mode 100644 frameworks/ets/ani/eventhub/BUILD.gn create mode 100644 frameworks/ets/ani/eventhub/include/ets_event_hub.h create mode 100644 frameworks/ets/ani/eventhub/src/ets_hybridgref.cpp create mode 100644 frameworks/ets/ani/eventhub/src/ts_hybridgref.cpp diff --git a/frameworks/ets/ani/eventhub/BUILD.gn b/frameworks/ets/ani/eventhub/BUILD.gn new file mode 100644 index 00000000000..747a6339c16 --- /dev/null +++ b/frameworks/ets/ani/eventhub/BUILD.gn @@ -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. + +import("//build/config/components/ets_frontend/ets2abc_config.gni") +import("//build/ohos.gni") +import("//foundation/ability/ability_runtime/ability_runtime.gni") + +ohos_shared_library("event_hub_ani_kit") { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + cfi_vcall_icall_only = true + debug = false + } + + include_dirs = [ + "./include", + "${ability_runtime_path}/frameworks/ets/ani/enum_convert", + "${ability_runtime_path}/interfaces/kits/native/ability/native", + "${ability_runtime_path}/interfaces/kits/native/appkit/ability_runtime/app", + "${ability_runtime_path}/interfaces/kits/native/appkit/ability_runtime/context", + "${ability_runtime_path}/interfaces/kits/native/appkit/ability_runtime/ability_delegator/include", + "${ability_runtime_services_path}/common/include", + ] + configs = [] + + public_configs = [] + + sources = [ "./src/ets_event_hub.cpp" ] + + cflags = [] + if (target_cpu == "arm") { + cflags += [ "-DBINDER_IPC_32BIT" ] + } + + deps = [ + "${ability_runtime_innerkits_path}/ability_manager:ability_manager", + "${ability_runtime_innerkits_path}/ability_manager:ability_start_options", + "${ability_runtime_innerkits_path}/error_utils:ability_runtime_error_util", + "${ability_runtime_innerkits_path}/runtime:runtime", + "${ability_runtime_path}/frameworks/ets/ani/ani_common:ani_common", + "${ability_runtime_napi_path}/inner/napi_common:napi_common", + "${ability_runtime_native_path}/ability/native:abilitykit_native", + "${ability_runtime_native_path}/ability/native:ability_business_error", + "${ability_runtime_native_path}/appkit:app_context", + "${ability_runtime_native_path}/appkit:appkit_delegator", + "${ability_runtime_native_path}/appkit:delegator_mgmt", + ] + + external_deps = [ + "ability_base:want", + "ability_base:zuri", + "access_token:libtokenid_sdk", + "bundle_framework:appexecfwk_base", + "c_utils:utils", + "common_event_service:cesfwk_innerkits", + "eventhandler:libeventhandler", + "hilog:libhilog", + "init:libbegetutil", + "ipc:ipc_core", + "ipc:ipc_napi", + "json:nlohmann_json_static", + "napi:ace_napi", + "runtime_core:ani", + "runtime_core:ani_helpers", + ] + + public_external_deps = [ "ability_base:configuration" ] + + innerapi_tags = [ "platformsdk" ] + subsystem_name = "ability" + part_name = "ability_runtime" +} + +generate_static_abc("uri_permission_manager_abc") { + base_url = "./ets" + + files = [ "./ets/@ohos.application.uriPermissionManager.ets" ] + + dst_file = "$target_out_dir/uri_permission_manager.abc" + out_puts = [ "$target_out_dir/uri_permission_manager.abc" ] + + is_boot_abc = "True" + device_dst_file = "/system/framework/uri_permission_manager.abc" +} + +ohos_prebuilt_etc("uri_permission_manager_abc_etc") { + source = "$target_out_dir/uri_permission_manager.abc" + module_install_dir = "framework" + subsystem_name = "ability" + part_name = "ability_runtime" + deps = [ ":uri_permission_manager_abc" ] +} \ No newline at end of file diff --git a/frameworks/ets/ani/eventhub/include/ets_event_hub.h b/frameworks/ets/ani/eventhub/include/ets_event_hub.h new file mode 100644 index 00000000000..e77363c3b59 --- /dev/null +++ b/frameworks/ets/ani/eventhub/include/ets_event_hub.h @@ -0,0 +1,27 @@ +/* + * 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_ABILITY_RUNTIME_EVENT_HUB_H +#define OHOS_ABILITY_RUNTIME_EVENT_HUB_H + +#include "sts_runtime.h" + +namespace OHOS { +namespace AbilityRuntime { +static void +} +} + +#endif // OHOS_ABILITY_RUNTIME_EVENT_HUB_H \ No newline at end of file diff --git a/frameworks/ets/ani/eventhub/src/ets_hybridgref.cpp b/frameworks/ets/ani/eventhub/src/ets_hybridgref.cpp new file mode 100644 index 00000000000..aaaec13bc94 --- /dev/null +++ b/frameworks/ets/ani/eventhub/src/ets_hybridgref.cpp @@ -0,0 +1,91 @@ +/* + * 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 "ets_event_hub.h" + +#include "hilog_tag_wrapper.h" +#include "interop_js/hybridgref_ani.h" +#include "interop_js/hybridgref_napi.h" +#include + +namespace OHOS { +namespace AbilityRuntime { + +static hybridgref g_ref = nullptr; +static napi_value NativeGetRef(napi_env env, [[maybe_unused]] napi_callback_info info) +{ + napi_value result {}; + if (!hybridgref_get_napi_value(env, g_ref, &result)) { + napi_get_undefined(env, &result); + } + return result; +} + +static void NativeSaveHybridGref(ani_env *env, ani_object ref) +{ + ASSERT_TRUE(hybridgref_create_from_ani(env, static_cast(ref), &g_ref)); +} + +class HybridGrefPrimitiveEtsToTs { +public: + static bool GetAniEnv(ani_env **env) + { + ani_vm *aniVm; + ani_size res; + + auto status = ANI_GetCreatedVMs(&aniVm, 1U, &res); + if (status != ANI_OK || res == 0) { + return false; + } + + status = aniVm->GetEnv(ANI_VERSION_1, env); + return status == ANI_OK && *env != nullptr; + } + + static bool RegisterNativeGetRef(napi_env env) + { + napi_value global; + if (napi_get_global(env, &global) != napi_ok) { + return false; + } + napi_value fn; + if (napi_create_function(env, "nativeGetRef", NAPI_AUTO_LENGTH, NativeGetRef, nullptr, &fn) != napi_ok) { + return false; + } + + if (napi_set_named_property(env, global, "nativeGetRef", fn) != napi_ok) { + return false; + } + + return true; + } + + static bool RegisterNativeSaveRef(ani_env *env) + { + ani_module etsMod {}; + auto status = env->FindModule("Lets_functions;", &etsMod); + if (status != ANI_OK) { + return false; + } + std::array methods = { + ani_native_function {"saveHybridGref", nullptr, reinterpret_cast(NativeSaveHybridGref)}, + }; + status = env->Module_BindNativeFunctions(etsMod, methods.data(), methods.size()); + return status == ANI_OK; + } +} + +} // namespace AbilityRuntime +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/ets/ani/eventhub/src/ts_hybridgref.cpp b/frameworks/ets/ani/eventhub/src/ts_hybridgref.cpp new file mode 100644 index 00000000000..28be46c2bdc --- /dev/null +++ b/frameworks/ets/ani/eventhub/src/ts_hybridgref.cpp @@ -0,0 +1,201 @@ +/* + * 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 "ets_event_hub.h" + +#include "hilog_tag_wrapper.h" +#include "interop_js/hybridgref_ani.h" +#include "interop_js/hybridgref_napi.h" +#include + +namespace OHOS { +namespace AbilityRuntime { + +static hybridgref g_jsToEtsEventHubOnRef = nullptr; +static hybridgref g_jsToEtsEventHubOffRef = nullptr; +static hybridgref g_jsToEtsEventHubEmitRef = nullptr; + +static napi_value NativeSaveEventHubOnRef(napi_env env, napi_callback_info info) +{ + size_t argc = 1; + napi_value argv[1]; // NOLINT(modernize-avoid-c-arrays) + napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); + + if (argc < 1) { + napi_value undefined; + napi_get_undefined(env, &undefined); + return undefined; + } + + if (g_jsToEtsEventHubOnRef != nullptr) { + hybridgref_delete_from_napi(env, g_jsToEtsEventHubOnRef); + g_jsToEtsEventHubOnRef = nullptr; + } + + bool ok = hybridgref_create_from_napi(env, argv[0], &g_jsToEtsEventHubOnRef); + napi_value result; + napi_get_boolean(env, ok, &result); + return result; +} + +static napi_value NativeSaveEventHubOffRef(napi_env env, napi_callback_info info) +{ + size_t argc = 1; + napi_value argv[1]; // NOLINT(modernize-avoid-c-arrays) + napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); + + if (argc < 1) { + napi_value undefined; + napi_get_undefined(env, &undefined); + return undefined; + } + + if (g_jsToEtsEventHubOffRef != nullptr) { + hybridgref_delete_from_napi(env, g_jsToEtsEventHubOffRef); + g_jsToEtsEventHubOffRef = nullptr; + } + + bool ok = hybridgref_create_from_napi(env, argv[0], &g_jsToEtsEventHubOffRef); + napi_value result; + napi_get_boolean(env, ok, &result); + return result; +} + +static napi_value NativeSaveEventHubEmitRef(napi_env env, napi_callback_info info) +{ + size_t argc = 1; + napi_value argv[1]; // NOLINT(modernize-avoid-c-arrays) + napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); + + if (argc < 1) { + napi_value undefined; + napi_get_undefined(env, &undefined); + return undefined; + } + + if (g_jsToEtsEventHubEmitRef != nullptr) { + hybridgref_delete_from_napi(env, g_jsToEtsEventHubEmitRef); + g_jsToEtsEventHubEmitRef = nullptr; + } + + bool ok = hybridgref_create_from_napi(env, argv[0], &g_jsToEtsEventHubEmitRef); + napi_value result; + napi_get_boolean(env, ok, &result); + return result; +} + +static ani_object NativeGetEventHubOnRef(ani_env *env) +{ + ani_object result {}; + hybridgref_get_esvalue(env, g_jsToEtsEventHubOnRef, &result); + return result; +} + +static ani_object NativeGetEventHubOffRef(ani_env *env) +{ + ani_object result {}; + hybridgref_get_esvalue(env, g_jsToEtsEventHubOffRef, &result); + return result; +} + +static ani_object NativeGetEventHubEmitRef(ani_env *env) +{ + ani_object result {}; + hybridgref_get_esvalue(env, g_jsToEtsEventHubEmitRef, &result); + return result; +} + +class NativeGrefTsToEts { +public: + static bool GetAniEnv(ani_env **env) + { + ani_vm *aniVm; + ani_size res; + + auto status = ANI_GetCreatedVMs(&aniVm, 1U, &res); + if (status != ANI_OK || res == 0) { + return false; + } + + status = aniVm->GetEnv(ANI_VERSION_1, env); + return status == ANI_OK && *env != nullptr; + } + + static bool RegisterNativeSaveRef(napi_env env) + { + napi_value global; + if (napi_get_global(env, &global) != napi_ok) { + return false; + } + + napi_value nativeSaveEventHubOnFn; + if (napi_create_function(env, "nativeSaveEventHubOnRef", NAPI_AUTO_LENGTH, NativeSaveEventHubOnRef, nullptr, &nativeSaveEventHubOnFn) != napi_ok) { + return false; + } + if (napi_set_named_property(env, global, "nativeSaveEventHubOnRef", nativeSaveEventHubOnFn) != napi_ok) { + return false; + } + + napi_value nativeSaveEventHubOffFn; + if (napi_create_function(env, "nativeSaveEventHubOffRef", NAPI_AUTO_LENGTH, NativeSaveEventHubOffRef, nullptr, &nativeSaveEventHubOffFn) != napi_ok) { + return false; + } + if (napi_set_named_property(env, global, "nativeSaveEventHubOffRef", nativeSaveEventHubOffFn) != napi_ok) { + return false; + } + + napi_value nativeSaveEventHubEmitFn; + if (napi_create_function(env, "nativeSaveEventHubOffRef", NAPI_AUTO_LENGTH, NativeSaveEventHubOffRef, nullptr, &nativeSaveEventHubEmitFn) != napi_ok) { + return false; + } + if (napi_set_named_property(env, global, "nativeSaveEventHubOffRef", nativeSaveEventHubEmitFn) != napi_ok) { + return false; + } + + napi_value nativeReleaseRefsFn; + if (napi_create_function(env, "nativeReleaseEventHubRefs", NAPI_AUTO_LENGTH, + [](napi_env env, napi_callback_info info) -> napi_value { + ani_env *aniEnv = nullptr; + if (GetAniEnv(&aniEnv)) { + NativeReleaseEventHubRefs(aniEnv); + } + return nullptr; + }, nullptr, &nativeReleaseRefsFn) != napi_ok) { + return false; + } + if (napi_set_named_property(env, global, "nativeReleaseEventHubRefs", nativeReleaseRefsFn) != napi_ok) { + return false; + } + + return true; + } + + static bool RegisterETSGetter(ani_env *env) + { + ani_module mod {}; + if (env->FindModule("Lets_functions;", &mod) != ANI_OK) { + return false; + } + + std::array methods = { + ani_native_function {"nativeGetEventHubOnRef", nullptr, reinterpret_cast(NativeGetEventHubOnRef)}, + ani_native_function {"nativeGetEventHubOffRef", nullptr, reinterpret_cast(nativeGetEventHubOffRef)}, + ani_native_function {"nativeGetEventHubEmitRef", nullptr, reinterpret_cast(nativeGetEventHubEmitRef)}, + }; + return env->Module_BindNativeFunctions(mod, methods.data(), methods.size()) == ANI_OK; + } +} +} // namespace AbilityRuntime +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/ets/ets/application/EventHub.ets b/frameworks/ets/ets/application/EventHub.ets index e207537e509..4ccb62d5ecf 100644 --- a/frameworks/ets/ets/application/EventHub.ets +++ b/frameworks/ets/ets/application/EventHub.ets @@ -13,180 +13,107 @@ * limitations under the License. */ -export default class EventHub { - private eventMap: Map> = new Map>(); - - private getCloneArray(event: string): Array { - if (this.eventMap.get(event)) { - const array: Array = this.eventMap.get(event) as Array; - const cloneArray = deepcopy>(array) as Array; - return cloneArray; - } - return new Array(); - } - - on(event: string, callback: Object) { - if (!this.eventMap.get(event)) { - this.eventMap.set(event, new Array()); - } - let array: Array = this.eventMap.get(event) as Array; - if (array.indexOf(callback) === -1) { - array.push(callback); - } - } - - off(event: string, callback: Object) { - if (this.eventMap.get(event)) { - let cbArray: Array = this.eventMap.get(event) as Array; - let index: number = cbArray.indexOf(callback); - if (index > -1) { - for (; index + 1 < cbArray.length; index++) { - cbArray[index] = cbArray[index + 1]; - } - cbArray.pop(); - } - } - } - - off(event: string) { - if (this.eventMap.get(event)) { - this.eventMap.delete(event); - } - } - - emit(event:string) { - const cloneArray: Array = this.getCloneArray(event); - for (let i = 0; i < cloneArray.length; ++i) { - let f = cloneArray[i] as () => void; - f(); - } - } - - emit(event:string, p1: P1) { - const cloneArray: Array = this.getCloneArray(event); - for (let i = 0; i < cloneArray.length; ++i) { - let f = cloneArray[i] as (p1: P1) => void; - f(p1); - } - } - - emit(event: string, p1: P1, p2: P2) { - const cloneArray: Array = this.getCloneArray(event); - for (let i = 0; i < cloneArray.length; ++i) { - const f = cloneArray[i] as (p1: P1, p2: P2) => void; - f(p1, p2); - } - } +// eventHub.ets +native function nativeGetEventHubOnRef(): ESObject; +native function nativeGetEventHubOffRef(): ESObject; +native function nativeGetEventHubEmitRef(): ESObject; - emit(event: string, p1: P1, p2: P2, p3: P3) { - const cloneArray: Array = this.getCloneArray(event); - for (let i = 0; i < cloneArray.length; ++i) { - const f = cloneArray[i] as (p1: P1, p2: P2, p3: P3) => void; - f(p1, p2, p3); - } - } +type refType = Object | ESObject; +native function saveEventHubOnHybridGref(ref: refType): void; +native function saveEventHubOffHybridGref(ref: refType): void; +native function saveEventHubEmitHybridGref(ref: refType): void; - emit(event: string, p1: P1, p2: P2, p3: P3, p4: P4) { - const cloneArray: Array = this.getCloneArray(event); - for (let i = 0; i < cloneArray.length; ++i) { - const f = cloneArray[i] as (p1: P1, p2: P2, p3: P3, p4: P4) => void; - f(p1, p2, p3, p4); - } - } - - emit(event: string, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5) { - const cloneArray: Array = this.getCloneArray(event); - for (let i = 0; i < cloneArray.length; ++i) { - const f = cloneArray[i] as (p1: P1, p2: P2, p3: P3, p4: P4, p5: P5) => void; - f(p1, p2, p3, p4, p5); - } - } +export default class EventHub { + private eventMap: Map = new Map(); - emit(event: string, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6) { - const cloneArray: Array = this.getCloneArray(event); - for (let i = 0; i < cloneArray.length; ++i) { - const f = cloneArray[i] as (p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6) => void; - f(p1, p2, p3, p4, p5, p6); - } + constructor() { + saveEventHubOnHybridGref({ + registerOn: (event: string, callback: Function) => this.registerOnCallback(event, callback, true) + }); + saveEventHubOffHybridGref({ + registerOff: (event: string, callback?: Function) => this.registerOffCallback(event, callback, true) + }) + saveEventHubEmitHybridGref({ + registerEmit: (event: string, ...args: FixedArray) => this.registerEmitCallback(event, ...args) + }) } - emit(event: string, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7) { - const cloneArray: Array = this.getCloneArray(event); - for (let i = 0; i < cloneArray.length; ++i) { - const f = cloneArray[i] as (p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7) => void; - f(p1, p2, p3, p4, p5, p6, p7); + private registerOnCallback(event: string, callback: Function): void { + if (!this.eventMap.has(event)) { + this.eventMap.set(event, []); } - } - - emit(event: string, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8) { - const cloneArray: Array = this.getCloneArray(event); - for (let i = 0; i < cloneArray.length; ++i) { - const f = cloneArray[i] as (p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8) => void; - f(p1, p2, p3, p4, p5, p6, p7, p8); + + const callbacks = this.eventMap.get(event)!; + if (!callbacks.includes(callback)) { + callbacks.push(callback); } } - emit(event: string, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9) { - const cloneArray: Array = this.getCloneArray(event); - for (let i = 0; i < cloneArray.length; ++i) { - const f = cloneArray[i] as (p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9) => void; - f(p1, p2, p3, p4, p5, p6, p7, p8, p9); - } - } + on(event: string, callback: Function, fromNative = false): void { + this.registerOnCallback(event, callback); - emit(event: string, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10) { - const cloneArray: Array = this.getCloneArray(event); - for (let i = 0; i < cloneArray.length; ++i) { - const f = cloneArray[i] as (p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10) => void; - f(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); + if (!fromNative) { + const nativeObj = this.nativeGetEventHubOnRef(); + if (nativeObj) { + obj.invokeMethod(event, callback); + } } } - emit(event: string, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11) { - const cloneArray: Array = this.getCloneArray(event); - for (let i = 0; i < cloneArray.length; ++i) { - const f = cloneArray[i] as (p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11) => void; - f(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); + private registerOffCallback(event: string, callback?: Function): void { + if (!this.eventMap.has(event)) { + return; } - } - - emit(event: string, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12) { - const cloneArray: Array = this.getCloneArray(event); - for (let i = 0; i < cloneArray.length; ++i) { - const f = cloneArray[i] as (p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12) => void; - f(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); + + if (!callback) { + this.eventMap.delete(event); + } else { + const callbacks = this.eventMap.get(event)!; + const index = callbacks.indexOf(callback); + if (index > -1) { + callbacks.splice(index, 1); + } + + if (callbacks.length === 0) { + this.eventMap.delete(event); + } } } - emit(event: string, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13) { - const cloneArray: Array = this.getCloneArray(event); - for (let i = 0; i < cloneArray.length; ++i) { - const f = cloneArray[i] as (p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13) => void; - f(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); - } - } + off(event: string, callback?: Function, fromNative = false): void { + this.registerOffCallback(event, callback); - emit(event: string, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14) { - const cloneArray: Array = this.getCloneArray(event); - for (let i = 0; i < cloneArray.length; ++i) { - const f = cloneArray[i] as (p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14) => void; - f(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14); + if (!fromNative) { + const nativeObj = this.nativeGetEventHubOffRef(); + if (nativeObj) { + if (callback) { + nativeObj.callFunction(event, callback); + } else { + nativeObj.callFunction(event); + } + } } } - emit(event: string, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14, p15: P15) { - const cloneArray: Array = this.getCloneArray(event); - for (let i = 0; i < cloneArray.length; ++i) { - const f = cloneArray[i] as (p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14, p15: P15) => void; - f(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15); + private registerEmitCallback(event: string, args: FixedArray[]): void { + if (!this.eventMap.has(event)) { + return; } + + const callbacks = [...this.eventMap.get(event)!]; + callbacks.forEach(callback => { + try { + callback.unsafeCall(...args); + } catch (e) { + console.error(`Error triggering event '${event}':`, e); + } + }); } - emit(event: string, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14, p15: P15, p16: P16) { - const cloneArray: Array = this.getCloneArray(event); - for (let i = 0; i < cloneArray.length; ++i) { - const f = cloneArray[i] as (p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14, p15: P15, p16: P16) => void; - f(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16); + emit(event: string, ...args: FixedArray): void { + this.registerEmitCallback(event, args); + if (nativeObj) { + nativeObj.callFunction(event, ...args); } } } \ No newline at end of file diff --git a/frameworks/js/napi/app/context/context.js b/frameworks/js/napi/app/context/context.js index ed65a7c7aec..2c6153b75b5 100644 --- a/frameworks/js/napi/app/context/context.js +++ b/frameworks/js/napi/app/context/context.js @@ -13,12 +13,60 @@ * limitations under the License. */ +// eventHub.js +let etsOnHandler = null; +let etsOffHandler = null; +let etsEmitHandler = null; + +globalThis.nativeSaveEventHubOnRef = (handler) => { + etsOnHandler = handler; +}; + +globalThis.nativeSaveEventHubOffRef = (handler) => { + etsOffHandler = handler; +} + +globalThis.nativeSaveEventHubEmitRef = (handler) => { + etsEmitHandler = handler; +} + class EventHub { constructor() { this.eventMap = {}; + this.initNativeCommunication(); } - on(event, callback) { + initNativeCommunication() { + const onHandler = { + handleOn: (event, callback) => { + this.on(event, callback, true) + } + }; + + const offHandler = { + handleOff: (event, callback) => { + this.off(event, callback, true) + } + }; + + const emitHandler = { + handleEmit: (event, callback) => { + this.emit(event, ...args); + } + } + + if (globalThis.nativeSaveEventHubOnRef) { + globalThis.nativeSaveEventHubOnRef(onHandler); + } + if (globalThis.nativeSaveEventHubOffRef) { + globalThis.nativeSaveEventHubOffRef(offHandler); + } + if (globalThis.nativeSaveEventHubEmitRef) { + globalThis.nativeSaveEventHubEmitRef(emitHandler); + } + } + + on(event, callback, fromNative = false) { if ((typeof (event) !== 'string') || (typeof (callback) !== 'function')) { return; } @@ -28,6 +76,14 @@ class EventHub { if (this.eventMap[event].indexOf(callback) === -1) { this.eventMap[event].push(callback); } + + if (!fromNative && etsOnHandler) { + try { + etsOnHandler.handleOn(event, callback); + } catch (e) { + console.error(`Failed to register event '${event}' with Native: `, e); + } + } } off(event, callback) { @@ -48,6 +104,18 @@ class EventHub { delete this.eventMap[event]; } } + + if (!fromNative && etsOffHandler) { + try { + if (callback) { + etsOffHandler.handleOff(event, callback); + } else { + etsOffHandler.handleOff(event); + } + } catch (e) { + console.error(`Failed to unregister event '${event}' with Native:`, e); + } + } } emit(event, ...args) { @@ -61,6 +129,22 @@ class EventHub { cloneArray[i].apply(this, args); } } + + if (etsEmitHandler) { + try { + etsEmitHandler.handleEmit(event, ...args); + } catch (e) { + console.error(`Failed to emit event '${event}' to Native:`, e); + } + } + } + + dispose() { + this.eventMap = {}; + + if (globalThis.nativeReleaseEventHubRefs) { + globalThis.nativeReleaseEventHubRefs(); + } } } -- Gitee From 858f2971bee599e57e9ea65bca9d1fdfbdfd2259 Mon Sep 17 00:00:00 2001 From: zhang_hao_zheng Date: Thu, 12 Jun 2025 17:04:01 +0800 Subject: [PATCH 02/11] add gn Signed-off-by: zhang_hao_zheng Change-Id: Id4ecbcc85edc428936997694a2551b8b8b889a52 --- frameworks/ets/ani/BUILD.gn | 1 + .../ets/ani/{eventhub => event_hub}/BUILD.gn | 30 +----- .../include/ets_hybridgref.h} | 18 ++-- .../ets/ani/event_hub/include/event_hub.h | 1 + .../ets/ani/event_hub/include/ts_hybridgref.h | 32 ++++++ .../src/ets_hybridgref.cpp | 0 .../ets/ani/event_hub/src/event_hub.cpp | 69 +++++++++++++ .../src/ts_hybridgref.cpp | 4 +- frameworks/js/napi/app/context/BUILD.gn | 4 + .../js/napi/app/context/context_module.cpp | 2 + frameworks/native/runtime/interop_guard.cpp | 98 +++++++++++++++++++ 11 files changed, 224 insertions(+), 35 deletions(-) rename frameworks/ets/ani/{eventhub => event_hub}/BUILD.gn (79%) rename frameworks/ets/ani/{eventhub/include/ets_event_hub.h => event_hub/include/ets_hybridgref.h} (73%) create mode 100644 frameworks/ets/ani/event_hub/include/event_hub.h create mode 100644 frameworks/ets/ani/event_hub/include/ts_hybridgref.h rename frameworks/ets/ani/{eventhub => event_hub}/src/ets_hybridgref.cpp (100%) create mode 100644 frameworks/ets/ani/event_hub/src/event_hub.cpp rename frameworks/ets/ani/{eventhub => event_hub}/src/ts_hybridgref.cpp (98%) create mode 100644 frameworks/native/runtime/interop_guard.cpp diff --git a/frameworks/ets/ani/BUILD.gn b/frameworks/ets/ani/BUILD.gn index f487ec8a122..03e54954293 100644 --- a/frameworks/ets/ani/BUILD.gn +++ b/frameworks/ets/ani/BUILD.gn @@ -28,5 +28,6 @@ group("ani_packages") { "${ability_runtime_path}/frameworks/ets/ani/uri_permission_manager:uri_permission_manager_ani_kit", "${ability_runtime_path}/frameworks/ets/ani/wantagent:aniwantagent", "${ability_runtime_path}/frameworks/ets/ani/application:application_ani", + "${ability_runtime_path}/frameworks/ets/ani/event_hub:event_hub_ani_kit", ] } \ No newline at end of file diff --git a/frameworks/ets/ani/eventhub/BUILD.gn b/frameworks/ets/ani/event_hub/BUILD.gn similarity index 79% rename from frameworks/ets/ani/eventhub/BUILD.gn rename to frameworks/ets/ani/event_hub/BUILD.gn index 747a6339c16..c5d91807f0f 100644 --- a/frameworks/ets/ani/eventhub/BUILD.gn +++ b/frameworks/ets/ani/event_hub/BUILD.gn @@ -37,7 +37,11 @@ ohos_shared_library("event_hub_ani_kit") { public_configs = [] - sources = [ "./src/ets_event_hub.cpp" ] + sources = [ + "./src/ts_hybridgrep.cpp", + "./src/ets_hybridgrep.cpp", + "./src/event_hub.cpp", + ] cflags = [] if (target_cpu == "arm") { @@ -59,8 +63,6 @@ ohos_shared_library("event_hub_ani_kit") { ] external_deps = [ - "ability_base:want", - "ability_base:zuri", "access_token:libtokenid_sdk", "bundle_framework:appexecfwk_base", "c_utils:utils", @@ -68,8 +70,6 @@ ohos_shared_library("event_hub_ani_kit") { "eventhandler:libeventhandler", "hilog:libhilog", "init:libbegetutil", - "ipc:ipc_core", - "ipc:ipc_napi", "json:nlohmann_json_static", "napi:ace_napi", "runtime_core:ani", @@ -81,24 +81,4 @@ ohos_shared_library("event_hub_ani_kit") { innerapi_tags = [ "platformsdk" ] subsystem_name = "ability" part_name = "ability_runtime" -} - -generate_static_abc("uri_permission_manager_abc") { - base_url = "./ets" - - files = [ "./ets/@ohos.application.uriPermissionManager.ets" ] - - dst_file = "$target_out_dir/uri_permission_manager.abc" - out_puts = [ "$target_out_dir/uri_permission_manager.abc" ] - - is_boot_abc = "True" - device_dst_file = "/system/framework/uri_permission_manager.abc" -} - -ohos_prebuilt_etc("uri_permission_manager_abc_etc") { - source = "$target_out_dir/uri_permission_manager.abc" - module_install_dir = "framework" - subsystem_name = "ability" - part_name = "ability_runtime" - deps = [ ":uri_permission_manager_abc" ] } \ No newline at end of file diff --git a/frameworks/ets/ani/eventhub/include/ets_event_hub.h b/frameworks/ets/ani/event_hub/include/ets_hybridgref.h similarity index 73% rename from frameworks/ets/ani/eventhub/include/ets_event_hub.h rename to frameworks/ets/ani/event_hub/include/ets_hybridgref.h index e77363c3b59..35146131980 100644 --- a/frameworks/ets/ani/eventhub/include/ets_event_hub.h +++ b/frameworks/ets/ani/event_hub/include/ets_hybridgref.h @@ -11,17 +11,19 @@ * 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_ABILITY_RUNTIME_EVENT_HUB_H -#define OHOS_ABILITY_RUNTIME_EVENT_HUB_H +#ifndef ETS_HYBRIDGREF_H +#define ETS_HYBRIDGREF_H -#include "sts_runtime.h" +#include "ts_hybridgref.h" namespace OHOS { namespace AbilityRuntime { -static void -} -} -#endif // OHOS_ABILITY_RUNTIME_EVENT_HUB_H \ No newline at end of file +bool RegisterNativeGetRef(napi_env env); +bool RegisterNativeSaveRef(ani_env* env); + +} // namespace AbilityRuntime +} // namespace OHOS +#endif // ETS_HYBRIDGREF_H \ No newline at end of file diff --git a/frameworks/ets/ani/event_hub/include/event_hub.h b/frameworks/ets/ani/event_hub/include/event_hub.h new file mode 100644 index 00000000000..56a6051ca2b --- /dev/null +++ b/frameworks/ets/ani/event_hub/include/event_hub.h @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/frameworks/ets/ani/event_hub/include/ts_hybridgref.h b/frameworks/ets/ani/event_hub/include/ts_hybridgref.h new file mode 100644 index 00000000000..de14e97b137 --- /dev/null +++ b/frameworks/ets/ani/event_hub/include/ts_hybridgref.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 TS_HYBRIDGREF_H +#define TS_HYBRIDGREF_H + +#include +#include "napi/native_api.h" +#include "native_engine/native_engine.h" + +namespace OHOS { +namespace AbilityRuntime { +using hybridgref = void*; + +bool RegisterNativeSaveRef(napi_env env); +bool RegisterETSGetter(ani_env* env); + +} // namespace AbilityRuntime +} // namespace OHOS +#endif // TS_HYBRIDGREF_H \ No newline at end of file diff --git a/frameworks/ets/ani/eventhub/src/ets_hybridgref.cpp b/frameworks/ets/ani/event_hub/src/ets_hybridgref.cpp similarity index 100% rename from frameworks/ets/ani/eventhub/src/ets_hybridgref.cpp rename to frameworks/ets/ani/event_hub/src/ets_hybridgref.cpp diff --git a/frameworks/ets/ani/event_hub/src/event_hub.cpp b/frameworks/ets/ani/event_hub/src/event_hub.cpp new file mode 100644 index 00000000000..40fd4753448 --- /dev/null +++ b/frameworks/ets/ani/event_hub/src/event_hub.cpp @@ -0,0 +1,69 @@ +/* + * 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 "ts_hybridgref.h" +#include "ets_hybridgref.h" +#include +#include "hilog_tag_wrapper.h" + +using namespace AbilityRuntime; + +static napi_value Init(napi_env env, napi_value exports) { + + if (!RegisterNativeSaveRef(env)) { + TAG_LOGE(AAFwkTag::APPKIT, "Failed to register NativeSaveRef functions"); + } + + // 注册 ETS 到 TS 的功能 + ani_env* aniEnv = nullptr; + if (NativeGrefTsToEts::GetAniEnv(&aniEnv)) { + if (!RegisterETSGetter(aniEnv)) { + TAG_LOGI(AAFwkTag::APPKIT\, ("Failed to register ETS getter functions"); + } + } else { + TAG_LOGE(AAFwkTag::APPKIT, "Failed to get ANI environment"); + } + + // 注册 ETS 侧功能 + if (aniEnv) { + if (!HybridGrefPrimitiveEtsToTs::RegisterNativeSaveRef(aniEnv)) { + TAG_LOGE(AAFwkTag::APPKIT, "Failed to register ETS save functions"); + } + } + + // 注册 JS 侧功能 + if (!HybridGrefPrimitiveEtsToTs::RegisterNativeGetRef(env)) { + TAG_LOGE(AAFwkTag::APPKIT, "Failed to register JS getter functions"); + } + + return exports; +} + +// 模块注册 +EXTERN_C_START +static napi_module eventhub_module = { + .nm_version = 1, + .nm_flags = 0, + .nm_filename = nullptr, + .nm_register_func = Init, + .nm_modname = "eventhub", + .nm_priv = nullptr, + .reserved = {0}, +}; +EXTERN_C_END + +extern "C" __attribute__((constructor)) void RegisterModule() { + napi_module_register(&eventhub_module); +} \ No newline at end of file diff --git a/frameworks/ets/ani/eventhub/src/ts_hybridgref.cpp b/frameworks/ets/ani/event_hub/src/ts_hybridgref.cpp similarity index 98% rename from frameworks/ets/ani/eventhub/src/ts_hybridgref.cpp rename to frameworks/ets/ani/event_hub/src/ts_hybridgref.cpp index 28be46c2bdc..f048373c1ec 100644 --- a/frameworks/ets/ani/eventhub/src/ts_hybridgref.cpp +++ b/frameworks/ets/ani/event_hub/src/ts_hybridgref.cpp @@ -191,8 +191,8 @@ public: std::array methods = { ani_native_function {"nativeGetEventHubOnRef", nullptr, reinterpret_cast(NativeGetEventHubOnRef)}, - ani_native_function {"nativeGetEventHubOffRef", nullptr, reinterpret_cast(nativeGetEventHubOffRef)}, - ani_native_function {"nativeGetEventHubEmitRef", nullptr, reinterpret_cast(nativeGetEventHubEmitRef)}, + ani_native_function {"nativeGetEventHubOffRef", nullptr, reinterpret_cast(NativeGetEventHubOffRef)}, + ani_native_function {"nativeGetEventHubEmitRef", nullptr, reinterpret_cast(NativeGetEventHubEmitRef)}, }; return env->Module_BindNativeFunctions(mod, methods.data(), methods.size()) == ANI_OK; } diff --git a/frameworks/js/napi/app/context/BUILD.gn b/frameworks/js/napi/app/context/BUILD.gn index 46d7a1c625b..bc75c83ab5e 100644 --- a/frameworks/js/napi/app/context/BUILD.gn +++ b/frameworks/js/napi/app/context/BUILD.gn @@ -13,6 +13,7 @@ import("//build/config/components/ets_frontend/es2abc_config.gni") import("//build/ohos.gni") +import("//foundation/ability/ability_runtime/ability_runtime.gni") es2abc_gen_abc("gen_context_abc") { src_js = rebase_path("context.js") @@ -36,7 +37,10 @@ gen_js_obj("context_abc") { ohos_shared_library("context_napi") { sources = [ "context_module.cpp" ] + include_dirs = [ "${ability_runtime_path}/frameworks/ets/ani/event_hub/include" ] + deps = [ + "${ability_runtime_path}/frameworks/ets/ani/event_hub:event_hub_ani_kit", ":context_abc", ":context_js", ] diff --git a/frameworks/js/napi/app/context/context_module.cpp b/frameworks/js/napi/app/context/context_module.cpp index 0bb370f1f31..2d0b1847df9 100644 --- a/frameworks/js/napi/app/context/context_module.cpp +++ b/frameworks/js/napi/app/context/context_module.cpp @@ -14,6 +14,7 @@ */ #include "native_engine/native_engine.h" +#include "event_hub.h" extern const char _binary_context_js_start[]; extern const char _binary_context_js_end[]; @@ -23,6 +24,7 @@ extern const char _binary_context_abc_end[]; static napi_module _module = { .nm_version = 0, .nm_filename = "application/libcontext_napi.so/context.js", + .nm_register_func = OHOS:AbilityRuntim::InitEventHubNapi, .nm_modname = "application.Context", }; diff --git a/frameworks/native/runtime/interop_guard.cpp b/frameworks/native/runtime/interop_guard.cpp new file mode 100644 index 00000000000..b57beaf9f9b --- /dev/null +++ b/frameworks/native/runtime/interop_guard.cpp @@ -0,0 +1,98 @@ +/* + * 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 "interop_guard.h" + +#include "hilog_tag_wrapper.h" +#include "interop_js/hybridgref_ani.h" +#include "interop_js/hybridgref_napi.h" + +namespace OHOS { +namespace AbilityRuntime { +InteropGuard::InteropGuard(ani_env *env, ani_ref ref) +{ + if (env == nullptr || ref == nullptr) { + TAG_LOGE(AAFwkTag::JSRUNTIME, "invalid args"); + return; + } + ani_vm *aniVM = nullptr; + if (env->GetVM(&aniVM) != ANI_OK) { + TAG_LOGE(AAFwkTag::JSRUNTIME, "GetVM failed"); + return; + } + vm_ = aniVM; + hybridgref_create_from_ani(env, ref, &ref_); +} + +InteropGuard::InteropGuard(napi_env env, napi_value, value) +{ + if (env == nullptr || value == nullptr) { + TAG_LOGE(AAFwkTag::JSRUNTIME, "invalid args"); + return; + } + env_ = env; + hybridgref_create_from_napi(env, value, &ref_); +} + +ani_env* InteropGuard::GetAniEnv() +{ + if (vm_ == nullptr) { + TAG_LOGE(AAFwkTag::JSRUNTIME, "null vm"); + return nullptr; + } + ani_env* aniEnv = nullptr; + if (vm_->GetEnv(ANI_VERSION_1, &aniEnv) != ANI_OK) { + return nullptr; + } + return aniEnv; +} + +InteropGuard::~InteropGuard() +{ + if (ref_ == nullptr) { + return; + } + if (vm_ != nullptr) { + ani_env *env = GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::JSRUNTIME, "null env"); + return; + } + hybridgref_delete_from_ani(env, ref_); + return; + } + + if (env_ != nullptr) { + hybridgref_delete_from_napi(env_, ref_); + } +} + +ani_object InteropGuard::GetAniValue(ani_env, *env) +{ + ani_object result = nullptr; + hybridgref_get_esvalue(env, ref_, &result); + return result; +} + +napi_value InteropGuard::GetNapiValue(napi_env env) +{ + napi_value result {}; + if (!hybridgref_get_napi_value(env, ref_, &result)) { + napi_get_undefined(env, &result); + } + return result; +} +} // namespace AbilityRuntime +} // namespace OHOS \ No newline at end of file -- Gitee From c938bb9ac83ec646e557fee93febfade34178522 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=98=8A=E5=B3=A5?= Date: Sat, 14 Jun 2025 08:47:18 +0000 Subject: [PATCH 03/11] update frameworks/ets/ani/event_hub/include/ets_hybridgref.h. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 张昊峥 --- .../ets/ani/event_hub/include/ets_hybridgref.h | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/frameworks/ets/ani/event_hub/include/ets_hybridgref.h b/frameworks/ets/ani/event_hub/include/ets_hybridgref.h index 35146131980..def4f06a39b 100644 --- a/frameworks/ets/ani/event_hub/include/ets_hybridgref.h +++ b/frameworks/ets/ani/event_hub/include/ets_hybridgref.h @@ -15,15 +15,18 @@ #ifndef ETS_HYBRIDGREF_H #define ETS_HYBRIDGREF_H - + #include "ts_hybridgref.h" - +#include "sts_runtime.h" + namespace OHOS { namespace AbilityRuntime { - -bool RegisterNativeGetRef(napi_env env); -bool RegisterNativeSaveRef(ani_env* env); - + +class HybridGrefPrimitiveEtsToTs { +public: + static bool RegisterNativeGetRef(napi_env env); + static bool RegisterNativeSaveRef(ani_env* env); +}; } // namespace AbilityRuntime } // namespace OHOS #endif // ETS_HYBRIDGREF_H \ No newline at end of file -- Gitee From 93c1b2f718b235a55be8c85560ecea78b8c844b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=98=8A=E5=B3=A5?= Date: Sat, 14 Jun 2025 08:47:56 +0000 Subject: [PATCH 04/11] update frameworks/ets/ani/event_hub/include/event_hub.h. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 张昊峥 --- .../ets/ani/event_hub/include/event_hub.h | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/frameworks/ets/ani/event_hub/include/event_hub.h b/frameworks/ets/ani/event_hub/include/event_hub.h index 56a6051ca2b..18135075f7b 100644 --- a/frameworks/ets/ani/event_hub/include/event_hub.h +++ b/frameworks/ets/ani/event_hub/include/event_hub.h @@ -1 +1,32 @@ -1 \ No newline at end of file +/* + * 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 ETS_HYBRIDGREF_H +#define ETS_HYBRIDGREF_H + +#include "ts_hybridgref.h" +#include "sts_runtime.h" + +namespace OHOS { +namespace AbilityRuntime { + +class HybridGrefPrimitiveEtsToTs { +public: + static bool RegisterNativeGetRef(napi_env env); + static bool RegisterNativeSaveRef(ani_env* env); +}; +} // namespace AbilityRuntime +} // namespace OHOS +#endif // ETS_HYBRIDGREF_H \ No newline at end of file -- Gitee From a3bf6af3367395925a7c6defbf165830006e1248 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=98=8A=E5=B3=A5?= Date: Sat, 14 Jun 2025 08:48:27 +0000 Subject: [PATCH 05/11] update frameworks/ets/ani/event_hub/include/ts_hybridgref.h. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 张昊峥 --- .../ets/ani/event_hub/include/ts_hybridgref.h | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/frameworks/ets/ani/event_hub/include/ts_hybridgref.h b/frameworks/ets/ani/event_hub/include/ts_hybridgref.h index de14e97b137..3ab3b794fca 100644 --- a/frameworks/ets/ani/event_hub/include/ts_hybridgref.h +++ b/frameworks/ets/ani/event_hub/include/ts_hybridgref.h @@ -15,18 +15,22 @@ #ifndef TS_HYBRIDGREF_H #define TS_HYBRIDGREF_H - + #include #include "napi/native_api.h" #include "native_engine/native_engine.h" - +#include "sts_runtime.h" + namespace OHOS { namespace AbilityRuntime { using hybridgref = void*; - -bool RegisterNativeSaveRef(napi_env env); -bool RegisterETSGetter(ani_env* env); - + +class NativeGrefTsToEts { +public: + static bool RegisterNativeSaveRef(napi_env env); + static bool RegisterETSGetter(ani_env* env); +}; + } // namespace AbilityRuntime } // namespace OHOS #endif // TS_HYBRIDGREF_H \ No newline at end of file -- Gitee From 89a58945541b2abac9d919d7983365587b202ed4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=98=8A=E5=B3=A5?= Date: Sat, 14 Jun 2025 08:49:14 +0000 Subject: [PATCH 06/11] update frameworks/ets/ani/event_hub/src/ets_hybridgref.cpp. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 张昊峥 --- .../ets/ani/event_hub/src/ets_hybridgref.cpp | 92 ++++++++----------- 1 file changed, 39 insertions(+), 53 deletions(-) diff --git a/frameworks/ets/ani/event_hub/src/ets_hybridgref.cpp b/frameworks/ets/ani/event_hub/src/ets_hybridgref.cpp index aaaec13bc94..caa8f4e93f1 100644 --- a/frameworks/ets/ani/event_hub/src/ets_hybridgref.cpp +++ b/frameworks/ets/ani/event_hub/src/ets_hybridgref.cpp @@ -13,17 +13,18 @@ * limitations under the License. */ -#include "ets_event_hub.h" - +#include "ets_hybridgref.h" + #include "hilog_tag_wrapper.h" #include "interop_js/hybridgref_ani.h" #include "interop_js/hybridgref_napi.h" #include - + namespace OHOS { namespace AbilityRuntime { - -static hybridgref g_ref = nullptr; + +static __hybridgref* g_ref = nullptr; + static napi_value NativeGetRef(napi_env env, [[maybe_unused]] napi_callback_info info) { napi_value result {}; @@ -32,60 +33,45 @@ static napi_value NativeGetRef(napi_env env, [[maybe_unused]] napi_callback_info } return result; } - + static void NativeSaveHybridGref(ani_env *env, ani_object ref) { - ASSERT_TRUE(hybridgref_create_from_ani(env, static_cast(ref), &g_ref)); + if (!hybridgref_create_from_ani(env, static_cast(ref), &g_ref)) { + return; + } } - -class HybridGrefPrimitiveEtsToTs { -public: - static bool GetAniEnv(ani_env **env) - { - ani_vm *aniVm; - ani_size res; - - auto status = ANI_GetCreatedVMs(&aniVm, 1U, &res); - if (status != ANI_OK || res == 0) { - return false; - } - - status = aniVm->GetEnv(ANI_VERSION_1, env); - return status == ANI_OK && *env != nullptr; + +bool HybridGrefPrimitiveEtsToTs::RegisterNativeGetRef(napi_env env) +{ + napi_value global; + if (napi_get_global(env, &global) != napi_ok) { + return false; } - - static bool RegisterNativeGetRef(napi_env env) - { - napi_value global; - if (napi_get_global(env, &global) != napi_ok) { - return false; - } - napi_value fn; - if (napi_create_function(env, "nativeGetRef", NAPI_AUTO_LENGTH, NativeGetRef, nullptr, &fn) != napi_ok) { - return false; - } - - if (napi_set_named_property(env, global, "nativeGetRef", fn) != napi_ok) { - return false; - } - - return true; + napi_value fn; + if (napi_create_function(env, "nativeGetRef", NAPI_AUTO_LENGTH, NativeGetRef, nullptr, &fn) != napi_ok) { + return false; } - - static bool RegisterNativeSaveRef(ani_env *env) - { - ani_module etsMod {}; - auto status = env->FindModule("Lets_functions;", &etsMod); - if (status != ANI_OK) { - return false; - } - std::array methods = { - ani_native_function {"saveHybridGref", nullptr, reinterpret_cast(NativeSaveHybridGref)}, - }; - status = env->Module_BindNativeFunctions(etsMod, methods.data(), methods.size()); - return status == ANI_OK; + + if (napi_set_named_property(env, global, "nativeGetRef", fn) != napi_ok) { + return false; } + + return true; } - + +bool HybridGrefPrimitiveEtsToTs::RegisterNativeSaveRef(ani_env *env) +{ + ani_module etsMod {}; + auto status = env->FindModule("Lets_functions;", &etsMod); + if (status != ANI_OK) { + return false; + } + std::array methods = { + ani_native_function {"saveHybridGref", nullptr, reinterpret_cast(NativeSaveHybridGref)}, + }; + status = env->Module_BindNativeFunctions(etsMod, methods.data(), methods.size()); + return status == ANI_OK; +} + } // namespace AbilityRuntime } // namespace OHOS \ No newline at end of file -- Gitee From 9b4cf0b0ed9842091b8252ad0fa0b3664506323e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=98=8A=E5=B3=A5?= Date: Sat, 14 Jun 2025 08:49:42 +0000 Subject: [PATCH 07/11] update frameworks/ets/ani/event_hub/src/event_hub.cpp. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 张昊峥 --- .../ets/ani/event_hub/src/event_hub.cpp | 85 ++++++++++--------- 1 file changed, 45 insertions(+), 40 deletions(-) diff --git a/frameworks/ets/ani/event_hub/src/event_hub.cpp b/frameworks/ets/ani/event_hub/src/event_hub.cpp index 40fd4753448..d3776c2669b 100644 --- a/frameworks/ets/ani/event_hub/src/event_hub.cpp +++ b/frameworks/ets/ani/event_hub/src/event_hub.cpp @@ -13,57 +13,62 @@ * limitations under the License. */ +#include "event_hub.h" + #include "ts_hybridgref.h" #include "ets_hybridgref.h" #include #include "hilog_tag_wrapper.h" - -using namespace AbilityRuntime; - -static napi_value Init(napi_env env, napi_value exports) { - - if (!RegisterNativeSaveRef(env)) { - TAG_LOGE(AAFwkTag::APPKIT, "Failed to register NativeSaveRef functions"); +#include "js_runtime.h" +#include "js_runtime_utils.h" + +namespace OHOS { +namespace AbilityRuntime { + +void InitAni(ani_env *aniEnv) { + if (!NativeGrefTsToEts::RegisterETSGetter(aniEnv)) { + TAG_LOGI(AAFwkTag::APPKIT, "Failed to register ETS getter functions"); } - - // 注册 ETS 到 TS 的功能 - ani_env* aniEnv = nullptr; - if (NativeGrefTsToEts::GetAniEnv(&aniEnv)) { - if (!RegisterETSGetter(aniEnv)) { - TAG_LOGI(AAFwkTag::APPKIT\, ("Failed to register ETS getter functions"); - } - } else { - TAG_LOGE(AAFwkTag::APPKIT, "Failed to get ANI environment"); - } - - // 注册 ETS 侧功能 if (aniEnv) { if (!HybridGrefPrimitiveEtsToTs::RegisterNativeSaveRef(aniEnv)) { TAG_LOGE(AAFwkTag::APPKIT, "Failed to register ETS save functions"); } } - - // 注册 JS 侧功能 +} + +napi_value InitEventHubNapi(napi_env env, napi_value exportObj) +{ + if (!NativeGrefTsToEts::RegisterNativeSaveRef(env)) { + TAG_LOGE(AAFwkTag::APPKIT, "Failed to register NativeSaveRef functions"); + } if (!HybridGrefPrimitiveEtsToTs::RegisterNativeGetRef(env)) { TAG_LOGE(AAFwkTag::APPKIT, "Failed to register JS getter functions"); } - - return exports; + + return CreateJsUndefined(env); } - -// 模块注册 -EXTERN_C_START -static napi_module eventhub_module = { - .nm_version = 1, - .nm_flags = 0, - .nm_filename = nullptr, - .nm_register_func = Init, - .nm_modname = "eventhub", - .nm_priv = nullptr, - .reserved = {0}, -}; -EXTERN_C_END - -extern "C" __attribute__((constructor)) void RegisterModule() { - napi_module_register(&eventhub_module); -} \ No newline at end of file + +extern "C" { +ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) +{ + TAG_LOGD(AAFwkTag::APPKIT, "in EventHub ETS.ANI_Constructor"); + if (vm == nullptr || result == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null vm or result"); + return ANI_INVALID_ARGS; + } + ani_env *env = nullptr; + ani_status status = ANI_ERROR; + status = vm->GetEnv(ANI_VERSION_1, &env); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::APPKIT, "GetEnv failed, status: %{public}d", status); + return ANI_NOT_FOUND; + } + InitAni(env); + *result = ANI_VERSION_1; + TAG_LOGD(AAFwkTag::APPKIT, "EventHub.ANI_Constructor finished"); + return ANI_OK; +} +} + +} // namespace AbilityRuntime +} // namespace OHOS \ No newline at end of file -- Gitee From 4a0a61fbcd25ab905e169abf3fb2137a617a2962 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=98=8A=E5=B3=A5?= Date: Sat, 14 Jun 2025 08:50:16 +0000 Subject: [PATCH 08/11] update frameworks/ets/ani/event_hub/src/ts_hybridgref.cpp. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 张昊峥 --- .../ets/ani/event_hub/src/ts_hybridgref.cpp | 167 +++++++----------- 1 file changed, 68 insertions(+), 99 deletions(-) diff --git a/frameworks/ets/ani/event_hub/src/ts_hybridgref.cpp b/frameworks/ets/ani/event_hub/src/ts_hybridgref.cpp index f048373c1ec..fc34f01b2ba 100644 --- a/frameworks/ets/ani/event_hub/src/ts_hybridgref.cpp +++ b/frameworks/ets/ani/event_hub/src/ts_hybridgref.cpp @@ -13,189 +13,158 @@ * limitations under the License. */ -#include "ets_event_hub.h" - +#include "ts_hybridgref.h" + #include "hilog_tag_wrapper.h" #include "interop_js/hybridgref_ani.h" #include "interop_js/hybridgref_napi.h" #include - + namespace OHOS { namespace AbilityRuntime { - -static hybridgref g_jsToEtsEventHubOnRef = nullptr; -static hybridgref g_jsToEtsEventHubOffRef = nullptr; -static hybridgref g_jsToEtsEventHubEmitRef = nullptr; - + +static __hybridgref* g_jsToEtsEventHubOnRef = nullptr; +static __hybridgref* g_jsToEtsEventHubOffRef = nullptr; +static __hybridgref* g_jsToEtsEventHubEmitRef = nullptr; + static napi_value NativeSaveEventHubOnRef(napi_env env, napi_callback_info info) { size_t argc = 1; napi_value argv[1]; // NOLINT(modernize-avoid-c-arrays) napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); - + if (argc < 1) { napi_value undefined; napi_get_undefined(env, &undefined); return undefined; } - + if (g_jsToEtsEventHubOnRef != nullptr) { hybridgref_delete_from_napi(env, g_jsToEtsEventHubOnRef); g_jsToEtsEventHubOnRef = nullptr; } - + bool ok = hybridgref_create_from_napi(env, argv[0], &g_jsToEtsEventHubOnRef); napi_value result; napi_get_boolean(env, ok, &result); return result; } - + static napi_value NativeSaveEventHubOffRef(napi_env env, napi_callback_info info) { size_t argc = 1; napi_value argv[1]; // NOLINT(modernize-avoid-c-arrays) napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); - + if (argc < 1) { napi_value undefined; napi_get_undefined(env, &undefined); return undefined; } - + if (g_jsToEtsEventHubOffRef != nullptr) { hybridgref_delete_from_napi(env, g_jsToEtsEventHubOffRef); g_jsToEtsEventHubOffRef = nullptr; } - + bool ok = hybridgref_create_from_napi(env, argv[0], &g_jsToEtsEventHubOffRef); napi_value result; napi_get_boolean(env, ok, &result); return result; } - + static napi_value NativeSaveEventHubEmitRef(napi_env env, napi_callback_info info) { size_t argc = 1; napi_value argv[1]; // NOLINT(modernize-avoid-c-arrays) napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); - + if (argc < 1) { napi_value undefined; napi_get_undefined(env, &undefined); return undefined; } - + if (g_jsToEtsEventHubEmitRef != nullptr) { hybridgref_delete_from_napi(env, g_jsToEtsEventHubEmitRef); g_jsToEtsEventHubEmitRef = nullptr; } - + bool ok = hybridgref_create_from_napi(env, argv[0], &g_jsToEtsEventHubEmitRef); napi_value result; napi_get_boolean(env, ok, &result); return result; } - + static ani_object NativeGetEventHubOnRef(ani_env *env) { ani_object result {}; hybridgref_get_esvalue(env, g_jsToEtsEventHubOnRef, &result); return result; } - + static ani_object NativeGetEventHubOffRef(ani_env *env) { ani_object result {}; hybridgref_get_esvalue(env, g_jsToEtsEventHubOffRef, &result); return result; } - + static ani_object NativeGetEventHubEmitRef(ani_env *env) { ani_object result {}; hybridgref_get_esvalue(env, g_jsToEtsEventHubEmitRef, &result); return result; } - -class NativeGrefTsToEts { -public: - static bool GetAniEnv(ani_env **env) - { - ani_vm *aniVm; - ani_size res; - - auto status = ANI_GetCreatedVMs(&aniVm, 1U, &res); - if (status != ANI_OK || res == 0) { - return false; - } - - status = aniVm->GetEnv(ANI_VERSION_1, env); - return status == ANI_OK && *env != nullptr; + +bool NativeGrefTsToEts::RegisterNativeSaveRef(napi_env env) +{ + napi_value global; + if (napi_get_global(env, &global) != napi_ok) { + return false; } - - static bool RegisterNativeSaveRef(napi_env env) - { - napi_value global; - if (napi_get_global(env, &global) != napi_ok) { - return false; - } - - napi_value nativeSaveEventHubOnFn; - if (napi_create_function(env, "nativeSaveEventHubOnRef", NAPI_AUTO_LENGTH, NativeSaveEventHubOnRef, nullptr, &nativeSaveEventHubOnFn) != napi_ok) { - return false; - } - if (napi_set_named_property(env, global, "nativeSaveEventHubOnRef", nativeSaveEventHubOnFn) != napi_ok) { - return false; - } - - napi_value nativeSaveEventHubOffFn; - if (napi_create_function(env, "nativeSaveEventHubOffRef", NAPI_AUTO_LENGTH, NativeSaveEventHubOffRef, nullptr, &nativeSaveEventHubOffFn) != napi_ok) { - return false; - } - if (napi_set_named_property(env, global, "nativeSaveEventHubOffRef", nativeSaveEventHubOffFn) != napi_ok) { - return false; - } - - napi_value nativeSaveEventHubEmitFn; - if (napi_create_function(env, "nativeSaveEventHubOffRef", NAPI_AUTO_LENGTH, NativeSaveEventHubOffRef, nullptr, &nativeSaveEventHubEmitFn) != napi_ok) { - return false; - } - if (napi_set_named_property(env, global, "nativeSaveEventHubOffRef", nativeSaveEventHubEmitFn) != napi_ok) { - return false; - } - - napi_value nativeReleaseRefsFn; - if (napi_create_function(env, "nativeReleaseEventHubRefs", NAPI_AUTO_LENGTH, - [](napi_env env, napi_callback_info info) -> napi_value { - ani_env *aniEnv = nullptr; - if (GetAniEnv(&aniEnv)) { - NativeReleaseEventHubRefs(aniEnv); - } - return nullptr; - }, nullptr, &nativeReleaseRefsFn) != napi_ok) { - return false; - } - if (napi_set_named_property(env, global, "nativeReleaseEventHubRefs", nativeReleaseRefsFn) != napi_ok) { - return false; - } - - return true; + + napi_value nativeSaveEventHubOnFn; + if (napi_create_function(env, "nativeSaveEventHubOnRef", NAPI_AUTO_LENGTH, NativeSaveEventHubOnRef, nullptr, &nativeSaveEventHubOnFn) != napi_ok) { + return false; } - - static bool RegisterETSGetter(ani_env *env) - { - ani_module mod {}; - if (env->FindModule("Lets_functions;", &mod) != ANI_OK) { - return false; - } - - std::array methods = { - ani_native_function {"nativeGetEventHubOnRef", nullptr, reinterpret_cast(NativeGetEventHubOnRef)}, - ani_native_function {"nativeGetEventHubOffRef", nullptr, reinterpret_cast(NativeGetEventHubOffRef)}, - ani_native_function {"nativeGetEventHubEmitRef", nullptr, reinterpret_cast(NativeGetEventHubEmitRef)}, - }; - return env->Module_BindNativeFunctions(mod, methods.data(), methods.size()) == ANI_OK; + if (napi_set_named_property(env, global, "nativeSaveEventHubOnRef", nativeSaveEventHubOnFn) != napi_ok) { + return false; + } + + napi_value nativeSaveEventHubOffFn; + if (napi_create_function(env, "nativeSaveEventHubOffRef", NAPI_AUTO_LENGTH, NativeSaveEventHubOffRef, nullptr, &nativeSaveEventHubOffFn) != napi_ok) { + return false; + } + if (napi_set_named_property(env, global, "nativeSaveEventHubOffRef", nativeSaveEventHubOffFn) != napi_ok) { + return false; + } + + napi_value nativeSaveEventHubEmitFn; + if (napi_create_function(env, "nativeSaveEventHubEmitRef", NAPI_AUTO_LENGTH, NativeSaveEventHubEmitRef, nullptr, &nativeSaveEventHubEmitFn) != napi_ok) { + return false; + } + if (napi_set_named_property(env, global, "nativeSaveEventHubEmitRef", nativeSaveEventHubEmitFn) != napi_ok) { + return false; + } + + return true; +} + +bool NativeGrefTsToEts::RegisterETSGetter(ani_env *env) +{ + ani_module mod {}; + if (env->FindModule("Lets_functions;", &mod) != ANI_OK) { + return false; } + + std::array methods = { + ani_native_function {"nativeGetEventHubOnRef", nullptr, reinterpret_cast(NativeGetEventHubOnRef)}, + ani_native_function {"nativeGetEventHubOffRef", nullptr, reinterpret_cast(NativeGetEventHubOffRef)}, + ani_native_function {"nativeGetEventHubEmitRef", nullptr, reinterpret_cast(NativeGetEventHubEmitRef)}, + }; + return env->Module_BindNativeFunctions(mod, methods.data(), methods.size()) == ANI_OK; } + } // namespace AbilityRuntime } // namespace OHOS \ No newline at end of file -- Gitee From e0553ed4bd9d924d17565b165153dcf1c8cdae84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=98=8A=E5=B3=A5?= Date: Sat, 14 Jun 2025 08:54:22 +0000 Subject: [PATCH 09/11] update frameworks/ets/ets/application/EventHub.ets. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 张昊峥 --- frameworks/ets/ets/application/EventHub.ets | 77 ++++++++++++++------- 1 file changed, 51 insertions(+), 26 deletions(-) diff --git a/frameworks/ets/ets/application/EventHub.ets b/frameworks/ets/ets/application/EventHub.ets index 4ccb62d5ecf..feede55bfed 100644 --- a/frameworks/ets/ets/application/EventHub.ets +++ b/frameworks/ets/ets/application/EventHub.ets @@ -13,29 +13,53 @@ * limitations under the License. */ -// eventHub.ets -native function nativeGetEventHubOnRef(): ESObject; -native function nativeGetEventHubOffRef(): ESObject; -native function nativeGetEventHubEmitRef(): ESObject; +type refType = Object | ESObject; +type RegisterEmitFunction = (event: string, ...args: FixedArray) => void; + +interface EventHubRegistration { + registerOn: (event: string, callback: Function) => void; + registerOff: (event: string, callback?: Function) => void; + registerEmit: RegisterEmitFunction; +} type refType = Object | ESObject; -native function saveEventHubOnHybridGref(ref: refType): void; -native function saveEventHubOffHybridGref(ref: refType): void; -native function saveEventHubEmitHybridGref(ref: refType): void; +type RegisterEmitFunction = (event: string, ...args: FixedArray) => void; + +interface EventHubRegistration { + registerOn: (event: string, callback: Function) => void; + registerOff: (event: string, callback?: Function) => void; + registerEmit: RegisterEmitFunction; +} export default class EventHub { - private eventMap: Map = new Map(); + + native nativeGetEventHubOnRef(): ESObject; + native nativeGetEventHubOffRef(): ESObject; + native nativeGetEventHubEmitRef(): ESObject; + + native saveEventHubOnHybridGref(ref: refType): void; + native saveEventHubOffHybridGref(ref: refType): void; + native saveEventHubEmitHybridGref(ref: refType): void; + + private eventMap: Map = new Map(); constructor() { - saveEventHubOnHybridGref({ - registerOn: (event: string, callback: Function) => this.registerOnCallback(event, callback, true) - }); - saveEventHubOffHybridGref({ - registerOff: (event: string, callback?: Function) => this.registerOffCallback(event, callback, true) - }) - saveEventHubEmitHybridGref({ - registerEmit: (event: string, ...args: FixedArray) => this.registerEmitCallback(event, ...args) - }) + this.saveEventHubOnHybridGref({ + registerOn: (event: string, callback: Function): void => { + this.on(event, callback, true); + } + } as EventHubRegistration); + this.saveEventHubOffHybridGref({ + registerOff: (event: string, callback?: Function): void => { + this.off(event, callback, true); + } + } as EventHubRegistration); + + const emitHandler: RegisterEmitFunction = (event: string, ...args: FixedArray): void => { + this.emit(event, ...args); + } + + this.saveEventHubEmitHybridGref({ registerEmit: emitHandler } as EventHubRegistration); } private registerOnCallback(event: string, callback: Function): void { @@ -49,13 +73,13 @@ export default class EventHub { } } - on(event: string, callback: Function, fromNative = false): void { + on(event: string, callback: Function, fromNative: boolean = false): void { this.registerOnCallback(event, callback); if (!fromNative) { - const nativeObj = this.nativeGetEventHubOnRef(); + let nativeObj = this.nativeGetEventHubOnRef(); if (nativeObj) { - obj.invokeMethod(event, callback); + nativeObj.invokeMethod(event, callback); } } } @@ -80,22 +104,22 @@ export default class EventHub { } } - off(event: string, callback?: Function, fromNative = false): void { + off(event: string, callback?: Function, fromNative: boolean = false): void { this.registerOffCallback(event, callback); if (!fromNative) { const nativeObj = this.nativeGetEventHubOffRef(); if (nativeObj) { if (callback) { - nativeObj.callFunction(event, callback); + nativeObj.invokeMethod(event, callback); } else { - nativeObj.callFunction(event); + nativeObj.invokeMethod(event); } } } } - private registerEmitCallback(event: string, args: FixedArray[]): void { + private registerEmitCallback(event: string, ...args: FixedArray): void { if (!this.eventMap.has(event)) { return; } @@ -111,9 +135,10 @@ export default class EventHub { } emit(event: string, ...args: FixedArray): void { - this.registerEmitCallback(event, args); + this.registerEmitCallback(event, ...args); + const nativeObj = this.nativeGetEventHubEmitRef(); if (nativeObj) { - nativeObj.callFunction(event, ...args); + nativeObj.invokeMethod(event, ...args); } } } \ No newline at end of file -- Gitee From 581a908a710c95f551fbfa310800bfe149d224fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=98=8A=E5=B3=A5?= Date: Sat, 14 Jun 2025 08:55:59 +0000 Subject: [PATCH 10/11] update frameworks/js/napi/app/context/context.js. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 张昊峥 Change-Id: Ie9a0ed23fd90b9452d7fbb8c5132b29339c3f8a0 --- frameworks/js/napi/app/context/context.js | 4 - frameworks/native/runtime/interop_guard.cpp | 98 --------------------- 2 files changed, 102 deletions(-) delete mode 100644 frameworks/native/runtime/interop_guard.cpp diff --git a/frameworks/js/napi/app/context/context.js b/frameworks/js/napi/app/context/context.js index 2c6153b75b5..951ff9f9dad 100644 --- a/frameworks/js/napi/app/context/context.js +++ b/frameworks/js/napi/app/context/context.js @@ -141,10 +141,6 @@ class EventHub { dispose() { this.eventMap = {}; - - if (globalThis.nativeReleaseEventHubRefs) { - globalThis.nativeReleaseEventHubRefs(); - } } } diff --git a/frameworks/native/runtime/interop_guard.cpp b/frameworks/native/runtime/interop_guard.cpp deleted file mode 100644 index b57beaf9f9b..00000000000 --- a/frameworks/native/runtime/interop_guard.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/* - * 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 "interop_guard.h" - -#include "hilog_tag_wrapper.h" -#include "interop_js/hybridgref_ani.h" -#include "interop_js/hybridgref_napi.h" - -namespace OHOS { -namespace AbilityRuntime { -InteropGuard::InteropGuard(ani_env *env, ani_ref ref) -{ - if (env == nullptr || ref == nullptr) { - TAG_LOGE(AAFwkTag::JSRUNTIME, "invalid args"); - return; - } - ani_vm *aniVM = nullptr; - if (env->GetVM(&aniVM) != ANI_OK) { - TAG_LOGE(AAFwkTag::JSRUNTIME, "GetVM failed"); - return; - } - vm_ = aniVM; - hybridgref_create_from_ani(env, ref, &ref_); -} - -InteropGuard::InteropGuard(napi_env env, napi_value, value) -{ - if (env == nullptr || value == nullptr) { - TAG_LOGE(AAFwkTag::JSRUNTIME, "invalid args"); - return; - } - env_ = env; - hybridgref_create_from_napi(env, value, &ref_); -} - -ani_env* InteropGuard::GetAniEnv() -{ - if (vm_ == nullptr) { - TAG_LOGE(AAFwkTag::JSRUNTIME, "null vm"); - return nullptr; - } - ani_env* aniEnv = nullptr; - if (vm_->GetEnv(ANI_VERSION_1, &aniEnv) != ANI_OK) { - return nullptr; - } - return aniEnv; -} - -InteropGuard::~InteropGuard() -{ - if (ref_ == nullptr) { - return; - } - if (vm_ != nullptr) { - ani_env *env = GetAniEnv(); - if (env == nullptr) { - TAG_LOGE(AAFwkTag::JSRUNTIME, "null env"); - return; - } - hybridgref_delete_from_ani(env, ref_); - return; - } - - if (env_ != nullptr) { - hybridgref_delete_from_napi(env_, ref_); - } -} - -ani_object InteropGuard::GetAniValue(ani_env, *env) -{ - ani_object result = nullptr; - hybridgref_get_esvalue(env, ref_, &result); - return result; -} - -napi_value InteropGuard::GetNapiValue(napi_env env) -{ - napi_value result {}; - if (!hybridgref_get_napi_value(env, ref_, &result)) { - napi_get_undefined(env, &result); - } - return result; -} -} // namespace AbilityRuntime -} // namespace OHOS \ No newline at end of file -- Gitee From fc47648df7c09b9b3efba1825c470a9f87884f6d Mon Sep 17 00:00:00 2001 From: zhang_hao_zheng Date: Sat, 14 Jun 2025 17:31:10 +0800 Subject: [PATCH 11/11] =?UTF-8?q?=E7=AC=AC2=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I94cc88441f09b503f0d204f97c2396d595ae61d3 --- .../ets/ani/event_hub/include/event_hub.h | 22 ++++----- .../ets/ani/event_hub/src/ets_hybridgref.cpp | 1 - .../ets/ani/event_hub/src/event_hub.cpp | 45 ++++++++++++------- 3 files changed, 40 insertions(+), 28 deletions(-) diff --git a/frameworks/ets/ani/event_hub/include/event_hub.h b/frameworks/ets/ani/event_hub/include/event_hub.h index 18135075f7b..9760dc40a79 100644 --- a/frameworks/ets/ani/event_hub/include/event_hub.h +++ b/frameworks/ets/ani/event_hub/include/event_hub.h @@ -13,20 +13,22 @@ * limitations under the License. */ -#ifndef ETS_HYBRIDGREF_H -#define ETS_HYBRIDGREF_H - +#ifndef EVENT_HUB_H +#define EVENT_HUB_H + +#include "ets_hybridgref.h" #include "ts_hybridgref.h" -#include "sts_runtime.h" - + namespace OHOS { namespace AbilityRuntime { - -class HybridGrefPrimitiveEtsToTs { + +class EventHub { public: - static bool RegisterNativeGetRef(napi_env env); - static bool RegisterNativeSaveRef(ani_env* env); + static void InitAni(ani_env* env); + static napi_value InitEventHubNapi(napi_env env, napi_value exportObj); }; + } // namespace AbilityRuntime } // namespace OHOS -#endif // ETS_HYBRIDGREF_H \ No newline at end of file + +#endif // EVENT_HUB_H \ No newline at end of file diff --git a/frameworks/ets/ani/event_hub/src/ets_hybridgref.cpp b/frameworks/ets/ani/event_hub/src/ets_hybridgref.cpp index caa8f4e93f1..1b4adabaa79 100644 --- a/frameworks/ets/ani/event_hub/src/ets_hybridgref.cpp +++ b/frameworks/ets/ani/event_hub/src/ets_hybridgref.cpp @@ -24,7 +24,6 @@ namespace OHOS { namespace AbilityRuntime { static __hybridgref* g_ref = nullptr; - static napi_value NativeGetRef(napi_env env, [[maybe_unused]] napi_callback_info info) { napi_value result {}; diff --git a/frameworks/ets/ani/event_hub/src/event_hub.cpp b/frameworks/ets/ani/event_hub/src/event_hub.cpp index d3776c2669b..d1b9140506c 100644 --- a/frameworks/ets/ani/event_hub/src/event_hub.cpp +++ b/frameworks/ets/ani/event_hub/src/event_hub.cpp @@ -25,27 +25,38 @@ namespace OHOS { namespace AbilityRuntime { -void InitAni(ani_env *aniEnv) { - if (!NativeGrefTsToEts::RegisterETSGetter(aniEnv)) { - TAG_LOGI(AAFwkTag::APPKIT, "Failed to register ETS getter functions"); +static std::atomic g_initialized(false); + +void EventHub::InitAni(ani_env *aniEnv) { + if (g_initialized.exchange(true)) { + return; } - if (aniEnv) { - if (!HybridGrefPrimitiveEtsToTs::RegisterNativeSaveRef(aniEnv)) { - TAG_LOGE(AAFwkTag::APPKIT, "Failed to register ETS save functions"); - } + + if (!aniEnv) { + TAG_LOGE(AAFwkTag::APPKIT, "Invalid ani_env in InitAni"); + return; } + + bool success = NativeGrefTsToEts::RegisterETSGetter(aniEnv) && + HybridGrefPrimitiveEtsToTs::RegisterNativeSaveRef(aniEnv); + + TAG_LOGI(AAFwkTag::APPKIT, "EventHub ANI initialization %s", + success ? "succeeded" : "failed"); } - -napi_value InitEventHubNapi(napi_env env, napi_value exportObj) -{ - if (!NativeGrefTsToEts::RegisterNativeSaveRef(env)) { - TAG_LOGE(AAFwkTag::APPKIT, "Failed to register NativeSaveRef functions"); - } - if (!HybridGrefPrimitiveEtsToTs::RegisterNativeGetRef(env)) { - TAG_LOGE(AAFwkTag::APPKIT, "Failed to register JS getter functions"); + +napi_value EventHub::InitEventHubNapi(napi_env env, napi_value exportObj) { + if (!env) { + TAG_LOGE(AAFwkTag::APPKIT, "Invalid napi_env in InitEventHubNapi"); + return nullptr; } - - return CreateJsUndefined(env); + + bool success = NativeGrefTsToEts::RegisterNativeSaveRef(env) && + HybridGrefPrimitiveEtsToTs::RegisterNativeGetRef(env); + + TAG_LOGI(AAFwkTag::APPKIT, "EventHub NAPI initialization %s", + success ? "succeeded" : "failed"); + + return exportObj; } extern "C" { -- Gitee