diff --git a/frameworks/simulator/ability_simulator/BUILD.gn b/frameworks/simulator/ability_simulator/BUILD.gn index c0f0a38a5053cc3755b0bcf379d192ba17fca491..b4ec15139ab09d3e2a8b8ff2efa66b31239c9768 100644 --- a/frameworks/simulator/ability_simulator/BUILD.gn +++ b/frameworks/simulator/ability_simulator/BUILD.gn @@ -20,6 +20,91 @@ config("ability_simulator_public_config") { cflags_cc = [ "-Wno-unused-variable" ] } +ohos_shared_library("simulator_context_ani") { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + cfi_vcall_icall_only = true + debug = false + } + + include_dirs = [ + "${ability_runtime_services_path}/common/include", + ] + + sources = [ + "${ability_runtime_path}/frameworks/ets/ani/native_constructor/context_native_constructor.cpp", + ] + + external_deps = [ + "hilog:libhilog", +# "ipc:ipc_single", +# "ipc:rpc_ani", + "runtime_core:ani", + ] +# deps = [ +# "${ability_runtime_path}/frameworks/ets/ani/ani_common:ani_common", +# ] + + subsystem_name = "ability" + part_name = "ability_runtime" + output_extension = "so" +} + +ohos_shared_library("simulator_context_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_napi_path}/ability_auto_startup_callback", +# "${ability_runtime_path}/interfaces/kits/native/appkit/ability_runtime/context", + "${ability_runtime_path}/interfaces/kits/native/appkit/ability_runtime/app", + "${ability_runtime_path}/frameworks/simulator/common/include", + ] + + configs = [] + + public_configs = [] + + sources = [ "./src/ets_context_module.cpp" ] + +# deps = [ +# "${ability_runtime_innerkits_path}/ani_base_context:ani_base_context", +# "${ability_runtime_innerkits_path}/error_utils:ability_runtime_error_util", +# "${ability_runtime_innerkits_path}/runtime:runtime", +# "${ability_runtime_napi_path}/inner/napi_common:napi_common", +# "${ability_runtime_native_path}/ability/native:ability_business_error", +# "${ability_runtime_native_path}/appkit:app_context", +# "${ability_runtime_native_path}/appkit:app_context_utils", +# "${ability_runtime_native_path}/appkit:appkit_native", +# "${ability_runtime_native_path}/appkit:application_context_manager", +# "${ability_runtime_path}/frameworks/ets/ani/ani_common:ani_common", +# ] + + defines = [ "LINUX_PREVIEW" ] + + external_deps = [ +# "c_utils:utils", + "hilog:libhilog", +# "hitrace:hitrace_meter", + "napi:ace_napi", + "runtime_core:ani", +# "runtime_core:ani_helpers", + ] + + innerapi_tags = [ "platformsdk" ] + subsystem_name = "ability" + part_name = "ability_runtime" +} + + ohos_shared_library("ability_simulator_inner") { if (is_mingw || is_mac) { defines = [] @@ -38,6 +123,7 @@ ohos_shared_library("ability_simulator_inner") { cflags = [ "-std=c++17" ] include_dirs = [ + "//arkcompiler/runtime_core/static_core/plugins/ets/runtime/ani", "${ability_runtime_path}/js_environment/interfaces/inner_api", "${ability_runtime_path}/interfaces/kits/native/ability/native/ability_business_error", "${ability_runtime_native_path}/runtime", @@ -45,6 +131,7 @@ ohos_shared_library("ability_simulator_inner") { "${ability_runtime_innerkits_path}/error_utils/include", "${ability_runtime_innerkits_path}/runtime/include", "${windowmanager_path}/previewer/include", + "${windowmanager_path}/previewer", "${windowmanager_path}/previewer/mock", "${windowmanager_path}/previewer/mock/transaction", "${windowmanager_path}/previewer/mock/ui", @@ -54,6 +141,13 @@ ohos_shared_library("ability_simulator_inner") { "${simulator_path}/napi_module/application", ] + if (is_linux) { + include_dirs += [ + "${windowmanager_path}/interfaces/kits/ani/window_runtime/window_stage_ani/include/", + ] + defines += [ "LINUX_PREVIEW" ] + } + sources = [ "${ability_runtime_native_path}/ability/native/ability_business_error/ability_business_error.cpp", "${ability_runtime_native_path}/runtime/js_module_searcher.cpp", @@ -92,6 +186,12 @@ ohos_shared_library("ability_simulator_inner") { "src/simulator.cpp", ] + if (is_linux) { + sources += [ + "src/dynamic_loader_linux.cpp", + ] + } + public_configs = [ ":ability_simulator_public_config", "${simulator_path}/common:ability_simulator_common_config", @@ -106,10 +206,17 @@ ohos_shared_library("ability_simulator_inner") { "ets_utils:console", "ets_utils:timer", "hilog:libhilog", + "json:nlohmann_json_static", "napi:ace_napi", "previewer:ide_extension", "resource_management:resmgr_napi_core_preview", ] + if (is_linux) { + external_deps += [ +# "eventhandler:libeventhandler", + "runtime_core:ani", + ] + } if (ability_runtime_graphics) { external_deps += [ @@ -136,4 +243,11 @@ group("ability_simulator") { if (is_mingw || is_mac) { public_deps = [ ":ability_simulator_inner" ] } + if (is_linux) { + deps = [ + ":simulator_context_ani", + ":simulator_context_ani_kit", +# "//foundation/graphic/graphic_2d/rosen/modules/platform:eventhandler", + ] + } } diff --git a/frameworks/simulator/ability_simulator/include/bundle_parser/inner_bundle_info.h b/frameworks/simulator/ability_simulator/include/bundle_parser/inner_bundle_info.h index ad504017f3b9870e57f9dc40162cbc4c9eb78b35..085c787ffba1d4fd514de118beecbbb9fc860522 100644 --- a/frameworks/simulator/ability_simulator/include/bundle_parser/inner_bundle_info.h +++ b/frameworks/simulator/ability_simulator/include/bundle_parser/inner_bundle_info.h @@ -95,6 +95,7 @@ struct InnerModuleInfo { bool compressNativeLibs = true; std::vector nativeLibraryFileNames; AOTCompileStatus aotCompileStatus = AOTCompileStatus::NOT_COMPILED; + std::string codeLanguage = Constants::CODE_LANGUAGE_1_2; }; class InnerBundleInfo { diff --git a/frameworks/simulator/ability_simulator/include/dynamic_loader.h b/frameworks/simulator/ability_simulator/include/dynamic_loader.h new file mode 100644 index 0000000000000000000000000000000000000000..1e25e0af937322ae97e916f4d72ab4158a8e74d0 --- /dev/null +++ b/frameworks/simulator/ability_simulator/include/dynamic_loader.h @@ -0,0 +1,31 @@ +/* +* Copyright (c) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef OHOS_ABILITY_RUNTIME_DYNAMIC_LOADER_H +#define OHOS_ABILITY_RUNTIME_DYNAMIC_LOADER_H + +#if defined(LINUX_PLATFORM) +#include +#endif + +extern "C" { +void* DynamicLoadLibrary(const char* dlPath, unsigned int mode); +void* DynamicFindSymbol(void* so, const char* symbol); +const char* DynamicGetError(); +void DynamicFreeLibrary(void* so); +void DynamicInitNamespace(void* parent, const char* entries, const char* name); +}; + +#endif //OHOS_ABILITY_RUNTIME_DYNAMIC_LOADER_H diff --git a/frameworks/simulator/ability_simulator/include/ets_context_module.h b/frameworks/simulator/ability_simulator/include/ets_context_module.h new file mode 100644 index 0000000000000000000000000000000000000000..41ffb434eea5d6765e886ac89a658ed76d18a30c --- /dev/null +++ b/frameworks/simulator/ability_simulator/include/ets_context_module.h @@ -0,0 +1,51 @@ +/* +* 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_ETS_CONTEXT_MODULE_H +#define OHOS_ABILITY_RUNTIME_ETS_CONTEXT_MODULE_H + +#include + +#include "ani.h" +#include "context.h" +#include "native_engine/native_engine.h" + +namespace OHOS { +namespace AbilityRuntime { +class EtsContextModule { +public: + EtsContextModule() = default; + ~EtsContextModule() = default; + + EtsContextModule(const EtsContextModule&) = delete; + EtsContextModule(EtsContextModule&&) = delete; + EtsContextModule& operator=(const EtsContextModule&) = delete; + EtsContextModule& operator=(EtsContextModule&&) = delete; + + static ani_object NativeTransferStatic(ani_env *env, ani_object aniObj, ani_object input, ani_object type); + static ani_object NativeTransferDynamic(ani_env *env, ani_class aniCls, ani_object input); + static napi_value GetOrCreateDynamicObject(napi_env napiEnv, std::shared_ptr context); + +private: + static bool LoadTargetModule(ani_env *aniEnv, const std::string &className); + static std::unique_ptr CreateNativeReference(napi_env napiEnv, std::shared_ptr context); + static ani_object CreateStaticObject(ani_env *aniEnv, ani_object type, std::shared_ptr context); + static ani_object CreateDynamicObject(ani_env *aniEnv, ani_class aniCls, std::shared_ptr context); +}; + +void EtsContextModuleInit(ani_env *aniEnv); +} // namespace AbilityRuntime +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_ETS_CONTEXT_MODULE_H diff --git a/frameworks/simulator/ability_simulator/include/simulator.h b/frameworks/simulator/ability_simulator/include/simulator.h index ffd81e5bf3250051003e67b9920239750a640695..11e7e0827459a6d86fb1eae4390b1aa7c2700e2c 100644 --- a/frameworks/simulator/ability_simulator/include/simulator.h +++ b/frameworks/simulator/ability_simulator/include/simulator.h @@ -21,6 +21,10 @@ #include #include +#if defined(LINUX_PLATFORM) +#include "ani.h" +#include "window_scene.h" +#endif #include "configuration.h" #include "options.h" @@ -53,6 +57,12 @@ public: virtual void UpdateConfiguration(const AppExecFwk::Configuration &config) = 0; virtual void SetMockList(const std::map &mockList) = 0; virtual void SetHostResolveBufferTracker(ResolveBufferTrackerCallback cb) = 0; + virtual std::string GetCodeLanguage() = 0; +private: +#if defined(LINUX_PLATFORM) + virtual ani_object GetAniObj() { return nullptr; } + virtual std::shared_ptr GetWindowScene() { return nullptr; } +#endif // LINUX_PLATFORM }; } // namespace AbilityRuntime } // namespace OHOS diff --git a/frameworks/simulator/ability_simulator/src/bundle_parser/inner_bundle_info.cpp b/frameworks/simulator/ability_simulator/src/bundle_parser/inner_bundle_info.cpp index b99660efebeb595aaa5257d2604c63191348c587..2837871613fd3bc56716fb493d8456374cd55341 100644 --- a/frameworks/simulator/ability_simulator/src/bundle_parser/inner_bundle_info.cpp +++ b/frameworks/simulator/ability_simulator/src/bundle_parser/inner_bundle_info.cpp @@ -646,6 +646,7 @@ std::optional InnerBundleInfo::FindHapModuleInfo(const std::strin hapInfo.compressNativeLibs = it->second.compressNativeLibs; hapInfo.nativeLibraryFileNames = it->second.nativeLibraryFileNames; hapInfo.aotCompileStatus = it->second.aotCompileStatus; + hapInfo.codeLanguage = it->second.codeLanguage; return hapInfo; } diff --git a/frameworks/simulator/ability_simulator/src/bundle_parser/module_profile.cpp b/frameworks/simulator/ability_simulator/src/bundle_parser/module_profile.cpp index 4b1134b17f9c727f7064534437746e59aedd695d..2f50afff906fd294b30b824cf6d7146a0d4a254d 100644 --- a/frameworks/simulator/ability_simulator/src/bundle_parser/module_profile.cpp +++ b/frameworks/simulator/ability_simulator/src/bundle_parser/module_profile.cpp @@ -201,6 +201,7 @@ struct Ability { bool excludeFromMissions = false; bool recoverable = false; bool unclearableMission = false; + std::string codeLanguage = Constants::CODE_LANGUAGE_1_2; }; struct Extension { @@ -280,6 +281,7 @@ struct Module { std::string buildHash; std::string isolationMode; bool compressNativeLibs = true; + std::string codeLanguage = Constants::CODE_LANGUAGE_1_2; }; struct ModuleJson { @@ -781,6 +783,7 @@ bool ToAbilityInfo( abilityInfo.minWindowWidth = ability.minWindowWidth; abilityInfo.maxWindowHeight = ability.maxWindowHeight; abilityInfo.minWindowHeight = ability.minWindowHeight; + abilityInfo.codeLanguage = ability.codeLanguage; return true; } diff --git a/frameworks/simulator/ability_simulator/src/dynamic_loader_linux.cpp b/frameworks/simulator/ability_simulator/src/dynamic_loader_linux.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f6cb270c8aa14bd160c29708ed215d99c9cb4435 --- /dev/null +++ b/frameworks/simulator/ability_simulator/src/dynamic_loader_linux.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "dynamic_loader.h" + +#if defined(LINUX_PLATFORM) +#include +#endif + +extern "C" { +void* DynamicLoadLibrary(const char* dlPath, unsigned int mode) +{ + return dlopen(dlPath, mode); +} + +void* DynamicFindSymbol(void* so, const char* symbol) +{ + return dlsym(so, symbol); +} + +void DynamicFreeLibrary(void* so) +{ + (void)dlclose(so); +} + +const char* DynamicGetError() +{ + return dlerror(); +} +} diff --git a/frameworks/simulator/ability_simulator/src/ets_context_module.cpp b/frameworks/simulator/ability_simulator/src/ets_context_module.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3478bad2d2c417b783a982d0b356edf886bc5615 --- /dev/null +++ b/frameworks/simulator/ability_simulator/src/ets_context_module.cpp @@ -0,0 +1,460 @@ +/* + * 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_context_module.h" + +#include +#include +#include + +#ifndef LINUX_PREVIEW +#include "ani_base_context.h" +#include "ani_common_util.h" +#include "application_context_manager.h" +#include "context_transfer.h" +#include "ets_ability_stage_context.h" +#include "ets_application_context_utils.h" +#include "ets_context_utils.h" +#include "ets_error_utils.h" +#include "hilog_tag_wrapper.h" +#include "hitrace_meter.h" +#include "interop_js/arkts_esvalue.h" +#include "interop_js/arkts_interop_js_api.h" +#include "interop_js/hybridgref_ani.h" +#include "interop_js/hybridgref_napi.h" +#include "js_ability_stage_context.h" +#include "js_application_context_utils.h" +#include "js_context_utils.h" +#include "js_runtime_utils.h" +#include "native_engine/native_engine.h" +#endif // LINUX_PREVIEW + +namespace OHOS { +namespace AbilityRuntime { +namespace { +#ifndef LINUX_PREVIEW +constexpr const char *ETS_CONTEXT_CLASS_NAME = "Lapplication/Context/Context;"; + +std::string GetClassNameByContextType(const std::string &contextType) +{ + std::string className; + static const std::unordered_map mapping = { + {"Context", "Lapplication/Context/Context;"}, + {"ApplicationContext", "Lapplication/ApplicationContext/ApplicationContext;"}, + {"AbilityStageContext", "Lapplication/AbilityStageContext/AbilityStageContext;"}, + {"UIAbilityContext", "Lapplication/UIAbilityContext/UIAbilityContext;"} + }; + auto it = mapping.find(contextType); + if (it != mapping.end()) { + className = it->second; + } + return className; +} +#endif // LINUX_PREVIEW +} // namespace + +ani_object EtsContextModule::NativeTransferStatic(ani_env *aniEnv, ani_object self, ani_object input, ani_object type) +{ +#ifndef LINUX_PREVIEW + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + TAG_LOGD(AAFwkTag::ETSRUNTIME, "transfer static Context"); + if (aniEnv == nullptr) { + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "null aniEnv"); + return nullptr; + } + void *unwrapResult = nullptr; + bool success = arkts_esvalue_unwrap(aniEnv, input, &unwrapResult); + if (!success) { + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "failed to unwrap"); + EtsErrorUtil::ThrowEtsTransferClassError(aniEnv); + return nullptr; + } + if (unwrapResult == nullptr) { + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "null unwrapResult"); + EtsErrorUtil::ThrowEtsTransferClassError(aniEnv); + return nullptr; + } + + auto context = reinterpret_cast *>(unwrapResult)->lock(); + if (context == nullptr) { + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "null Context"); + EtsErrorUtil::ThrowEtsTransferClassError(aniEnv); + return nullptr; + } + + auto &bindingObj = context->GetBindingObject(); + if (bindingObj == nullptr) { + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "null bindingObj"); + EtsErrorUtil::ThrowEtsTransferClassError(aniEnv); + return nullptr; + } + + auto staticContext = bindingObj->Get(); + if (staticContext != nullptr) { + TAG_LOGI(AAFwkTag::ETSRUNTIME, "there exist a staticContext"); + return reinterpret_cast(*staticContext); + } + + auto contextObj = CreateStaticObject(aniEnv, type, context); + if (contextObj == nullptr) { + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "contextObj invalid"); + EtsErrorUtil::ThrowEtsTransferClassError(aniEnv); + return nullptr; + } + + return contextObj; +#else + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "EtsContextModule::NativeTransferStatic not implemented"); + return nullptr; +#endif // LINUX_PREVIEW +} + +ani_object EtsContextModule::CreateStaticObject(ani_env *aniEnv, ani_object type, std::shared_ptr context) +{ +#ifndef LINUX_PREVIEW + std::string contextType; + if (!AppExecFwk::GetStdString(aniEnv, reinterpret_cast(type), contextType)) { + //TAG_LOGE(AAFwkTag::JSNAPI, "GetStdString failed"); + return nullptr; + } + TAG_LOGD(AAFwkTag::ETSRUNTIME, "contextType %{public}s", contextType.c_str()); + + if (!ContextTransfer::GetInstance().IsStaticCreatorExist(contextType)) { + std::string className = GetClassNameByContextType(contextType); + if (!LoadTargetModule(aniEnv, className)) { + return nullptr; + } + } + + auto contextObj = ContextTransfer::GetInstance().GetStaticObject(contextType, aniEnv, context); + if (contextObj == nullptr) { + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "contextObj invalid"); + return nullptr; + } + + return contextObj; +#else + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "EtsContextModule::CreateStaticObject not implemented"); + return nullptr; +#endif // LINUX_PREVIEW +} + +bool EtsContextModule::LoadTargetModule(ani_env *aniEnv, const std::string &className) +{ +#ifndef LINUX_PREVIEW + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + ani_class contextCls = nullptr; + auto status = aniEnv->FindClass(className.c_str(), &contextCls); + if (status != ANI_OK) { + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "FindClass %{public}s failed status: %{public}d", className.c_str(), status); + return false; + } + + std::string gotContextType; + if (!AppExecFwk::GetStaticFieldString(aniEnv, contextCls, "contextType", gotContextType)) { + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "get context type failed"); + return false; + } + + TAG_LOGD(AAFwkTag::ETSRUNTIME, "gotContext %{public}s", gotContextType.c_str()); + return true; +#else + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "EtsContextModule::LoadTargetModule not implemented"); + return false; +#endif // LINUX_PREVIEW +} + +std::unique_ptr EtsContextModule::CreateNativeReference(napi_env napiEnv, + std::shared_ptr context) +{ +#ifndef LINUX_PREVIEW + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + if (napiEnv == nullptr || context == nullptr) { + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "null param"); + return nullptr; + } + + auto value = CreateJsBaseContext(napiEnv, context); + auto systemModule = JsRuntime::LoadSystemModuleByEngine(napiEnv, "application.Context", &value, 1); + if (systemModule == nullptr) { + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "null system module"); + return nullptr; + } + + napi_value object = systemModule->GetNapiValue(); + if (!CheckTypeForNapiValue(napiEnv, object, napi_object)) { + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "check type failed"); + return nullptr; + } + + auto workContext = new (std::nothrow) std::weak_ptr(context); + if (workContext == nullptr) { + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "null workContext"); + return nullptr; + } + auto status = napi_coerce_to_native_binding_object(napiEnv, object, DetachCallbackFunc, AttachBaseContext, + workContext, nullptr); + if (status != napi_ok) { + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "coerce context failed: %{public}d", status); + delete workContext; + return nullptr; + } + + status = napi_wrap(napiEnv, object, workContext, + [](napi_env, void *data, void *) { + TAG_LOGD(AAFwkTag::ETSRUNTIME, "finalizer for weak_ptr context"); + delete static_cast *>(data); + }, nullptr, nullptr); + if (status != napi_ok) { + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "wrap failed: %{public}d", status); + delete workContext; + return nullptr; + } + + return systemModule; +#else + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "EtsContextModule::CreateNativeReference not implemented"); + return nullptr; +#endif // LINUX_PREVIEW +} + +napi_value EtsContextModule::GetOrCreateDynamicObject(napi_env napiEnv, std::shared_ptr context) +{ +#ifndef LINUX_PREVIEW + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + if (napiEnv == nullptr || context == nullptr) { + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "null param"); + return nullptr; + } + + // if sub-thread, create a new context and return + if (getpid() != syscall(SYS_gettid)) { + auto subThreadObj = static_cast(context->GetSubThreadObject(static_cast(napiEnv))); + if (subThreadObj != nullptr) { + return subThreadObj->Get(); + } + auto subThreadRef = CreateNativeReference(napiEnv, context); + if (subThreadRef == nullptr) { + return nullptr; + } + auto newObject = subThreadRef->Get(); + context->BindSubThreadObject(static_cast(napiEnv), static_cast(subThreadRef.release())); + return newObject; + } + + // if main-thread, get bindingObj firstly + auto &bindingObj = context->GetBindingObject(); + if (bindingObj == nullptr) { + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "null bindingObj"); + return nullptr; + } + + // if main-thread bindingObj exist, return it directly + auto dynamicContext = bindingObj->Get(); + if (dynamicContext != nullptr) { + TAG_LOGI(AAFwkTag::UIABILITY, "there exist a dynamicContext"); + return dynamicContext->Get(); + } + + // if main-thread bindingObj didn't exist, create and bind + std::unique_ptr nativeRef = CreateNativeReference(napiEnv, context); + if (nativeRef == nullptr) { + return nullptr; + } + + auto object = nativeRef->Get(); + context->Bind(nativeRef.release()); + return object; +#else + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "EtsContextModule::GetOrCreateDynamicObject not implemented"); + return nullptr; +#endif // LINUX_PREVIEW +} + +ani_object EtsContextModule::NativeTransferDynamic(ani_env *aniEnv, ani_class aniCls, ani_object input) +{ +#ifndef LINUX_PREVIEW + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + TAG_LOGD(AAFwkTag::ETSRUNTIME, "transfer dynamic Context"); + if (aniEnv == nullptr) { + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "null aniEnv"); + return nullptr; + } + + auto context = AbilityRuntime::GetStageModeContext(aniEnv, input); + if (context == nullptr) { + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "null context"); + EtsErrorUtil::ThrowEtsTransferClassError(aniEnv); + return nullptr; + } + + ani_object object = CreateDynamicObject(aniEnv, aniCls, context); + if (object == nullptr) { + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "invalid object"); + EtsErrorUtil::ThrowEtsTransferClassError(aniEnv); + return nullptr; + } + + return object; +#else + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "EtsContextModule::NativeTransferDynamic not implemented"); + return nullptr; +#endif // LINUX_PREVIEW +} + +ani_object EtsContextModule::CreateDynamicObject(ani_env *aniEnv, ani_class aniCls, + std::shared_ptr contextPtr) +{ +#ifndef LINUX_PREVIEW + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + std::string contextType; + if (!AppExecFwk::GetStaticFieldString(aniEnv, aniCls, "contextType", contextType)) { + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "get context type failed"); + return nullptr; + } + TAG_LOGD(AAFwkTag::ETSRUNTIME, "contextType %{public}s", contextType.c_str()); + + if (!ContextTransfer::GetInstance().IsDynamicCreatorExist(contextType)) { + std::string className = GetClassNameByContextType(contextType); + if (!LoadTargetModule(aniEnv, className)) { + return nullptr; + } + } + + // get napiEnv from aniEnv + napi_env napiEnv = {}; + if (!arkts_napi_scope_open(aniEnv, &napiEnv)) { + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "arkts_napi_scope_open failed"); + return nullptr; + } + + // create normal context + auto contextObj = ContextTransfer::GetInstance().GetDynamicObject(contextType, napiEnv, contextPtr); + if (contextObj == nullptr) { + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "create Context failed"); + arkts_napi_scope_close_n(napiEnv, 0, nullptr, nullptr); + return nullptr; + } + + hybridgref ref = nullptr; + bool success = hybridgref_create_from_napi(napiEnv, contextObj, &ref); + if (!success) { + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "hybridgref_create_from_napi failed"); + arkts_napi_scope_close_n(napiEnv, 0, nullptr, nullptr); + return nullptr; + } + + ani_object result = nullptr; + success = hybridgref_get_esvalue(aniEnv, ref, &result); + if (!success) { + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "hybridgref_get_esvalue failed"); + hybridgref_delete_from_napi(napiEnv, ref); + arkts_napi_scope_close_n(napiEnv, 0, nullptr, nullptr); + return nullptr; + } + + hybridgref_delete_from_napi(napiEnv, ref); + + if (!arkts_napi_scope_close_n(napiEnv, 0, nullptr, nullptr)) { + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "arkts_napi_scope_close_n failed"); + return nullptr; + } + + return result; +#else + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "EtsContextModule::CreateDynamicObject not implemented"); + return nullptr; +#endif // LINUX_PREVIEW +} + +void EtsContextModuleInit(ani_env *aniEnv) +{ +#ifndef LINUX_PREVIEW + TAG_LOGD(AAFwkTag::ETSRUNTIME, "Init Context kit"); + if (aniEnv == nullptr) { + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "null ani env"); + return; + } + + ani_class contextCls = nullptr; + auto status = aniEnv->FindClass(ETS_CONTEXT_CLASS_NAME, &contextCls); + if (status != ANI_OK) { + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "FindClass Context failed status: %{public}d", status); + return; + } + + std::array nativeFuncs = { + ani_native_function { "nativeTransferStatic", "Lstd/interop/ESValue;Lstd/core/String;:Lstd/core/Object;", + reinterpret_cast(EtsContextModule::NativeTransferStatic) }, + ani_native_function { "nativeTransferDynamic", "Lstd/core/Object;:Lstd/interop/ESValue;", + reinterpret_cast(EtsContextModule::NativeTransferDynamic) }, + }; + status = aniEnv->Class_BindStaticNativeMethods(contextCls, nativeFuncs.data(), nativeFuncs.size()); + if (status != ANI_OK) { + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "Class_BindStaticNativeMethods failed status: %{public}d", status); + return; + } + + ContextTransfer::GetInstance().RegisterStaticObjectCreator("Context", + [](ani_env *aniEnv, std::shared_ptr context) -> ani_object { + ani_class cls {}; + ani_status status = ANI_ERROR; + if ((status = aniEnv->FindClass("Lapplication/Context/Context;", &cls)) != ANI_OK) { + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "status: %{public}d", status); + return nullptr; + } + return ContextUtil::CreateContextObject(aniEnv, cls, context); + }); + + ContextTransfer::GetInstance().RegisterDynamicObjectCreator("Context", + [](napi_env napiEnv, std::shared_ptr context) -> napi_value { + auto object = EtsContextModule::GetOrCreateDynamicObject(napiEnv, context); + if (object == nullptr) { + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "get or create object failed"); + return nullptr; + } + return object; + }); + + TAG_LOGD(AAFwkTag::ETSRUNTIME, "Init Context kit end"); +#else + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "EtsContextModuleInit not implemented"); +#endif // LINUX_PREVIEW +} + +extern "C" { +ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) +{ +// TAG_LOGD(AAFwkTag::ETSRUNTIME, "ANI_Constructor"); + if (vm == nullptr) { + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "null vm"); + return ANI_ERROR; + } + + ani_env *aniEnv = nullptr; + ani_status status = vm->GetEnv(ANI_VERSION_1, &aniEnv); + if (status != ANI_OK) { + //TAG_LOGE(AAFwkTag::ETSRUNTIME, "GetEnv failed status: %{public}d", status); + return ANI_NOT_FOUND; + } + + EtsContextModuleInit(aniEnv); + *result = ANI_VERSION_1; +// TAG_LOGD(AAFwkTag::ETSRUNTIME, "ANI_Constructor finish"); + return ANI_OK; +} +} +} // namespace AbilityRuntime +} // namespace OHOS diff --git a/frameworks/simulator/ability_simulator/src/simulator.cpp b/frameworks/simulator/ability_simulator/src/simulator.cpp index b51897b2530b1cc230fa0778c55bc273d256d907..1cd5eed6befd03d245bed2c2a0e537be9fe1c162 100644 --- a/frameworks/simulator/ability_simulator/src/simulator.cpp +++ b/frameworks/simulator/ability_simulator/src/simulator.cpp @@ -19,14 +19,23 @@ #include #include #include +#include +#include #include #include #include "ability_context.h" #include "ability_stage_context.h" +#include "bundle_constants.h" +#if defined(LINUX_PLATFORM) +#include "ani.h" +#include "ani_window_stage.h" +//#include "ani_window_manager.h" +#endif // LINUX_PLATFORM #include "bundle_container.h" #include "console.h" #include "declarative_module_preloader.h" +#include "dynamic_loader.h" #include "hilog_tag_wrapper.h" #include "js_ability_context.h" #include "js_ability_stage_context.h" @@ -52,6 +61,7 @@ namespace OHOS { namespace AbilityRuntime { namespace { + constexpr int64_t DEFAULT_GC_POOL_SIZE = 0x10000000; // 256MB constexpr int32_t DEFAULT_ARK_PROPERTIES = -1; constexpr size_t DEFAULT_GC_THREAD_NUM = 7; @@ -67,6 +77,7 @@ const std::string VERSION = "version"; const std::string ENTRY_PATH = "entryPath"; const std::string IS_SO = "isSO"; const std::string DEPENDENCY_ALIAS = "dependencyAlias"; +const std::string ENTERENCE_PATH = "entry/src/main/ets/entryability/EntryAbility/EntryAbility"; #if defined(WINDOWS_PLATFORM) constexpr char ARK_DEBUGGER_LIB_PATH[] = "libark_inspector.dll"; @@ -76,6 +87,119 @@ constexpr char ARK_DEBUGGER_LIB_PATH[] = "libark_inspector.dylib"; #error "Unsupported platform" #endif +#if defined(LINUX_PLATFORM) +typedef struct EtsVMOption { +// EtsOptionType option; + const void *extraInfo; +} EtsVMOption; + +typedef struct EtsVMInitArgs { + int version; + int nOptions; + EtsVMOption *options; +} EtsVMInitArgs; + +struct STSRuntimeAPI { + int (*ETS_GetDefaultVMInitArgs)(EtsVMInitArgs *vmArgs); + int (*ETS_GetCreatedVMs)(void **vmBuf, size_t bufLen, size_t *nVms); + ani_status (*ANI_GetCreatedVMs)(ani_vm **vms_buffer, ani_size vms_buffer_length, ani_size *result); + ani_status (*ANI_CreateVM)(const ani_options *options, uint32_t version, ani_vm **result); +}; + +using GetDefaultVMInitArgsSTSRuntimeType = int (*)(EtsVMInitArgs* vmArgs); +using GetCreatedVMsSTSRuntimeType = int (*)(void** vmBuf, size_t bufLen, size_t* nVms); +using CreateVMSTSRuntimeType = ani_status (*)(const ani_options *options, uint32_t version, ani_vm **result); +using ANIGetCreatedVMsType = ani_status (*)(ani_vm **vms_buffer, ani_size vms_buffer_length, ani_size *result); + +auto&& renderCallback = []( + const void*, const size_t bufferSize, const int32_t width, const int32_t height, const uint64_t timestamp) -> bool { + return true; +}; + +const char BOOT_PATH[] = "module/bootpath.json"; +bool LoadBootPathFile(std::string& bootfiles) +{ + std::ifstream inFile; + inFile.open(BOOT_PATH, std::ios::in); + if (!inFile.is_open()) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "read json error"); + return false; + } + nlohmann::json jsonObject = nlohmann::json::parse(inFile); + if (jsonObject.is_discarded()) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "json discarded error"); + inFile.close(); + return false; + } + + if (jsonObject.is_null() || jsonObject.empty()) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "invalid json"); + inFile.close(); + return false; + } + + for (const auto &[key, value] : jsonObject.items()) { + if (!value.is_null() && value.is_string()) { + std::string jsonValue = value.get(); + if (jsonValue.empty()) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "json value of %{public}s is empty", key.c_str()); + continue; + } + if (!bootfiles.empty()) { + bootfiles += ":"; + } + bootfiles += jsonValue.c_str(); + } + } + inFile.close(); + return true; +} + +bool LoadSymbolGetDefaultVMInitArgs(void* handle, STSRuntimeAPI& apis) +{ + auto symbol = DynamicFindSymbol(handle, "ETS_GetDefaultVMInitArgs"); + if (symbol == nullptr) { + TAG_LOGE(AAFwkTag::ABILITY_SIM, "runtime api not found: %{public}s", "ETS_GetDefaultVMInitArgs"); + return false; + } + apis.ETS_GetDefaultVMInitArgs = reinterpret_cast(symbol); + return true; +} + +bool LoadSymbolGetCreatedVMs(void* handle, STSRuntimeAPI& apis) +{ + auto symbol = DynamicFindSymbol(handle, "ETS_GetCreatedVMs"); + if (symbol == nullptr) { + TAG_LOGE(AAFwkTag::ABILITY_SIM, "runtime api not found: %{public}s", "ETS_GetCreatedVMs"); + return false; + } + apis.ETS_GetCreatedVMs = reinterpret_cast(symbol); + return true; +} + +bool LoadSymbolANIGetCreatedVMs(void* handle, STSRuntimeAPI& apis) +{ + auto symbol = DynamicFindSymbol(handle, "ANI_GetCreatedVMs"); + if (symbol == nullptr) { + TAG_LOGE(AAFwkTag::ABILITY_SIM, "runtime api not found: %{public}s", "ANI_GetCreatedVMs"); + return false; + } + apis.ANI_GetCreatedVMs = reinterpret_cast(symbol); + return true; +} + +bool LoadSymbolCreateVM(void* handle, STSRuntimeAPI& apis) +{ + auto symbol = DynamicFindSymbol(handle, "ANI_CreateVM"); + if (symbol == nullptr) { + TAG_LOGE(AAFwkTag::ABILITY_SIM, "runtime api not found: %{public}s", "ANI_CreateVM"); + return false; + } + apis.ANI_CreateVM = reinterpret_cast(symbol); + return true; +} +#endif // LINUX_PLATFORM + int32_t PrintVmLog(int32_t, int32_t, const char*, const char*, const char *message) { TAG_LOGD(AAFwkTag::ABILITY_SIM, "ArkLog:%{public}s", message); @@ -110,11 +234,27 @@ public: void UpdateConfiguration(const AppExecFwk::Configuration &config) override; void SetMockList(const std::map &mockList) override; void SetHostResolveBufferTracker(ResolveBufferTrackerCallback cb) override; + std::string GetCodeLanguage() override + { + return abilityInfo_->codeLanguage; + } +#if defined(LINUX_PLATFORM) + ani_object GetAniObj() override + { + return entryObject; + } + std::shared_ptr GetWindowScene() override + { + return windowScene_; + } +#endif // LINUX_PLATFORM + private: bool OnInit(); void Run(); napi_value LoadScript(const std::string &srcPath); void InitResourceMgr(); + void InitAbilityContext(); void InitJsAbilityContext(napi_env env, napi_value instanceValue); void DispatchStartLifecycle(napi_value instanceValue); std::unique_ptr CreateJsWindowStage(const std::shared_ptr &windowScene); @@ -162,6 +302,27 @@ private: std::map &pkgAliasMap); void GetPkgContextInfoListInner(cJSON *itemObject, std::vector &items, std::map &pkgAliasMap, std::string &pkgName); + int64_t StartJSAbility( + const std::string &abilitySrcPath, TerminateCallback callback, const std::string &abilityName = ""); +#if defined(LINUX_PLATFORM) + int64_t StartSTSAbility( + const std::string &abilitySrcPath, TerminateCallback callback, const std::string &abilityName = ""); + + bool LoadSTSRuntimeApis(); + bool StartSTSRuntime(); + bool LoadStsModule(); + bool onWindowStageCreate(ani_class entryClass, ani_object entryObject, ...); + + ani_env *aniEnv_ = nullptr; + ani_vm *aniVM_ = nullptr; + ani_class entryClass = nullptr; + ani_object entryObject = nullptr; + ani_ref entryObjectRef = nullptr; + + STSRuntimeAPI lazyApis_ = {}; + + std::shared_ptr windowScene_; +#endif // LINUX_PLATFORM }; void DebuggerTask::HandleTask(const uv_async_t *req) @@ -375,6 +536,29 @@ int64_t SimulatorImpl::StartAbility( } CreateStageContext(); + +#if defined(LINUX_PLATFORM) + return StartSTSAbility(abilitySrcPath, callback, abilityName); +#else + return 0; +#endif // LINUX_PLATFORM +/* + if (abilityInfo_->codeLanguage == AppExecFwk::Constants::CODE_LANGUAGE_1_1) { + return StartJSAbility(abilitySrcPath, callback, abilityName); +#if defined(LINUX_PLATFORM) + } else if (abilityInfo_->codeLanguage == AppExecFwk::Constants::CODE_LANGUAGE_1_2) { + return StartSTSAbility(abilitySrcPath, callback, abilityName); +#endif // LINUX_PLATFORM + } else { + TAG_LOGE(AAFwkTag::ABILITY_SIM, "Unsuported code language %{public}s", abilityInfo_->codeLanguage.c_str()); + return 0; + } +*/ +} + +int64_t SimulatorImpl::StartJSAbility( + const std::string &abilitySrcPath, TerminateCallback callback, const std::string &abilityName) +{ std::ifstream stream(options_.modulePath, std::ios::ate | std::ios::binary); if (!stream.is_open()) { TAG_LOGE(AAFwkTag::ABILITY_SIM, "open:%{public}s failed", options_.modulePath.c_str()); @@ -427,6 +611,44 @@ int64_t SimulatorImpl::StartAbility( return currentId_; } +#if defined(LINUX_PLATFORM) +int64_t SimulatorImpl::StartSTSAbility( + const std::string &abilitySrcPath, TerminateCallback callback, const std::string &abilityName) +{ + std::regex reg("modules.abc"); + std::string modulePath = std::regex_replace(options_.modulePath, reg, "modules_static.abc"); + options_.modulePath = modulePath; + InitAbilityContext(); + + LoadSTSRuntimeApis(); + StartSTSRuntime(); + + windowScene_ = std::make_shared(); + if (windowScene_ == nullptr) { + TAG_LOGE(AAFwkTag::ABILITY, "Could not create WindowScene"); + return 0; + } + sptr listener = nullptr; + auto ret = windowScene_->Init(-1, context_, listener); + if (ret != OHOS::Rosen::WMError::WM_OK) { + TAG_LOGE(AAFwkTag::ABILITY, "Could not init WindowScene"); + return 0; + } + auto window = windowScene_->GetMainWindow(); + window->CreateSurfaceNode("default", std::move(renderCallback)); + LoadStsModule(); + + auto stsWindowStage = CreateAniWindowStage(aniEnv_, windowScene_); +// auto stsWindowStage = OHOS::Rosen::AniWindowManager::WindowStageCreate(aniEnv_, 0); + onWindowStageCreate(entryClass, entryObject, stsWindowStage); + + ++currentId_; + terminateCallback_ = callback; +// InitResourceMgr(); + return currentId_; +} +#endif // LINUX_PLATFORM + bool SimulatorImpl::LoadAbilityStage(uint8_t *buffer, size_t len) { if (moduleInfo_ == nullptr) { @@ -630,7 +852,7 @@ void SimulatorImpl::InitResourceMgr() resourceMgr_->UpdateResConfig(*resConfig); } -void SimulatorImpl::InitJsAbilityContext(napi_env env, napi_value obj) +void SimulatorImpl::InitAbilityContext() { if (context_ == nullptr) { context_ = std::make_shared(); @@ -640,6 +862,11 @@ void SimulatorImpl::InitJsAbilityContext(napi_env env, napi_value obj) context_->SetResourceManager(resourceMgr_); context_->SetAbilityInfo(abilityInfo_); } +} + +void SimulatorImpl::InitJsAbilityContext(napi_env env, napi_value obj) +{ + InitAbilityContext(); napi_value contextObj = CreateJsAbilityContext(nativeEngine_, context_); auto systemModule = std::shared_ptr( JsRuntime::LoadSystemModuleByEngine(nativeEngine_, "application.AbilityContext", &contextObj, 1)); @@ -950,7 +1177,193 @@ void SimulatorImpl::Run() postTask_([this]() { Run(); }, 0); } } + +#if defined(LINUX_PLATFORM) +bool SimulatorImpl::LoadSTSRuntimeApis() +{ + auto dsoAce = DynamicLoadLibrary("libace_compatible.so", 1); + if (!dsoAce) { + TAG_LOGE(AAFwkTag::ABILITY_SIM, "load library failed: %{public}s", "libace_compatible.so"); + return false; + } + auto dso = DynamicLoadLibrary("libarkruntime.so", 1); + if (!dso) { + TAG_LOGE(AAFwkTag::ABILITY_SIM, "load library failed: %{public}s", "libarkruntime.so"); + return false; + } + auto dsoEts = DynamicLoadLibrary("libetsnative.so", 1); + if (!dso) { + TAG_LOGE(AAFwkTag::ABILITY_SIM, "load library failed: %{public}s", "libetsnative.so"); + return false; + } + if (!LoadSymbolGetDefaultVMInitArgs(dsoEts, lazyApis_) || + !LoadSymbolGetCreatedVMs(dsoEts, lazyApis_) || + !LoadSymbolCreateVM(dso, lazyApis_) || + !LoadSymbolANIGetCreatedVMs(dso, lazyApis_)) { + TAG_LOGE(AAFwkTag::ABILITY_SIM, "load library failed: %{public}s", "LoadSymbolGetDefaultVMInitArgs"); + return false; + } + return true; +} + +bool SimulatorImpl::StartSTSRuntime() +{ + std::string bootfiles; + LoadBootPathFile(bootfiles); + + // Create boot-panda-files options + std::vector options; + const std::string optionPrefix = "--ext:"; + std::string bootString = optionPrefix + "--boot-panda-files=" + bootfiles; + TAG_LOGI(AAFwkTag::ABILITY_SIM, "bootString %{public}s", bootString.c_str()); + options.push_back(ani_option{bootString.c_str(), nullptr}); +// std::string schedulingExternal = optionPrefix + "--coroutine-enable-external-scheduling=true"; +// ani_option schedulingExternalOption = {schedulingExternal.data(), nullptr}; +// options.push_back(schedulingExternalOption); + + std::string forbiddenJIT = optionPrefix + "--compiler-enable-jit=false"; + ani_option forbiddenJITOption = {forbiddenJIT.data(), nullptr}; + options.push_back(forbiddenJITOption); + + options.push_back(ani_option{"--ext:--log-level=info", nullptr}); + + options.push_back(ani_option{"--ext:--gc-type=stw", nullptr}); + +// Linux runtime does not support "interop" +// std::string interop = optionPrefix + "interop"; +// ani_option interopOption = {interop.data(), (void*)aniEnv_}; +// options.push_back(interopOption); + + ani_options optionsPtr = {options.size(), options.data()}; + auto status = lazyApis_.ANI_CreateVM(&optionsPtr, ANI_VERSION_1, &aniVM_); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ABILITY_SIM, "ANI_CreateVM failed %{public}d", status); + return false; + } + + ani_size nrVMs; + if (lazyApis_.ANI_GetCreatedVMs(&aniVM_, 1, &nrVMs) != ANI_OK) { + return false; + }; + + if (aniVM_->GetEnv(ANI_VERSION_1, &aniEnv_) != ANI_OK) { + TAG_LOGE(AAFwkTag::ABILITY_SIM, "Failed GetEnv"); + return false; + } + return true; +} + +bool SimulatorImpl::LoadStsModule() +{ + ani_class stringCls = nullptr; + if (aniEnv_->FindClass("Lstd/core/String;", &stringCls) != ANI_OK) { + TAG_LOGE(AAFwkTag::ABILITY_SIM, "FindClass Lstd/core/String Failed"); + return false; + } + + std::regex reg("modules.abc"); + std::string modulePath = std::regex_replace(options_.modulePath, reg, "modules_static.abc"); + ani_string ani_str; + if (aniEnv_->String_NewUTF8(modulePath.c_str(), modulePath.size(), &ani_str) != ANI_OK) { + TAG_LOGE(AAFwkTag::ABILITY_SIM, "String_NewUTF8 modulePath Failed"); + return false; + } + + ani_ref undefined_ref; + if (aniEnv_->GetUndefined(&undefined_ref) != ANI_OK) { + TAG_LOGE(AAFwkTag::ABILITY_SIM, "GetUndefined failed"); + return false; + } + ani_array_ref refArray; + if (aniEnv_->Array_New_Ref(stringCls, 1, undefined_ref, &refArray) != ANI_OK) { + TAG_LOGE(AAFwkTag::ABILITY_SIM, "Array_New_Ref Failed"); + return false; + } + if (aniEnv_->Array_Set_Ref(refArray, 0, ani_str) != ANI_OK) { + TAG_LOGE(AAFwkTag::ABILITY_SIM, "Array_Set_Ref Failed"); + return false; + } + + ani_class cls = nullptr; + if (aniEnv_->FindClass("Lstd/core/AbcRuntimeLinker;", &cls) != ANI_OK) { + TAG_LOGE(AAFwkTag::ABILITY_SIM, "FindClass AbcRuntimeLinker failed"); + return false; + } + ani_method method = nullptr; + if (aniEnv_->Class_FindMethod(cls, "", "Lstd/core/RuntimeLinker;[Lstd/core/String;:V", &method) != ANI_OK) { + TAG_LOGE(AAFwkTag::ABILITY_SIM, "Class_FindMethod ctor failed"); + return false; + } + ani_object object = nullptr; + if (aniEnv_->Object_New(cls, method, &object, undefined_ref, refArray) != ANI_OK) { + TAG_LOGE(AAFwkTag::ABILITY_SIM, "Object_New AbcRuntimeLinker failed"); + return false; + } + ani_method loadClassMethod = nullptr; + if (aniEnv_->Class_FindMethod(cls, "loadClass", nullptr, &loadClassMethod) != ANI_OK) { + TAG_LOGE(AAFwkTag::ABILITY_SIM, "Class_FindMethod loadClass failed"); + return false; + } + + std::string entryPath = ENTERENCE_PATH; + ani_string entryClassStr; + aniEnv_->String_NewUTF8(entryPath.c_str(), entryPath.length(), &entryClassStr); + ani_ref entryClassRef = nullptr; + ani_boolean isInit = false; + TAG_LOGI(AAFwkTag::ABILITY_SIM, "load class: %{public}s", entryPath.c_str()); + if (aniEnv_->Object_CallMethod_Ref(object, loadClassMethod, &entryClassRef, entryClassStr, isInit) != ANI_OK) { + TAG_LOGE(AAFwkTag::ABILITY_SIM, "Object_CallMethod_Ref loadClassMethod failed"); + return false; + } + entryClass = static_cast(entryClassRef); + + ani_method entryMethod = nullptr; + if (aniEnv_->Class_FindMethod(entryClass, "", ":V", &entryMethod) != ANI_OK) { + TAG_LOGE(AAFwkTag::ABILITY_SIM, "Class_FindMethod ctor failed"); + return false; + } + if (aniEnv_->Object_New(entryClass, entryMethod, &entryObject) != ANI_OK) { + TAG_LOGE(AAFwkTag::ABILITY_SIM, "Object_New AbcRuntimeLinker failed"); + return false; + } + ani_ref entryObjectRef = nullptr; + if (aniEnv_->GlobalReference_Create(entryObject, &entryObjectRef) != ANI_OK) { + TAG_LOGE(AAFwkTag::ABILITY_SIM, "GlobalReference_Create failed"); + return false; + } + +/* + if (aniEnv_->Class_FindMethod(entryClass, "onCreate", ":V", &method) != ANI_OK) { + TAG_LOGI(AAFwkTag::ABILITY, "Class_FindMethod FAILED"); + return false; + } + if (aniEnv_->Object_CallMethod_Void(entryObject, method) != ANI_OK) { + TAG_LOGE(AAFwkTag::ABILITY, "CALL Object_CallMethod FAILED"); + return false; + } +*/ + return true; +} + +bool SimulatorImpl::onWindowStageCreate(ani_class entryClass, ani_object entryObject, ...) +{ + ani_method method {}; + auto status = aniEnv_->Class_FindMethod(entryClass, "onWindowStageCreate", "L@ohos/window/window/WindowStage;:V", &method); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::UIABILITY, "status : %{public}d", status); + return false; + } + va_list args; + va_start(args, entryObject); + if ((status = aniEnv_->Object_CallMethod_Void_V(entryObject, method, args)) != ANI_OK) { + TAG_LOGE(AAFwkTag::UIABILITY, "status : %{public}d", status); + return false; + } + va_end(args); + return true; } +#endif // LINUX_PLATFORM +} // namespace std::shared_ptr Simulator::Create(const Options &options) { diff --git a/frameworks/simulator/common/include/ability_info.h b/frameworks/simulator/common/include/ability_info.h index 2b2b57852f13d12908184487cacbacb8300e421c..f7c4aef9633a09c10a13835f1bdc495d374866a4 100644 --- a/frameworks/simulator/common/include/ability_info.h +++ b/frameworks/simulator/common/include/ability_info.h @@ -21,6 +21,7 @@ #include #include "application_info.h" +#include "bundle_constants.h" #include "extension_ability_info.h" namespace OHOS { @@ -212,6 +213,8 @@ struct AbilityInfo { int64_t installTime; std::vector supportExtNames; std::vector supportMimeTypes; + + std::string codeLanguage = Constants::CODE_LANGUAGE_1_2; }; } // namespace AppExecFwk } // namespace OHOS diff --git a/frameworks/simulator/common/include/application_info.h b/frameworks/simulator/common/include/application_info.h index ab8a00e1a93b054715da92ba99170ee776312aad..37b3f9aef6af23ea869f525b40f2843a028dba9c 100644 --- a/frameworks/simulator/common/include/application_info.h +++ b/frameworks/simulator/common/include/application_info.h @@ -19,6 +19,7 @@ #include #include #include +#include "bundle_constants.h" #include "module_info.h" namespace OHOS { @@ -300,6 +301,8 @@ struct ApplicationInfo { std::string organization; std::string installSource; std::string configuration; + + std::string codeLanguage = Constants::CODE_LANGUAGE_1_2; }; } // namespace AppExecFwk } // namespace OHOS diff --git a/frameworks/simulator/common/include/bundle_constants.h b/frameworks/simulator/common/include/bundle_constants.h index f8694a0849c6feffaaea7c026a0176b8ac3321bc..1d6fda74a6e33c0542440ad4f975f845a93ef2c3 100644 --- a/frameworks/simulator/common/include/bundle_constants.h +++ b/frameworks/simulator/common/include/bundle_constants.h @@ -47,6 +47,11 @@ constexpr const char* HAP_PATH = "hapPath"; constexpr int32_t INITIAL_APP_INDEX = 0; constexpr const char* RELATIVE_PATH = "../"; constexpr const char* APP_DETAIL_ABILITY = "AppDetailAbility"; + +constexpr const char* CODE_LANGUAGE = "codeLanguage"; +constexpr const char* CODE_LANGUAGE_1_1 = "1.1"; +constexpr const char* CODE_LANGUAGE_1_2 = "1.2"; +constexpr const char* CODE_LANGUAGE_HYBRID = "hybrid"; } // namespace Constants } // namespace AppExecFwk } // namespace OHOS diff --git a/frameworks/simulator/common/include/extension_ability_info.h b/frameworks/simulator/common/include/extension_ability_info.h index b4822125678938427d63d37d592b001b650eca4f..b2c5d7fa36015115d8c99aa03790cb668c7d389e 100644 --- a/frameworks/simulator/common/include/extension_ability_info.h +++ b/frameworks/simulator/common/include/extension_ability_info.h @@ -110,6 +110,7 @@ struct ExtensionAbilityInfo { CompileMode compileMode = CompileMode::JS_BUNDLE; int32_t uid = -1; std::vector skillUri; + std::string codeLanguage = Constants::CODE_LANGUAGE_1_2; }; } // namespace AppExecFwk } // namespace OHOS diff --git a/frameworks/simulator/common/include/hap_module_info.h b/frameworks/simulator/common/include/hap_module_info.h index 35278cfadbcda16808a00bed1c158fcc54ff439a..2fd6490119942ab500aee08c8ac4eeb3a1658495 100644 --- a/frameworks/simulator/common/include/hap_module_info.h +++ b/frameworks/simulator/common/include/hap_module_info.h @@ -21,6 +21,7 @@ #include "ability_info.h" #include "application_info.h" #include "extension_ability_info.h" +#include "bundle_constants.h" namespace OHOS { namespace AppExecFwk { @@ -175,6 +176,7 @@ struct HapModuleInfo { // overlay module info std::vector overlayModuleInfos; + std::string codeLanguage = Constants::CODE_LANGUAGE_1_2; }; } // namespace AppExecFwk } // namespace OHOS