18bf80f4bSopenharmony_ci/*
28bf80f4bSopenharmony_ci * Copyright (C) 2024 Huawei Device Co., Ltd.
38bf80f4bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
48bf80f4bSopenharmony_ci * you may not use this file except in compliance with the License.
58bf80f4bSopenharmony_ci * You may obtain a copy of the License at
68bf80f4bSopenharmony_ci *
78bf80f4bSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
88bf80f4bSopenharmony_ci *
98bf80f4bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
108bf80f4bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
118bf80f4bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128bf80f4bSopenharmony_ci * See the License for the specific language governing permissions and
138bf80f4bSopenharmony_ci * limitations under the License.
148bf80f4bSopenharmony_ci */
158bf80f4bSopenharmony_ci
168bf80f4bSopenharmony_ci#include "test_runner.h"
178bf80f4bSopenharmony_ci
188bf80f4bSopenharmony_ci#include <dlfcn.h>
198bf80f4bSopenharmony_ci#include <memory>
208bf80f4bSopenharmony_ci#include <string_view>
218bf80f4bSopenharmony_ci
228bf80f4bSopenharmony_ci#include "napi/native_api.h"
238bf80f4bSopenharmony_ci#include "napi/native_node_api.h"
248bf80f4bSopenharmony_ci
258bf80f4bSopenharmony_ci#include <base/containers/array_view.h>
268bf80f4bSopenharmony_ci
278bf80f4bSopenharmony_ci#include <core/intf_engine.h>
288bf80f4bSopenharmony_ci#include <core/ecs/intf_system_graph_loader.h>
298bf80f4bSopenharmony_ci#include <core/engine_info.h>
308bf80f4bSopenharmony_ci#include <core/implementation_uids.h>
318bf80f4bSopenharmony_ci#include <core/io/intf_file_manager.h>
328bf80f4bSopenharmony_ci#include <core/namespace.h>
338bf80f4bSopenharmony_ci#include <core/os/intf_platform.h>
348bf80f4bSopenharmony_ci#include <core/plugin/intf_plugin_register.h>
358bf80f4bSopenharmony_ci#include <core/property/intf_property_handle.h>
368bf80f4bSopenharmony_ci
378bf80f4bSopenharmony_ci#include <meta/interface/intf_meta_object_lib.h>
388bf80f4bSopenharmony_ci#include <meta/interface/intf_task_queue_registry.h>
398bf80f4bSopenharmony_ci#include <meta/interface/intf_task_queue.h>
408bf80f4bSopenharmony_ci#include <meta/interface/intf_object.h>
418bf80f4bSopenharmony_ci#include <meta/interface/intf_object_registry.h>
428bf80f4bSopenharmony_ci#include <meta/interface/intf_task_queue.h>
438bf80f4bSopenharmony_ci#include <meta/base/shared_ptr.h>
448bf80f4bSopenharmony_ci#include <meta/base/interface_macros.h>
458bf80f4bSopenharmony_ci#include <meta/api/make_callback.h>
468bf80f4bSopenharmony_ci#include <meta/ext/object.h>
478bf80f4bSopenharmony_ci
488bf80f4bSopenharmony_ci#include <scene_plugin/namespace.h>
498bf80f4bSopenharmony_ci#include <scene_plugin/interface/intf_scene.h>
508bf80f4bSopenharmony_ci#include <scene_plugin/interface/intf_ecs_scene.h>
518bf80f4bSopenharmony_ci#include <scene_plugin/interface/intf_mesh.h>
528bf80f4bSopenharmony_ci#include <scene_plugin/interface/intf_material.h>
538bf80f4bSopenharmony_ci#include <scene_plugin/api/scene_uid.h>
548bf80f4bSopenharmony_ci
558bf80f4bSopenharmony_ci#include "ability.h"
568bf80f4bSopenharmony_ci#include "data_ability_helper.h"
578bf80f4bSopenharmony_ci#include "napi_base_context.h"
588bf80f4bSopenharmony_ci
598bf80f4bSopenharmony_ci#include <render/implementation_uids.h>
608bf80f4bSopenharmony_ci#include <render/gles/intf_device_gles.h>
618bf80f4bSopenharmony_ci#include <render/intf_renderer.h>
628bf80f4bSopenharmony_ci#include <render/intf_render_context.h>
638bf80f4bSopenharmony_ci
648bf80f4bSopenharmony_ci#include "3d_widget_adapter_log.h"
658bf80f4bSopenharmony_ci#include "ohos/texture_layer.h"
668bf80f4bSopenharmony_ci
678bf80f4bSopenharmony_ciCORE_BEGIN_NAMESPACE()
688bf80f4bSopenharmony_ciIPluginRegister& (*GetPluginRegister) () = nullptr;
698bf80f4bSopenharmony_ci
708bf80f4bSopenharmony_civoid (*CreatePluginRegistry) (
718bf80f4bSopenharmony_ci    const struct PlatformCreateInfo& platformCreateInfo) = nullptr;
728bf80f4bSopenharmony_ci
738bf80f4bSopenharmony_cibool (*IsDebugBuild) () = nullptr;
748bf80f4bSopenharmony_ci
758bf80f4bSopenharmony_ciBASE_NS::string_view (*GetVersion) () = nullptr;
768bf80f4bSopenharmony_ciCORE_END_NAMESPACE()
778bf80f4bSopenharmony_ci
788bf80f4bSopenharmony_ciMETA_BEGIN_NAMESPACE()
798bf80f4bSopenharmony_ciOHOS::Render3D::HapInfo GetHapInfo()
808bf80f4bSopenharmony_ci{
818bf80f4bSopenharmony_ci    std::shared_ptr<OHOS::AbilityRuntime::ApplicationContext> context =
828bf80f4bSopenharmony_ci        OHOS::AbilityRuntime::ApplicationContext::GetApplicationContext();
838bf80f4bSopenharmony_ci    if (!context) {
848bf80f4bSopenharmony_ci        WIDGET_LOGE("Failed to get application context.");
858bf80f4bSopenharmony_ci        return {};
868bf80f4bSopenharmony_ci    }
878bf80f4bSopenharmony_ci    auto resourceManager = context->GetResourceManager();
888bf80f4bSopenharmony_ci    if (!resourceManager) {
898bf80f4bSopenharmony_ci        WIDGET_LOGE("Failed to get resource manager.");
908bf80f4bSopenharmony_ci        return {};
918bf80f4bSopenharmony_ci    }
928bf80f4bSopenharmony_ci    OHOS::Render3D::HapInfo hapInfo;
938bf80f4bSopenharmony_ci    hapInfo.bundleName_ = resourceManager->bundleInfo.first;
948bf80f4bSopenharmony_ci    hapInfo.moduleName_ = resourceManager->bundleInfo.second;
958bf80f4bSopenharmony_ci
968bf80f4bSopenharmony_ci    // hapPath
978bf80f4bSopenharmony_ci    std::string hapPath = context->GetBundleCodeDir();
988bf80f4bSopenharmony_ci    hapInfo.hapPath_ = hapPath + "/" + hapInfo.moduleName_ + ".hap";
998bf80f4bSopenharmony_ci    WIDGET_LOGD("bundle %s, module %s, hapPath %s",
1008bf80f4bSopenharmony_ci        hapInfo.bundleName_.c_str(),
1018bf80f4bSopenharmony_ci        hapInfo.moduleName_.c_str(),
1028bf80f4bSopenharmony_ci        hapInfo.hapPath_.c_str());
1038bf80f4bSopenharmony_ci
1048bf80f4bSopenharmony_ci    return hapInfo;
1058bf80f4bSopenharmony_ci}
1068bf80f4bSopenharmony_ci
1078bf80f4bSopenharmony_ciusing IntfPtr = META_NS::SharedPtrIInterface;
1088bf80f4bSopenharmony_ciusing IntfWeakPtr = META_NS::WeakPtrIInterface;
1098bf80f4bSopenharmony_ci
1108bf80f4bSopenharmony_cistruct EngineInstance {
1118bf80f4bSopenharmony_ci    void *libHandle = nullptr;
1128bf80f4bSopenharmony_ci    BASE_NS::shared_ptr<RENDER_NS::IRenderContext> renderContext;
1138bf80f4bSopenharmony_ci    BASE_NS::shared_ptr<CORE_NS::IEngine> engine;
1148bf80f4bSopenharmony_ci};
1158bf80f4bSopenharmony_ci
1168bf80f4bSopenharmony_cistatic EngineInstance g_engineInstance;
1178bf80f4bSopenharmony_ci
1188bf80f4bSopenharmony_ciMETA_NS::ITaskQueue::Ptr engineThread;
1198bf80f4bSopenharmony_ciMETA_NS::ITaskQueue::Ptr ioThread;
1208bf80f4bSopenharmony_ci
1218bf80f4bSopenharmony_cistatic constexpr BASE_NS::Uid ENGINE_THREAD { "2070e705-d061-40e4-bfb7-90fad2c280af" };
1228bf80f4bSopenharmony_cistatic constexpr BASE_NS::Uid APP_THREAD { "b2e8cef3-453a-4651-b564-5190f8b5190d" };
1238bf80f4bSopenharmony_cistatic constexpr BASE_NS::Uid IO_QUEUE { "be88e9a0-9cd8-45ab-be48-937953dc258f" };
1248bf80f4bSopenharmony_ci
1258bf80f4bSopenharmony_ciOHOS::Render3D::HapInfo hapInfo;
1268bf80f4bSopenharmony_ci
1278bf80f4bSopenharmony_citemplate<typename T>
1288bf80f4bSopenharmony_cibool LoadFunc(T &fn, const char *fName, void* handle)
1298bf80f4bSopenharmony_ci{
1308bf80f4bSopenharmony_ci    fn = reinterpret_cast<T>(dlsym(handle, fName));
1318bf80f4bSopenharmony_ci    if (fn == nullptr) {
1328bf80f4bSopenharmony_ci        WIDGET_LOGE("%s open %s", __func__, dlerror());
1338bf80f4bSopenharmony_ci        return false;
1348bf80f4bSopenharmony_ci    }
1358bf80f4bSopenharmony_ci    return true;
1368bf80f4bSopenharmony_ci}
1378bf80f4bSopenharmony_ci
1388bf80f4bSopenharmony_ci
1398bf80f4bSopenharmony_cibool LoadEngineLib()
1408bf80f4bSopenharmony_ci{
1418bf80f4bSopenharmony_ci    if (g_engineInstance.libHandle != nullptr) {
1428bf80f4bSopenharmony_ci        WIDGET_LOGD("%s, already loaded", __func__);
1438bf80f4bSopenharmony_ci        return true;
1448bf80f4bSopenharmony_ci    }
1458bf80f4bSopenharmony_ci
1468bf80f4bSopenharmony_ci    #define TO_STRING(name) #name
1478bf80f4bSopenharmony_ci    #define LIB_NAME(name) TO_STRING(name)
1488bf80f4bSopenharmony_ci    constexpr std::string_view lib { "/system/lib/libAGPDLL.z.so" };
1498bf80f4bSopenharmony_ci    g_engineInstance.libHandle = dlopen(lib.data(), RTLD_LAZY);
1508bf80f4bSopenharmony_ci
1518bf80f4bSopenharmony_ci    if (g_engineInstance.libHandle == nullptr) {
1528bf80f4bSopenharmony_ci        WIDGET_LOGE("%s, open lib fail %s", __func__, dlerror());
1538bf80f4bSopenharmony_ci        return false;
1548bf80f4bSopenharmony_ci    }
1558bf80f4bSopenharmony_ci    #undef TO_STRING
1568bf80f4bSopenharmony_ci    #undef LIB_NAME
1578bf80f4bSopenharmony_ci
1588bf80f4bSopenharmony_ci    if (!(LOAD_FUNC(CORE_NS::CreatePluginRegistry,
1598bf80f4bSopenharmony_ci        "_ZN4Core20CreatePluginRegistryERKNS_18PlatformCreateInfoE")
1608bf80f4bSopenharmony_ci        && LOAD_FUNC(CORE_NS::GetPluginRegister, "_ZN4Core17GetPluginRegisterEv")
1618bf80f4bSopenharmony_ci        && LOAD_FUNC(CORE_NS::IsDebugBuild, "_ZN4Core12IsDebugBuildEv")
1628bf80f4bSopenharmony_ci        && LOAD_FUNC(CORE_NS::GetVersion, "_ZN4Core13GetVersionRevEv"))) {
1638bf80f4bSopenharmony_ci        return false;
1648bf80f4bSopenharmony_ci    }
1658bf80f4bSopenharmony_ci    #undef LOAD_FUNC
1668bf80f4bSopenharmony_ci
1678bf80f4bSopenharmony_ci    return true;
1688bf80f4bSopenharmony_ci}
1698bf80f4bSopenharmony_ci
1708bf80f4bSopenharmony_cibool LoadPlugins(const CORE_NS::PlatformCreateInfo& platformCreateInfo)
1718bf80f4bSopenharmony_ci{
1728bf80f4bSopenharmony_ci    WIDGET_LOGD("LoadPlugins Begin lgp");
1738bf80f4bSopenharmony_ci    if (g_engineInstance.engine) {
1748bf80f4bSopenharmony_ci        return true;
1758bf80f4bSopenharmony_ci    }
1768bf80f4bSopenharmony_ci    if (!LoadEngineLib()) {
1778bf80f4bSopenharmony_ci        return false;
1788bf80f4bSopenharmony_ci    }
1798bf80f4bSopenharmony_ci    WIDGET_LOGD("load engine success!");
1808bf80f4bSopenharmony_ci    const BASE_NS::Uid DefaultPluginList[] { SCENE_NS::UID_SCENE_PLUGIN };
1818bf80f4bSopenharmony_ci
1828bf80f4bSopenharmony_ci    CORE_NS::CreatePluginRegistry(platformCreateInfo);
1838bf80f4bSopenharmony_ci    if (!CORE_NS::GetPluginRegister().LoadPlugins(DefaultPluginList)) {
1848bf80f4bSopenharmony_ci        WIDGET_LOGE("fail to load scene widget plugin");
1858bf80f4bSopenharmony_ci        return false;
1868bf80f4bSopenharmony_ci    }
1878bf80f4bSopenharmony_ci    WIDGET_LOGD("load plugin success");
1888bf80f4bSopenharmony_ci    return true;
1898bf80f4bSopenharmony_ci}
1908bf80f4bSopenharmony_ci
1918bf80f4bSopenharmony_cibool InitEngine(CORE_NS::PlatformCreateInfo platformCreateInfo)
1928bf80f4bSopenharmony_ci{
1938bf80f4bSopenharmony_ci    if (g_engineInstance.engine) {
1948bf80f4bSopenharmony_ci        return true;
1958bf80f4bSopenharmony_ci    }
1968bf80f4bSopenharmony_ci    auto& tr = META_NS::GetTaskQueueRegistry();
1978bf80f4bSopenharmony_ci    auto& obr = META_NS::GetObjectRegistry();
1988bf80f4bSopenharmony_ci
1998bf80f4bSopenharmony_ci    engineThread = tr.GetTaskQueue(ENGINE_THREAD);
2008bf80f4bSopenharmony_ci    if (!engineThread) {
2018bf80f4bSopenharmony_ci        engineThread = obr.Create<META_NS::ITaskQueue>(META_NS::ClassId::ThreadedTaskQueue);
2028bf80f4bSopenharmony_ci        tr.RegisterTaskQueue(engineThread, ENGINE_THREAD);
2038bf80f4bSopenharmony_ci    }
2048bf80f4bSopenharmony_ci    ioThread = tr.GetTaskQueue(IO_QUEUE);
2058bf80f4bSopenharmony_ci    if (!ioThread) {
2068bf80f4bSopenharmony_ci        ioThread = obr.Create<META_NS::ITaskQueue>(META_NS::ClassId::ThreadedTaskQueue);
2078bf80f4bSopenharmony_ci        tr.RegisterTaskQueue(ioThread, IO_QUEUE);
2088bf80f4bSopenharmony_ci    }
2098bf80f4bSopenharmony_ci    return true;
2108bf80f4bSopenharmony_ci}
2118bf80f4bSopenharmony_ci
2128bf80f4bSopenharmony_cibool LoadPluginsAndInit()
2138bf80f4bSopenharmony_ci{
2148bf80f4bSopenharmony_ci    WIDGET_LOGD("scene adapter loadPlugins");
2158bf80f4bSopenharmony_ci    hapInfo = GetHapInfo();
2168bf80f4bSopenharmony_ci
2178bf80f4bSopenharmony_ci    #define TO_STRING(name) #name
2188bf80f4bSopenharmony_ci    #define PLATFORM_PATH_NAME(name) TO_STRING(name)
2198bf80f4bSopenharmony_ci    CORE_NS::PlatformCreateInfo platformCreateInfo {
2208bf80f4bSopenharmony_ci        PLATFORM_PATH_NAME(PLATFORM_CORE_ROOT_PATH),
2218bf80f4bSopenharmony_ci        PLATFORM_PATH_NAME(PLATFORM_APP_ROOT_PATH),
2228bf80f4bSopenharmony_ci        PLATFORM_PATH_NAME(PLATFORM_APP_PLUGIN_PATH),
2238bf80f4bSopenharmony_ci        hapInfo.hapPath_.c_str(),
2248bf80f4bSopenharmony_ci        hapInfo.bundleName_.c_str(),
2258bf80f4bSopenharmony_ci        hapInfo.moduleName_.c_str()
2268bf80f4bSopenharmony_ci    };
2278bf80f4bSopenharmony_ci    #undef TO_STRING
2288bf80f4bSopenharmony_ci    #undef PLATFORM_PATH_NAME
2298bf80f4bSopenharmony_ci    if (!LoadPlugins(platformCreateInfo)) {
2308bf80f4bSopenharmony_ci        return false;
2318bf80f4bSopenharmony_ci    }
2328bf80f4bSopenharmony_ci
2338bf80f4bSopenharmony_ci    if (!InitEngine(platformCreateInfo)) {
2348bf80f4bSopenharmony_ci        return false;
2358bf80f4bSopenharmony_ci    }
2368bf80f4bSopenharmony_ci
2378bf80f4bSopenharmony_ci    return true;
2388bf80f4bSopenharmony_ci}
2398bf80f4bSopenharmony_ci
2408bf80f4bSopenharmony_civoid SetTest()
2418bf80f4bSopenharmony_ci{
2428bf80f4bSopenharmony_ci    LoadPluginsAndInit();
2438bf80f4bSopenharmony_ci    RegisterTestTypes();
2448bf80f4bSopenharmony_ci}
2458bf80f4bSopenharmony_ci
2468bf80f4bSopenharmony_civoid ResetTest()
2478bf80f4bSopenharmony_ci{
2488bf80f4bSopenharmony_ci    g_engineInstance.engine.reset();
2498bf80f4bSopenharmony_ci}
2508bf80f4bSopenharmony_ciMETA_END_NAMESPACE()
2518bf80f4bSopenharmony_ci
252