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 "plugin_registry.h"
178bf80f4bSopenharmony_ci
188bf80f4bSopenharmony_ci#include <algorithm>
198bf80f4bSopenharmony_ci
208bf80f4bSopenharmony_ci#include <base/util/uid_util.h>
218bf80f4bSopenharmony_ci#include <core/ecs/intf_component_manager.h>
228bf80f4bSopenharmony_ci#include <core/log.h>
238bf80f4bSopenharmony_ci
248bf80f4bSopenharmony_ci#include "image/loaders/image_loader_ktx.h"
258bf80f4bSopenharmony_ci#include "image/loaders/image_loader_stb_image.h"
268bf80f4bSopenharmony_ci#include "image/loaders/image_loader_libpng.h"
278bf80f4bSopenharmony_ci#include "image/loaders/image_loader_libjpeg.h"
288bf80f4bSopenharmony_ci#include "io/file_manager.h"
298bf80f4bSopenharmony_ci#include "io/std_filesystem.h"
308bf80f4bSopenharmony_ci#include "os/intf_library.h"
318bf80f4bSopenharmony_ci#include "static_plugin_decl.h"
328bf80f4bSopenharmony_ci
338bf80f4bSopenharmony_ciCORE_BEGIN_NAMESPACE()
348bf80f4bSopenharmony_ciusing BASE_NS::array_view;
358bf80f4bSopenharmony_ciusing BASE_NS::move;
368bf80f4bSopenharmony_ciusing BASE_NS::pair;
378bf80f4bSopenharmony_ciusing BASE_NS::reverse_iterator;
388bf80f4bSopenharmony_ciusing BASE_NS::string;
398bf80f4bSopenharmony_ciusing BASE_NS::string_view;
408bf80f4bSopenharmony_ciusing BASE_NS::to_string;
418bf80f4bSopenharmony_ciusing BASE_NS::Uid;
428bf80f4bSopenharmony_ciusing BASE_NS::vector;
438bf80f4bSopenharmony_ci
448bf80f4bSopenharmony_ciIInterface* CreateFileMonitor(CORE_NS::IClassFactory& registry, CORE_NS::PluginToken token);
458bf80f4bSopenharmony_ciIInterface* GetFileApiFactory(CORE_NS::IClassRegister& registry, CORE_NS::PluginToken token);
468bf80f4bSopenharmony_ci
478bf80f4bSopenharmony_cinamespace StaticPluginRegistry {
488bf80f4bSopenharmony_ci// static_plugin_registry magic begin
498bf80f4bSopenharmony_ci#if defined(CORE_USE_COMPILER_GENERATED_STATIC_LIST) && (CORE_USE_COMPILER_GENERATED_STATIC_LIST == 1)
508bf80f4bSopenharmony_ci
518bf80f4bSopenharmony_ci#if _MSC_VER
528bf80f4bSopenharmony_ci#pragma section("spd$b", long, read)
538bf80f4bSopenharmony_ci#pragma section("spd$d", long, read)
548bf80f4bSopenharmony_ci#pragma section("spd$e", long, read)
558bf80f4bSopenharmony_ci__declspec(allocate("spd$b")) static constexpr const IPlugin* g_staticPluginList = nullptr;
568bf80f4bSopenharmony_ci__declspec(allocate("spd$e")) static constexpr const IPlugin* g_staticPluginListEnd = nullptr;
578bf80f4bSopenharmony_ci#else
588bf80f4bSopenharmony_ci// clang-format off
598bf80f4bSopenharmony_ci__asm__(
608bf80f4bSopenharmony_ci    ".pushsection " SECTION(spl.1)
618bf80f4bSopenharmony_ci    " .local g_staticPluginList\n"
628bf80f4bSopenharmony_ci    " g_staticPluginList:\n"
638bf80f4bSopenharmony_ci    ".dc.a 0x0\n"
648bf80f4bSopenharmony_ci    ".section " SECTION(spl.2)
658bf80f4bSopenharmony_ci    " .local g_staticPluginListData\n"
668bf80f4bSopenharmony_ci    "g_staticPluginListData:\n"
678bf80f4bSopenharmony_ci    " .dc.a 0x0\n"
688bf80f4bSopenharmony_ci    " .section " SECTION(spl.3)
698bf80f4bSopenharmony_ci    " .local g_staticPluginListEnd\n"
708bf80f4bSopenharmony_ci    " g_staticPluginListEnd:\n"
718bf80f4bSopenharmony_ci    ".dc.a 0x0\n"
728bf80f4bSopenharmony_ci    " .popsection\n");
738bf80f4bSopenharmony_ci// clang-format on
748bf80f4bSopenharmony_ciextern "C" {
758bf80f4bSopenharmony_ciextern CORE_NS::IPlugin const* const g_staticPluginList;
768bf80f4bSopenharmony_ciextern CORE_NS::IPlugin const* const g_staticPluginListData;
778bf80f4bSopenharmony_ciextern CORE_NS::IPlugin const* const g_staticPluginListEnd;
788bf80f4bSopenharmony_ci__attribute__((used)) CORE_NS::IPlugin const* const g_staticPluginListDataRef = g_staticPluginListData;
798bf80f4bSopenharmony_ci}
808bf80f4bSopenharmony_ci#endif
818bf80f4bSopenharmony_ci
828bf80f4bSopenharmony_ci#else
838bf80f4bSopenharmony_ci
848bf80f4bSopenharmony_ci#if _MSC_VER
858bf80f4bSopenharmony_cistatic CORE_NS::IPlugin const* const* g_staticPluginList = nullptr;
868bf80f4bSopenharmony_cistatic size_t g_staticPluginListCount = 0;
878bf80f4bSopenharmony_ci#else
888bf80f4bSopenharmony_ci__attribute__((visibility("hidden"))) static CORE_NS::IPlugin const* const* g_staticPluginList = nullptr;
898bf80f4bSopenharmony_ci__attribute__((visibility("hidden"))) static size_t g_staticPluginListCount = 0;
908bf80f4bSopenharmony_ci#endif
918bf80f4bSopenharmony_ci
928bf80f4bSopenharmony_civoid RegisterStaticPlugin(const CORE_NS::IPlugin& plugin)
938bf80f4bSopenharmony_ci{
948bf80f4bSopenharmony_ci    static BASE_NS::vector<const CORE_NS::IPlugin*> gGlobalPlugins;
958bf80f4bSopenharmony_ci    gGlobalPlugins.push_back(&plugin);
968bf80f4bSopenharmony_ci    g_staticPluginList = gGlobalPlugins.data();
978bf80f4bSopenharmony_ci    g_staticPluginListCount = gGlobalPlugins.size();
988bf80f4bSopenharmony_ci}
998bf80f4bSopenharmony_ci#endif
1008bf80f4bSopenharmony_ci} // namespace StaticPluginRegistry
1018bf80f4bSopenharmony_ci
1028bf80f4bSopenharmony_cinamespace {
1038bf80f4bSopenharmony_cistruct LibPlugin {
1048bf80f4bSopenharmony_ci    ILibrary::Ptr lib;
1058bf80f4bSopenharmony_ci    const IPlugin* plugin;
1068bf80f4bSopenharmony_ci};
1078bf80f4bSopenharmony_ci
1088bf80f4bSopenharmony_citemplate<typename Container, typename Predicate>
1098bf80f4bSopenharmony_ciinline typename Container::const_iterator FindIf(const Container& container, Predicate&& predicate)
1108bf80f4bSopenharmony_ci{
1118bf80f4bSopenharmony_ci    return std::find_if(container.cbegin(), container.cend(), BASE_NS::forward<Predicate>(predicate));
1128bf80f4bSopenharmony_ci}
1138bf80f4bSopenharmony_ci
1148bf80f4bSopenharmony_citemplate<typename Container, typename Predicate>
1158bf80f4bSopenharmony_ciinline bool NoneOf(const Container& container, Predicate&& predicate)
1168bf80f4bSopenharmony_ci{
1178bf80f4bSopenharmony_ci    return std::none_of(container.cbegin(), container.cend(), BASE_NS::forward<Predicate>(predicate));
1188bf80f4bSopenharmony_ci}
1198bf80f4bSopenharmony_ci
1208bf80f4bSopenharmony_citemplate<typename Container, typename Predicate>
1218bf80f4bSopenharmony_ciinline bool AllOf(const Container& container, Predicate&& predicate)
1228bf80f4bSopenharmony_ci{
1238bf80f4bSopenharmony_ci    return std::all_of(container.cbegin(), container.cend(), BASE_NS::forward<Predicate>(predicate));
1248bf80f4bSopenharmony_ci}
1258bf80f4bSopenharmony_ci
1268bf80f4bSopenharmony_civoid GatherStaticPlugins(vector<LibPlugin>& plugins)
1278bf80f4bSopenharmony_ci{
1288bf80f4bSopenharmony_ci    CORE_LOG_V("Static plugins:");
1298bf80f4bSopenharmony_ci#if defined(CORE_USE_COMPILER_GENERATED_STATIC_LIST) && (CORE_USE_COMPILER_GENERATED_STATIC_LIST == 1)
1308bf80f4bSopenharmony_ci    const array_view<const IPlugin* const> staticPluginRegistry(
1318bf80f4bSopenharmony_ci        &StaticPluginRegistry::g_staticPluginList, &StaticPluginRegistry::g_staticPluginListEnd);
1328bf80f4bSopenharmony_ci#else
1338bf80f4bSopenharmony_ci    const array_view<const IPlugin* const> staticPluginRegistry(
1348bf80f4bSopenharmony_ci        StaticPluginRegistry::g_staticPluginList, StaticPluginRegistry::g_staticPluginListCount);
1358bf80f4bSopenharmony_ci#endif
1368bf80f4bSopenharmony_ci
1378bf80f4bSopenharmony_ci    for (const auto plugin : staticPluginRegistry) {
1388bf80f4bSopenharmony_ci        if (plugin && (plugin->typeUid == IPlugin::UID)) {
1398bf80f4bSopenharmony_ci            CORE_LOG_V("\t%s", plugin->name);
1408bf80f4bSopenharmony_ci            plugins.push_back({ nullptr, plugin });
1418bf80f4bSopenharmony_ci        }
1428bf80f4bSopenharmony_ci    }
1438bf80f4bSopenharmony_ci}
1448bf80f4bSopenharmony_ci
1458bf80f4bSopenharmony_civoid GatherDynamicPlugins(vector<LibPlugin>& plugins, IFileManager& fileManager)
1468bf80f4bSopenharmony_ci{
1478bf80f4bSopenharmony_ci    CORE_LOG_V("Dynamic plugins:");
1488bf80f4bSopenharmony_ci    const auto libraryFileExtension = ILibrary::GetFileExtension();
1498bf80f4bSopenharmony_ci    constexpr string_view pluginRoot { "plugins://" };
1508bf80f4bSopenharmony_ci    if (IDirectory::Ptr pluginFiles = fileManager.OpenDirectory(pluginRoot); pluginFiles) {
1518bf80f4bSopenharmony_ci        for (const auto& file : pluginFiles->GetEntries()) {
1528bf80f4bSopenharmony_ci            const string_view pluginFile = file.name;
1538bf80f4bSopenharmony_ci            if (pluginFile.ends_with(libraryFileExtension)) {
1548bf80f4bSopenharmony_ci                const string absoluteFile = fileManager.GetEntry(pluginRoot + file.name).name;
1558bf80f4bSopenharmony_ci                if (ILibrary::Ptr lib = ILibrary::Load(absoluteFile); lib) {
1568bf80f4bSopenharmony_ci                    const IPlugin* plugin = lib->GetPlugin();
1578bf80f4bSopenharmony_ci                    if (plugin && (plugin->typeUid == IPlugin::UID)) {
1588bf80f4bSopenharmony_ci                        CORE_LOG_V("\t%s", plugin->name);
1598bf80f4bSopenharmony_ci                        plugins.push_back({ move(lib), plugin });
1608bf80f4bSopenharmony_ci                    }
1618bf80f4bSopenharmony_ci                }
1628bf80f4bSopenharmony_ci            }
1638bf80f4bSopenharmony_ci        }
1648bf80f4bSopenharmony_ci    }
1658bf80f4bSopenharmony_ci}
1668bf80f4bSopenharmony_ci
1678bf80f4bSopenharmony_civoid Notify(const array_view<IPluginRegister::ITypeInfoListener*> listeners,
1688bf80f4bSopenharmony_ci    IPluginRegister::ITypeInfoListener::EventType type, array_view<const ITypeInfo* const> typeInfos)
1698bf80f4bSopenharmony_ci{
1708bf80f4bSopenharmony_ci    for (IPluginRegister::ITypeInfoListener* listener : listeners) {
1718bf80f4bSopenharmony_ci        if (listener) {
1728bf80f4bSopenharmony_ci            listener->OnTypeInfoEvent(type, typeInfos);
1738bf80f4bSopenharmony_ci        }
1748bf80f4bSopenharmony_ci    }
1758bf80f4bSopenharmony_ci}
1768bf80f4bSopenharmony_cistatic constexpr CORE_NS::IImageLoaderManager::ImageLoaderTypeInfo KTX_LOADER {
1778bf80f4bSopenharmony_ci    { CORE_NS::IImageLoaderManager::ImageLoaderTypeInfo::UID },
1788bf80f4bSopenharmony_ci    nullptr,
1798bf80f4bSopenharmony_ci    BASE_NS::Uid { "306357a4-d49c-4670-9746-5ccbba567dc9" },
1808bf80f4bSopenharmony_ci    CreateImageLoaderKtx,
1818bf80f4bSopenharmony_ci    KTX_IMAGE_TYPES,
1828bf80f4bSopenharmony_ci};
1838bf80f4bSopenharmony_cistatic constexpr CORE_NS::IImageLoaderManager::ImageLoaderTypeInfo STB_LOADER {
1848bf80f4bSopenharmony_ci    { CORE_NS::IImageLoaderManager::ImageLoaderTypeInfo::UID },
1858bf80f4bSopenharmony_ci    nullptr,
1868bf80f4bSopenharmony_ci    BASE_NS::Uid { "a5049cb8-10bb-4047-b7f5-e9939d5bb3a5" },
1878bf80f4bSopenharmony_ci    CreateImageLoaderStbImage,
1888bf80f4bSopenharmony_ci    STB_IMAGE_TYPES,
1898bf80f4bSopenharmony_ci};
1908bf80f4bSopenharmony_cistatic constexpr CORE_NS::IImageLoaderManager::ImageLoaderTypeInfo PNG_LOADER {
1918bf80f4bSopenharmony_ci    { CORE_NS::IImageLoaderManager::ImageLoaderTypeInfo::UID },
1928bf80f4bSopenharmony_ci    nullptr,
1938bf80f4bSopenharmony_ci    BASE_NS::Uid { "dacbcb8d-60d6-4337-8295-7af99b517c1d" },
1948bf80f4bSopenharmony_ci    CreateImageLoaderLibPNGImage,
1958bf80f4bSopenharmony_ci    PNG_IMAGE_TYPES,
1968bf80f4bSopenharmony_ci};
1978bf80f4bSopenharmony_cistatic constexpr CORE_NS::IImageLoaderManager::ImageLoaderTypeInfo JPEG_LOADER {
1988bf80f4bSopenharmony_ci    { CORE_NS::IImageLoaderManager::ImageLoaderTypeInfo::UID },
1998bf80f4bSopenharmony_ci    nullptr,
2008bf80f4bSopenharmony_ci    BASE_NS::Uid { "c5fb2284-561f-4078-8a00-74b82f161964" },
2018bf80f4bSopenharmony_ci    CreateImageLoaderLibJPEGImage,
2028bf80f4bSopenharmony_ci    JPEG_IMAGE_TYPES,
2038bf80f4bSopenharmony_ci};
2048bf80f4bSopenharmony_ci} // namespace
2058bf80f4bSopenharmony_ci
2068bf80f4bSopenharmony_civector<InterfaceTypeInfo> PluginRegistry::RegisterGlobalInterfaces(PluginRegistry& registry)
2078bf80f4bSopenharmony_ci{
2088bf80f4bSopenharmony_ci    vector<InterfaceTypeInfo> interfaces = {
2098bf80f4bSopenharmony_ci        InterfaceTypeInfo { &registry, UID_LOGGER, GetName<ILogger>().data(), nullptr,
2108bf80f4bSopenharmony_ci            [](IClassRegister& /* registry */, PluginToken token) -> IInterface* {
2118bf80f4bSopenharmony_ci                return &static_cast<PluginRegistry*>(token)->logger_;
2128bf80f4bSopenharmony_ci            } },
2138bf80f4bSopenharmony_ci        InterfaceTypeInfo { &registry, UID_FRUSTUM_UTIL, GetName<IFrustumUtil>().data(), nullptr,
2148bf80f4bSopenharmony_ci            [](IClassRegister& /* registry */, PluginToken token) -> IInterface* {
2158bf80f4bSopenharmony_ci                return &static_cast<PluginRegistry*>(token)->frustumUtil_;
2168bf80f4bSopenharmony_ci            } },
2178bf80f4bSopenharmony_ci        InterfaceTypeInfo { &registry, UID_ENGINE_FACTORY, GetName<IEngineFactory>().data(), nullptr,
2188bf80f4bSopenharmony_ci            [](IClassRegister& /* registry */, PluginToken token) -> IInterface* {
2198bf80f4bSopenharmony_ci                return static_cast<PluginRegistry*>(token)->engineFactory_.GetInterface(IEngineFactory::UID);
2208bf80f4bSopenharmony_ci            } },
2218bf80f4bSopenharmony_ci        InterfaceTypeInfo { &registry, UID_SYSTEM_GRAPH_LOADER, GetName<ISystemGraphLoaderFactory>().data(), nullptr,
2228bf80f4bSopenharmony_ci            [](IClassRegister& /* registry */, PluginToken token) -> IInterface* {
2238bf80f4bSopenharmony_ci                return &static_cast<PluginRegistry*>(token)->systemGraphLoadeFactory;
2248bf80f4bSopenharmony_ci            } },
2258bf80f4bSopenharmony_ci        InterfaceTypeInfo { &registry, UID_GLOBAL_FACTORY, "Global registry factory", nullptr,
2268bf80f4bSopenharmony_ci            [](IClassRegister& registry, PluginToken /* token */) -> IInterface* {
2278bf80f4bSopenharmony_ci                return registry.GetInterface<IClassFactory>();
2288bf80f4bSopenharmony_ci            } },
2298bf80f4bSopenharmony_ci        InterfaceTypeInfo {
2308bf80f4bSopenharmony_ci            &registry, UID_FILESYSTEM_API_FACTORY, "Filesystem API factory", nullptr, GetFileApiFactory },
2318bf80f4bSopenharmony_ci        InterfaceTypeInfo { &registry, UID_FILE_MONITOR, "Filemonitor", CreateFileMonitor, nullptr },
2328bf80f4bSopenharmony_ci        InterfaceTypeInfo { &registry, UID_FILE_MANAGER, "FileManager",
2338bf80f4bSopenharmony_ci            [](IClassFactory& /* factory */, PluginToken /* token */) -> IInterface* {
2348bf80f4bSopenharmony_ci                return new CORE_NS::FileManager();
2358bf80f4bSopenharmony_ci            },
2368bf80f4bSopenharmony_ci            nullptr },
2378bf80f4bSopenharmony_ci        InterfaceTypeInfo { &registry, UID_TASK_QUEUE_FACTORY, "Task queue factory", nullptr,
2388bf80f4bSopenharmony_ci            [](IClassRegister& /* registry */, PluginToken token) -> IInterface* {
2398bf80f4bSopenharmony_ci                return &static_cast<PluginRegistry*>(token)->taskQueueFactory_;
2408bf80f4bSopenharmony_ci            } },
2418bf80f4bSopenharmony_ci#if (CORE_PERF_ENABLED == 1)
2428bf80f4bSopenharmony_ci        InterfaceTypeInfo { &registry, UID_PERFORMANCE_FACTORY, GetName<IPerformanceDataManagerFactory>().data(),
2438bf80f4bSopenharmony_ci            nullptr,
2448bf80f4bSopenharmony_ci            [](IClassRegister& /* registry */, PluginToken token) -> IInterface* {
2458bf80f4bSopenharmony_ci                return &static_cast<PluginRegistry*>(token)->perfManFactory_;
2468bf80f4bSopenharmony_ci            } }
2478bf80f4bSopenharmony_ci#endif
2488bf80f4bSopenharmony_ci    };
2498bf80f4bSopenharmony_ci
2508bf80f4bSopenharmony_ci    for (const auto& info : interfaces) {
2518bf80f4bSopenharmony_ci        registry.RegisterInterfaceType(info);
2528bf80f4bSopenharmony_ci    }
2538bf80f4bSopenharmony_ci    registry.RegisterTypeInfo(KTX_LOADER);
2548bf80f4bSopenharmony_ci    registry.RegisterTypeInfo(STB_LOADER);
2558bf80f4bSopenharmony_ci    registry.RegisterTypeInfo(PNG_LOADER);
2568bf80f4bSopenharmony_ci    registry.RegisterTypeInfo(JPEG_LOADER);
2578bf80f4bSopenharmony_ci    return interfaces;
2588bf80f4bSopenharmony_ci}
2598bf80f4bSopenharmony_ci
2608bf80f4bSopenharmony_civoid PluginRegistry::UnregisterGlobalInterfaces()
2618bf80f4bSopenharmony_ci{
2628bf80f4bSopenharmony_ci    UnregisterTypeInfo(STB_LOADER);
2638bf80f4bSopenharmony_ci    UnregisterTypeInfo(KTX_LOADER);
2648bf80f4bSopenharmony_ci    UnregisterTypeInfo(PNG_LOADER);
2658bf80f4bSopenharmony_ci    UnregisterTypeInfo(JPEG_LOADER);
2668bf80f4bSopenharmony_ci    for (const auto& info : ownInterfaceInfos_) {
2678bf80f4bSopenharmony_ci        UnregisterInterfaceType(info);
2688bf80f4bSopenharmony_ci    }
2698bf80f4bSopenharmony_ci}
2708bf80f4bSopenharmony_ci
2718bf80f4bSopenharmony_ciPluginRegistry::PluginRegistry()
2728bf80f4bSopenharmony_ci{
2738bf80f4bSopenharmony_ci    ownInterfaceInfos_ = RegisterGlobalInterfaces(*this);
2748bf80f4bSopenharmony_ci}
2758bf80f4bSopenharmony_ci
2768bf80f4bSopenharmony_ciPluginRegistry::~PluginRegistry()
2778bf80f4bSopenharmony_ci{
2788bf80f4bSopenharmony_ci    UnloadPlugins({});
2798bf80f4bSopenharmony_ci    UnregisterGlobalInterfaces();
2808bf80f4bSopenharmony_ci}
2818bf80f4bSopenharmony_ci
2828bf80f4bSopenharmony_ci// IPluginRegister
2838bf80f4bSopenharmony_ciarray_view<const IPlugin* const> PluginRegistry::GetPlugins() const
2848bf80f4bSopenharmony_ci{
2858bf80f4bSopenharmony_ci    return plugins_;
2868bf80f4bSopenharmony_ci}
2878bf80f4bSopenharmony_ci
2888bf80f4bSopenharmony_cibool PluginRegistry::LoadPlugins(const array_view<const Uid> pluginUids)
2898bf80f4bSopenharmony_ci{
2908bf80f4bSopenharmony_ci    // Gather all the available static and dynamic libraries.
2918bf80f4bSopenharmony_ci    vector<LibPlugin> plugins;
2928bf80f4bSopenharmony_ci    GatherStaticPlugins(plugins);
2938bf80f4bSopenharmony_ci    GatherDynamicPlugins(plugins, fileManager_);
2948bf80f4bSopenharmony_ci
2958bf80f4bSopenharmony_ci    // If a list of UIDs was given remove all except the requires plugins.
2968bf80f4bSopenharmony_ci    if (!pluginUids.empty()) {
2978bf80f4bSopenharmony_ci        // Gather dependencies of each plugin.
2988bf80f4bSopenharmony_ci        vector<Uid> toLoad;
2998bf80f4bSopenharmony_ci        toLoad.reserve(plugins.size());
3008bf80f4bSopenharmony_ci
3018bf80f4bSopenharmony_ci        auto addDependencies = [](auto&& addDependencies, vector<Uid>& toBeLoaded,
3028bf80f4bSopenharmony_ci                                   const vector<LibPlugin>& availablePlugins,
3038bf80f4bSopenharmony_ci                                   BASE_NS::vector<const IPlugin*>& loadedPlugins, const Uid& uidToLoad) -> bool {
3048bf80f4bSopenharmony_ci            bool found = true;
3058bf80f4bSopenharmony_ci            // Only consider plugins which are not already loaded, and not yet in the loading list.
3068bf80f4bSopenharmony_ci            if (NoneOf(
3078bf80f4bSopenharmony_ci                    loadedPlugins, [&uidToLoad](const IPlugin* loaded) { return loaded->version.uid == uidToLoad; }) &&
3088bf80f4bSopenharmony_ci                NoneOf(toBeLoaded, [&uidToLoad](const Uid& willLoad) { return willLoad == uidToLoad; })) {
3098bf80f4bSopenharmony_ci                if (auto pos = FindIf(availablePlugins,
3108bf80f4bSopenharmony_ci                        [&uidToLoad](
3118bf80f4bSopenharmony_ci                            const LibPlugin& libPlugin) { return libPlugin.plugin->version.uid == uidToLoad; });
3128bf80f4bSopenharmony_ci                    pos != availablePlugins.end()) {
3138bf80f4bSopenharmony_ci                    found = AllOf(pos->plugin->pluginDependencies, [&](const Uid& dependency) {
3148bf80f4bSopenharmony_ci                        return addDependencies(
3158bf80f4bSopenharmony_ci                            addDependencies, toBeLoaded, availablePlugins, loadedPlugins, dependency);
3168bf80f4bSopenharmony_ci                    });
3178bf80f4bSopenharmony_ci                    if (found) {
3188bf80f4bSopenharmony_ci                        toBeLoaded.push_back(uidToLoad);
3198bf80f4bSopenharmony_ci                    } else {
3208bf80f4bSopenharmony_ci                        CORE_LOG_E("Missing dependencies for: %s", to_string(uidToLoad).data());
3218bf80f4bSopenharmony_ci                    }
3228bf80f4bSopenharmony_ci                } else {
3238bf80f4bSopenharmony_ci                    CORE_LOG_E("Plugin not found: %s", to_string(uidToLoad).data());
3248bf80f4bSopenharmony_ci                    found = false;
3258bf80f4bSopenharmony_ci                }
3268bf80f4bSopenharmony_ci            }
3278bf80f4bSopenharmony_ci            return found;
3288bf80f4bSopenharmony_ci        };
3298bf80f4bSopenharmony_ci        const bool found = AllOf(pluginUids,
3308bf80f4bSopenharmony_ci            [&](const Uid& uid) { return addDependencies(addDependencies, toLoad, plugins, plugins_, uid); });
3318bf80f4bSopenharmony_ci
3328bf80f4bSopenharmony_ci        // Order the available plugins to match the to-be-loaded list and remove extras.
3338bf80f4bSopenharmony_ci        auto begin = plugins.begin();
3348bf80f4bSopenharmony_ci        auto end = plugins.end();
3358bf80f4bSopenharmony_ci        for (const Uid& uid : toLoad) {
3368bf80f4bSopenharmony_ci            if (auto pos = std::find_if(
3378bf80f4bSopenharmony_ci                    begin, end, [uid](const LibPlugin& libPlugin) { return libPlugin.plugin->version.uid == uid; });
3388bf80f4bSopenharmony_ci                pos != end) {
3398bf80f4bSopenharmony_ci                std::rotate(begin, pos, end);
3408bf80f4bSopenharmony_ci                ++begin;
3418bf80f4bSopenharmony_ci            }
3428bf80f4bSopenharmony_ci        }
3438bf80f4bSopenharmony_ci        plugins.erase(begin, end);
3448bf80f4bSopenharmony_ci
3458bf80f4bSopenharmony_ci        if (!found) {
3468bf80f4bSopenharmony_ci            CORE_LOG_E("Unable to load plugins:");
3478bf80f4bSopenharmony_ci            for (const auto& uid : pluginUids) {
3488bf80f4bSopenharmony_ci                if (NoneOf(plugins, [uid](const auto& available) { return available.plugin->version.uid == uid; })) {
3498bf80f4bSopenharmony_ci                    CORE_LOG_E("\t%s", to_string(uid).data());
3508bf80f4bSopenharmony_ci                }
3518bf80f4bSopenharmony_ci            }
3528bf80f4bSopenharmony_ci            return false;
3538bf80f4bSopenharmony_ci        }
3548bf80f4bSopenharmony_ci    }
3558bf80f4bSopenharmony_ci
3568bf80f4bSopenharmony_ci    // Now we should have only the desired plugins and can load all of them.
3578bf80f4bSopenharmony_ci    CORE_LOG_D("Load plugins:");
3588bf80f4bSopenharmony_ci    loading_ = true;
3598bf80f4bSopenharmony_ci    for (auto& plugin : plugins) {
3608bf80f4bSopenharmony_ci        RegisterPlugin(move(plugin.lib), *plugin.plugin,
3618bf80f4bSopenharmony_ci            NoneOf(pluginUids,
3628bf80f4bSopenharmony_ci                [&loading = (plugin.plugin->version.uid)](const Uid& userRequest) { return userRequest == loading; }));
3638bf80f4bSopenharmony_ci    }
3648bf80f4bSopenharmony_ci    loading_ = false;
3658bf80f4bSopenharmony_ci
3668bf80f4bSopenharmony_ci    if (!newTypeInfos_.empty()) {
3678bf80f4bSopenharmony_ci        Notify(typeInfoListeners_, ITypeInfoListener::EventType::ADDED, newTypeInfos_);
3688bf80f4bSopenharmony_ci        newTypeInfos_.clear();
3698bf80f4bSopenharmony_ci    }
3708bf80f4bSopenharmony_ci
3718bf80f4bSopenharmony_ci    return true;
3728bf80f4bSopenharmony_ci}
3738bf80f4bSopenharmony_ci
3748bf80f4bSopenharmony_civoid PluginRegistry::UnloadPlugins(const array_view<const Uid> pluginUids)
3758bf80f4bSopenharmony_ci{
3768bf80f4bSopenharmony_ci    CORE_LOG_D("Unload plugins:");
3778bf80f4bSopenharmony_ci    if (pluginUids.empty()) {
3788bf80f4bSopenharmony_ci        while (!pluginDatas_.empty() && !plugins_.empty()) {
3798bf80f4bSopenharmony_ci            UnregisterPlugin(*plugins_.back(), pluginDatas_.back().token);
3808bf80f4bSopenharmony_ci            plugins_.pop_back();
3818bf80f4bSopenharmony_ci            pluginDatas_.pop_back();
3828bf80f4bSopenharmony_ci        }
3838bf80f4bSopenharmony_ci        plugins_.clear();
3848bf80f4bSopenharmony_ci        pluginDatas_.clear();
3858bf80f4bSopenharmony_ci    } else {
3868bf80f4bSopenharmony_ci        [](array_view<const IPlugin*> plugins, array_view<PluginData> pluginDatas,
3878bf80f4bSopenharmony_ci            const array_view<const Uid>& pluginUids) {
3888bf80f4bSopenharmony_ci            auto recurse = [](const array_view<const IPlugin*>& plugins, array_view<PluginData>& pluginDatas,
3898bf80f4bSopenharmony_ci                               const array_view<const Uid>& pluginUids, auto& recurseRef) -> void {
3908bf80f4bSopenharmony_ci                for (const auto& uid : pluginUids) {
3918bf80f4bSopenharmony_ci                    if (auto pos = std::find_if(plugins.begin(), plugins.end(),
3928bf80f4bSopenharmony_ci                            [uid](const IPlugin* pl) { return pl && pl->version.uid == uid; });
3938bf80f4bSopenharmony_ci                        pos != plugins.end()) {
3948bf80f4bSopenharmony_ci                        const auto index = static_cast<size_t>(std::distance(plugins.begin(), pos));
3958bf80f4bSopenharmony_ci                        if (--pluginDatas[index].refcnt <= 0) {
3968bf80f4bSopenharmony_ci                            recurseRef(plugins, pluginDatas, (*pos)->pluginDependencies, recurseRef);
3978bf80f4bSopenharmony_ci                        }
3988bf80f4bSopenharmony_ci                    }
3998bf80f4bSopenharmony_ci                }
4008bf80f4bSopenharmony_ci            };
4018bf80f4bSopenharmony_ci            recurse(plugins, pluginDatas, pluginUids, recurse);
4028bf80f4bSopenharmony_ci        }(plugins_, pluginDatas_, pluginUids);
4038bf80f4bSopenharmony_ci
4048bf80f4bSopenharmony_ci        auto pdIt = pluginDatas_.crbegin();
4058bf80f4bSopenharmony_ci        for (auto pos = plugins_.crbegin(), last = plugins_.crend(); pos != last;) {
4068bf80f4bSopenharmony_ci            if (pdIt->refcnt <= 0) {
4078bf80f4bSopenharmony_ci                UnregisterPlugin(*(*pos), pdIt->token);
4088bf80f4bSopenharmony_ci                plugins_.erase(pos.base() - 1);
4098bf80f4bSopenharmony_ci                pluginDatas_.erase(pdIt.base() - 1);
4108bf80f4bSopenharmony_ci            }
4118bf80f4bSopenharmony_ci            ++pos;
4128bf80f4bSopenharmony_ci            ++pdIt;
4138bf80f4bSopenharmony_ci        }
4148bf80f4bSopenharmony_ci    }
4158bf80f4bSopenharmony_ci}
4168bf80f4bSopenharmony_ci
4178bf80f4bSopenharmony_ciIClassRegister& PluginRegistry::GetClassRegister() const
4188bf80f4bSopenharmony_ci{
4198bf80f4bSopenharmony_ci    return *const_cast<PluginRegistry*>(this);
4208bf80f4bSopenharmony_ci}
4218bf80f4bSopenharmony_ci
4228bf80f4bSopenharmony_civoid PluginRegistry::RegisterTypeInfo(const ITypeInfo& type)
4238bf80f4bSopenharmony_ci{
4248bf80f4bSopenharmony_ci    if (const auto pos = typeInfos_.find(type.typeUid); pos != typeInfos_.cend()) {
4258bf80f4bSopenharmony_ci        pos->second.push_back(&type);
4268bf80f4bSopenharmony_ci    } else {
4278bf80f4bSopenharmony_ci        typeInfos_.insert({ type.typeUid, {} }).first->second.push_back(&type);
4288bf80f4bSopenharmony_ci    }
4298bf80f4bSopenharmony_ci
4308bf80f4bSopenharmony_ci    // During plugin loading gather all the infos and send events once.
4318bf80f4bSopenharmony_ci    if (loading_) {
4328bf80f4bSopenharmony_ci        newTypeInfos_.push_back(&type);
4338bf80f4bSopenharmony_ci    } else {
4348bf80f4bSopenharmony_ci        const ITypeInfo* const infos[] = { &type };
4358bf80f4bSopenharmony_ci        Notify(typeInfoListeners_, ITypeInfoListener::EventType::ADDED, infos);
4368bf80f4bSopenharmony_ci    }
4378bf80f4bSopenharmony_ci}
4388bf80f4bSopenharmony_ci
4398bf80f4bSopenharmony_civoid PluginRegistry::UnregisterTypeInfo(const ITypeInfo& type)
4408bf80f4bSopenharmony_ci{
4418bf80f4bSopenharmony_ci    if (const auto typeInfos = typeInfos_.find(type.typeUid); typeInfos != typeInfos_.cend()) {
4428bf80f4bSopenharmony_ci        auto& infos = typeInfos->second;
4438bf80f4bSopenharmony_ci        if (const auto info = std::find(infos.cbegin(), infos.cend(), &type); info != infos.cend()) {
4448bf80f4bSopenharmony_ci            infos.erase(info);
4458bf80f4bSopenharmony_ci        }
4468bf80f4bSopenharmony_ci    }
4478bf80f4bSopenharmony_ci
4488bf80f4bSopenharmony_ci    const ITypeInfo* const infos[] = { &type };
4498bf80f4bSopenharmony_ci    Notify(typeInfoListeners_, ITypeInfoListener::EventType::REMOVED, infos);
4508bf80f4bSopenharmony_ci}
4518bf80f4bSopenharmony_ci
4528bf80f4bSopenharmony_ciarray_view<const ITypeInfo* const> PluginRegistry::GetTypeInfos(const Uid& typeUid) const
4538bf80f4bSopenharmony_ci{
4548bf80f4bSopenharmony_ci    if (const auto typeInfos = typeInfos_.find(typeUid); typeInfos != typeInfos_.cend()) {
4558bf80f4bSopenharmony_ci        return typeInfos->second;
4568bf80f4bSopenharmony_ci    }
4578bf80f4bSopenharmony_ci    return {};
4588bf80f4bSopenharmony_ci}
4598bf80f4bSopenharmony_ci
4608bf80f4bSopenharmony_civoid PluginRegistry::AddListener(ITypeInfoListener& listener)
4618bf80f4bSopenharmony_ci{
4628bf80f4bSopenharmony_ci    if (std::none_of(typeInfoListeners_.begin(), typeInfoListeners_.end(),
4638bf80f4bSopenharmony_ci            [adding = &listener](const auto& current) { return current == adding; })) {
4648bf80f4bSopenharmony_ci        typeInfoListeners_.push_back(&listener);
4658bf80f4bSopenharmony_ci    }
4668bf80f4bSopenharmony_ci}
4678bf80f4bSopenharmony_ci
4688bf80f4bSopenharmony_civoid PluginRegistry::RemoveListener(const ITypeInfoListener& listener)
4698bf80f4bSopenharmony_ci{
4708bf80f4bSopenharmony_ci    if (auto pos = std::find(typeInfoListeners_.begin(), typeInfoListeners_.end(), &listener);
4718bf80f4bSopenharmony_ci        pos != typeInfoListeners_.end()) {
4728bf80f4bSopenharmony_ci        *pos = nullptr;
4738bf80f4bSopenharmony_ci    }
4748bf80f4bSopenharmony_ci}
4758bf80f4bSopenharmony_ci
4768bf80f4bSopenharmony_ci// IClassRegister
4778bf80f4bSopenharmony_civoid PluginRegistry::RegisterInterfaceType(const InterfaceTypeInfo& interfaceInfo)
4788bf80f4bSopenharmony_ci{
4798bf80f4bSopenharmony_ci    // keep interfaceTypeInfos_ sorted according to UIDs
4808bf80f4bSopenharmony_ci    const auto pos = std::upper_bound(interfaceTypeInfos_.cbegin(), interfaceTypeInfos_.cend(), interfaceInfo.uid,
4818bf80f4bSopenharmony_ci        [](Uid value, const InterfaceTypeInfo* element) { return value < element->uid; });
4828bf80f4bSopenharmony_ci    interfaceTypeInfos_.insert(pos, &interfaceInfo);
4838bf80f4bSopenharmony_ci}
4848bf80f4bSopenharmony_ci
4858bf80f4bSopenharmony_civoid PluginRegistry::UnregisterInterfaceType(const InterfaceTypeInfo& interfaceInfo)
4868bf80f4bSopenharmony_ci{
4878bf80f4bSopenharmony_ci    if (!interfaceTypeInfos_.empty()) {
4888bf80f4bSopenharmony_ci        const auto pos = std::lower_bound(interfaceTypeInfos_.cbegin(), interfaceTypeInfos_.cend(), interfaceInfo.uid,
4898bf80f4bSopenharmony_ci            [](const InterfaceTypeInfo* element, Uid value) { return element->uid < value; });
4908bf80f4bSopenharmony_ci        if ((pos != interfaceTypeInfos_.cend()) && (*pos)->uid == interfaceInfo.uid) {
4918bf80f4bSopenharmony_ci            interfaceTypeInfos_.erase(pos);
4928bf80f4bSopenharmony_ci        }
4938bf80f4bSopenharmony_ci    }
4948bf80f4bSopenharmony_ci}
4958bf80f4bSopenharmony_ci
4968bf80f4bSopenharmony_ciarray_view<const InterfaceTypeInfo* const> PluginRegistry::GetInterfaceMetadata() const
4978bf80f4bSopenharmony_ci{
4988bf80f4bSopenharmony_ci    return { interfaceTypeInfos_.data(), interfaceTypeInfos_.size() };
4998bf80f4bSopenharmony_ci}
5008bf80f4bSopenharmony_ci
5018bf80f4bSopenharmony_ciconst InterfaceTypeInfo& PluginRegistry::GetInterfaceMetadata(const Uid& uid) const
5028bf80f4bSopenharmony_ci{
5038bf80f4bSopenharmony_ci    static constexpr InterfaceTypeInfo invalidType {};
5048bf80f4bSopenharmony_ci
5058bf80f4bSopenharmony_ci    if (!interfaceTypeInfos_.empty()) {
5068bf80f4bSopenharmony_ci        const auto pos = std::lower_bound(interfaceTypeInfos_.cbegin(), interfaceTypeInfos_.cend(), uid,
5078bf80f4bSopenharmony_ci            [](const InterfaceTypeInfo* element, Uid value) { return element->uid < value; });
5088bf80f4bSopenharmony_ci        if ((pos != interfaceTypeInfos_.cend()) && (*pos)->uid == uid) {
5098bf80f4bSopenharmony_ci            return *(*pos);
5108bf80f4bSopenharmony_ci        }
5118bf80f4bSopenharmony_ci    }
5128bf80f4bSopenharmony_ci    return invalidType;
5138bf80f4bSopenharmony_ci}
5148bf80f4bSopenharmony_ci
5158bf80f4bSopenharmony_ciIInterface* PluginRegistry::GetInstance(const Uid& uid) const
5168bf80f4bSopenharmony_ci{
5178bf80f4bSopenharmony_ci    const auto& data = GetInterfaceMetadata(uid);
5188bf80f4bSopenharmony_ci    if (data.getInterface) {
5198bf80f4bSopenharmony_ci        return data.getInterface(const_cast<PluginRegistry&>(*this), data.token);
5208bf80f4bSopenharmony_ci    }
5218bf80f4bSopenharmony_ci    return nullptr;
5228bf80f4bSopenharmony_ci}
5238bf80f4bSopenharmony_ci
5248bf80f4bSopenharmony_ci// IClassFactory
5258bf80f4bSopenharmony_ciIInterface::Ptr PluginRegistry::CreateInstance(const Uid& uid)
5268bf80f4bSopenharmony_ci{
5278bf80f4bSopenharmony_ci    const auto& data = GetInterfaceMetadata(uid);
5288bf80f4bSopenharmony_ci    if (data.createInterface) {
5298bf80f4bSopenharmony_ci        return IInterface::Ptr { data.createInterface(*this, data.token) };
5308bf80f4bSopenharmony_ci    }
5318bf80f4bSopenharmony_ci    return {};
5328bf80f4bSopenharmony_ci}
5338bf80f4bSopenharmony_ci
5348bf80f4bSopenharmony_ci// IInterface
5358bf80f4bSopenharmony_ciconst IInterface* PluginRegistry::GetInterface(const Uid& uid) const
5368bf80f4bSopenharmony_ci{
5378bf80f4bSopenharmony_ci    return const_cast<PluginRegistry*>(this)->GetInterface(uid);
5388bf80f4bSopenharmony_ci}
5398bf80f4bSopenharmony_ci
5408bf80f4bSopenharmony_ciIInterface* PluginRegistry::GetInterface(const Uid& uid)
5418bf80f4bSopenharmony_ci{
5428bf80f4bSopenharmony_ci    if ((uid == IInterface::UID) || (uid == IClassRegister::UID)) {
5438bf80f4bSopenharmony_ci        return static_cast<IClassRegister*>(this);
5448bf80f4bSopenharmony_ci    }
5458bf80f4bSopenharmony_ci    if (uid == IClassFactory::UID) {
5468bf80f4bSopenharmony_ci        return static_cast<IClassFactory*>(this);
5478bf80f4bSopenharmony_ci    }
5488bf80f4bSopenharmony_ci    return nullptr;
5498bf80f4bSopenharmony_ci}
5508bf80f4bSopenharmony_ci
5518bf80f4bSopenharmony_civoid PluginRegistry::Ref() {}
5528bf80f4bSopenharmony_ci
5538bf80f4bSopenharmony_civoid PluginRegistry::Unref() {}
5548bf80f4bSopenharmony_ci
5558bf80f4bSopenharmony_ci// Public members
5568bf80f4bSopenharmony_civoid PluginRegistry::RegisterPluginPath(const string_view path)
5578bf80f4bSopenharmony_ci{
5588bf80f4bSopenharmony_ci    if (!fileProtocolRegistered_) {
5598bf80f4bSopenharmony_ci        fileProtocolRegistered_ = true;
5608bf80f4bSopenharmony_ci        fileManager_.RegisterFilesystem("file", IFilesystem::Ptr { new StdFilesystem("/") });
5618bf80f4bSopenharmony_ci    }
5628bf80f4bSopenharmony_ci    fileManager_.RegisterPath("plugins", path, false);
5638bf80f4bSopenharmony_ci}
5648bf80f4bSopenharmony_ci
5658bf80f4bSopenharmony_ciIFileManager& PluginRegistry::GetFileManager()
5668bf80f4bSopenharmony_ci{
5678bf80f4bSopenharmony_ci    return fileManager_;
5688bf80f4bSopenharmony_ci}
5698bf80f4bSopenharmony_ci
5708bf80f4bSopenharmony_ci// Private members
5718bf80f4bSopenharmony_civoid PluginRegistry::RegisterPlugin(ILibrary::Ptr lib, const IPlugin& plugin, bool asDependency)
5728bf80f4bSopenharmony_ci{
5738bf80f4bSopenharmony_ci    CORE_LOG_D("\tRegister Plugin: %s %s", plugin.name, to_string(plugin.version.uid).data());
5748bf80f4bSopenharmony_ci    if (plugin.version.GetVersionString) {
5758bf80f4bSopenharmony_ci        CORE_LOG_D("\tVersion Info: %s", plugin.version.GetVersionString());
5768bf80f4bSopenharmony_ci    }
5778bf80f4bSopenharmony_ci    if (std::any_of(plugins_.begin(), plugins_.end(),
5788bf80f4bSopenharmony_ci            [&plugin](const IPlugin* pl) { return strcmp(plugin.name, pl->name) == 0; })) {
5798bf80f4bSopenharmony_ci        CORE_LOG_W("\tSkipping duplicate plugin: %s!", plugin.name);
5808bf80f4bSopenharmony_ci        return;
5818bf80f4bSopenharmony_ci    }
5828bf80f4bSopenharmony_ci    // when a plugin is loaded/ registered due a requested plugin depends on it ref count starts from zero and it's
5838bf80f4bSopenharmony_ci    // expected that some following plugin will place a reference. once that plugin releases its reference the
5848bf80f4bSopenharmony_ci    // dependency is known to be a candidate for unloading.
5858bf80f4bSopenharmony_ci    PluginData pd { move(lib), {}, asDependency ? 0 : 1 };
5868bf80f4bSopenharmony_ci    if (plugin.registerInterfaces) {
5878bf80f4bSopenharmony_ci        pd.token = plugin.registerInterfaces(*static_cast<IPluginRegister*>(this));
5888bf80f4bSopenharmony_ci    }
5898bf80f4bSopenharmony_ci
5908bf80f4bSopenharmony_ci    pluginDatas_.push_back(move(pd));
5918bf80f4bSopenharmony_ci    plugins_.push_back(&plugin);
5928bf80f4bSopenharmony_ci    for (const auto& dependency : plugin.pluginDependencies) {
5938bf80f4bSopenharmony_ci        if (auto pos = std::find_if(plugins_.begin(), plugins_.end(),
5948bf80f4bSopenharmony_ci                [dependency](const IPlugin* plugin) { return plugin->version.uid == dependency; });
5958bf80f4bSopenharmony_ci            pos != plugins_.end()) {
5968bf80f4bSopenharmony_ci            const auto index = static_cast<size_t>(std::distance(plugins_.begin(), pos));
5978bf80f4bSopenharmony_ci            ++pluginDatas_[index].refcnt;
5988bf80f4bSopenharmony_ci        }
5998bf80f4bSopenharmony_ci    }
6008bf80f4bSopenharmony_ci}
6018bf80f4bSopenharmony_ci
6028bf80f4bSopenharmony_civoid PluginRegistry::UnregisterPlugin(const IPlugin& plugin, PluginToken token)
6038bf80f4bSopenharmony_ci{
6048bf80f4bSopenharmony_ci    CORE_LOG_D("\tUnregister Plugin: %s %s", plugin.name, to_string(plugin.version.uid).data());
6058bf80f4bSopenharmony_ci
6068bf80f4bSopenharmony_ci    if (plugin.unregisterInterfaces) {
6078bf80f4bSopenharmony_ci        plugin.unregisterInterfaces(token);
6088bf80f4bSopenharmony_ci    }
6098bf80f4bSopenharmony_ci}
6108bf80f4bSopenharmony_ci
6118bf80f4bSopenharmony_ci// Library exports
6128bf80f4bSopenharmony_ciCORE_PUBLIC IPluginRegister& GetPluginRegister()
6138bf80f4bSopenharmony_ci{
6148bf80f4bSopenharmony_ci    static PluginRegistry registry;
6158bf80f4bSopenharmony_ci    return registry;
6168bf80f4bSopenharmony_ci}
6178bf80f4bSopenharmony_ci
6188bf80f4bSopenharmony_ciCORE_PUBLIC void CreatePluginRegistry(const PlatformCreateInfo& platformCreateInfo)
6198bf80f4bSopenharmony_ci{
6208bf80f4bSopenharmony_ci    static bool once = false;
6218bf80f4bSopenharmony_ci    if (!once) {
6228bf80f4bSopenharmony_ci        once = true;
6238bf80f4bSopenharmony_ci        auto& registry = static_cast<PluginRegistry&>(GetPluginRegister());
6248bf80f4bSopenharmony_ci        // Create plugins:// protocol that points to plugin files.
6258bf80f4bSopenharmony_ci        // register path to system plugins
6268bf80f4bSopenharmony_ci        // Root path is the location where system plugins , non-rofs assets etc could be held.
6278bf80f4bSopenharmony_ci        auto platform = Platform::Create(platformCreateInfo);
6288bf80f4bSopenharmony_ci        platform->RegisterPluginLocations(registry);
6298bf80f4bSopenharmony_ci    }
6308bf80f4bSopenharmony_ci}
6318bf80f4bSopenharmony_ciCORE_END_NAMESPACE()
632