From 5a09648a9d6321f11c729d2d278499079b7611b4 Mon Sep 17 00:00:00 2001 From: Hosang Kim Date: Tue, 29 Nov 2022 15:26:52 +0900 Subject: [PATCH] Revert "[Tizen] Revert "[Web] Fix WebView terminate crash"" This reverts commit 35dc5815394f53b80eb4a5b8afd1fa60f4bc1497. --- .../internal/web-engine/common/web-engine-impl.cpp | 244 ++++++++++++++------- dali/internal/web-engine/common/web-engine-impl.h | 19 -- 2 files changed, 166 insertions(+), 97 deletions(-) mode change 100755 => 100644 dali/internal/web-engine/common/web-engine-impl.cpp diff --git a/dali/internal/web-engine/common/web-engine-impl.cpp b/dali/internal/web-engine/common/web-engine-impl.cpp old mode 100755 new mode 100644 index 558dac7..3d5e300 --- a/dali/internal/web-engine/common/web-engine-impl.cpp +++ b/dali/internal/web-engine/common/web-engine-impl.cpp @@ -26,7 +26,6 @@ // INTERNAL INCLUDES #include -#include #include #include #include @@ -53,10 +52,6 @@ constexpr char const* const kPluginFullNamePrefix = "libdali2-web-engine-"; constexpr char const* const kPluginFullNamePostfix = "-plugin.so"; constexpr char const* const kPluginFullNameDefault = "libdali2-web-engine-plugin.so"; -// Note: Dali WebView policy does not allow to use multiple web engines in an application. -// So once pluginName is set to non-empty string, it will not change. -std::string pluginName; - std::string MakePluginName(const char* environmentName) { std::stringstream fullName; @@ -71,114 +66,202 @@ Dali::BaseHandle Create() Dali::TypeRegistration type(typeid(Dali::WebEngine), typeid(Dali::BaseHandle), Create); -} // unnamed namespace - -void* WebEngine::mHandle = nullptr; -WebEngine::CreateWebEngineFunction WebEngine::mCreateWebEnginePtr = nullptr; -WebEngine::DestroyWebEngineFunction WebEngine::mDestroyWebEnginePtr = nullptr; - -WebEnginePtr WebEngine::New() +/** + * @brief Control the WebEnginePlugin library lifecycle. + * Hold the plugin library handle in static singletone. + * It will makes library handle alives during all WebEngine resources create & destory. + */ +struct WebEnginePluginObject { - WebEngine* instance = new WebEngine(); - if(!instance->Initialize()) +public: + static WebEnginePluginObject& GetInstance() { - delete instance; - return nullptr; + static WebEnginePluginObject gPluginHandle; + return gPluginHandle; } - return instance; -} - -Dali::WebEngineContext* WebEngine::GetContext() -{ - if(!InitializePluginHandle()) + /** + * @brief Converts an handle to a bool. + * + * This is useful for checking whether the WebEnginePluginObject succes to load library. + * @note We don't check mHandle because it is possible that mHandle load is success but + * Create/Destroy API load failed. + */ + explicit operator bool() const { - return nullptr; + return mLoadSuccess; } - using GetWebEngineContext = Dali::WebEngineContext* (*)(); - GetWebEngineContext getWebEngineContextPtr = reinterpret_cast(dlsym(mHandle, "GetWebEngineContext")); - if(getWebEngineContextPtr) + bool InitializeContextHandle() { - return getWebEngineContextPtr(); - } + if(!mHandle) + { + return false; + } - return nullptr; -} + if(!mGetWebEngineContextPtr) + { + mGetWebEngineContextPtr = reinterpret_cast(dlsym(mHandle, "GetWebEngineContext")); -Dali::WebEngineCookieManager* WebEngine::GetCookieManager() -{ - if(!InitializePluginHandle()) - { - return nullptr; + if(!mGetWebEngineContextPtr) + { + DALI_LOG_ERROR("Can't load symbol GetWebEngineContext(), error: %s\n", dlerror()); + return false; + } + } + + return true; } - using GetWebEngineCookieManager = Dali::WebEngineCookieManager* (*)(); - GetWebEngineCookieManager getWebEngineCookieManagerPtr = reinterpret_cast(dlsym(mHandle, "GetWebEngineCookieManager")); - if(getWebEngineCookieManagerPtr) + bool InitializeCookieManagerHandle() { - return getWebEngineCookieManagerPtr(); - } + if(!mHandle) + { + return false; + } - return nullptr; -} + if(!mGetWebEngineCookieManagerPtr) + { + mGetWebEngineCookieManagerPtr = reinterpret_cast(dlsym(mHandle, "GetWebEngineCookieManager")); + + if(!mGetWebEngineCookieManagerPtr) + { + DALI_LOG_ERROR("Can't load symbol GetWebEngineCookieManager(), error: %s\n", dlerror()); + return false; + } + } -bool WebEngine::InitializePluginHandle() -{ - if(mHandle) - { - DALI_LOG_ERROR("Plugin.so has been opened already.\n"); return true; } - if(pluginName.length() == 0) +private: + // Private constructor / destructor + WebEnginePluginObject() + : mPluginName{}, + mLoadSuccess{false}, + mHandle{nullptr}, + mCreateWebEnginePtr{nullptr}, + mDestroyWebEnginePtr{nullptr}, + mGetWebEngineContextPtr{nullptr}, + mGetWebEngineCookieManagerPtr{nullptr} { - // pluginName is not initialized yet. - const char* name = EnvironmentVariable::GetEnvironmentVariable(DALI_ENV_WEB_ENGINE_NAME); - if(name) + if(mPluginName.length() == 0) { - pluginName = MakePluginName(name); + // mPluginName is not initialized yet. + const char* name = EnvironmentVariable::GetEnvironmentVariable(DALI_ENV_WEB_ENGINE_NAME); + if(name) + { + mPluginName = MakePluginName(name); + } + else + { + mPluginName = std::string(kPluginFullNameDefault); + } } - else + + mHandle = dlopen(mPluginName.c_str(), RTLD_LAZY); + if(!mHandle) { - pluginName = std::string(kPluginFullNameDefault); + DALI_LOG_ERROR("Can't load %s : %s\n", mPluginName.c_str(), dlerror()); + return; } + + mCreateWebEnginePtr = reinterpret_cast(dlsym(mHandle, "CreateWebEnginePlugin")); + if(mCreateWebEnginePtr == nullptr) + { + DALI_LOG_ERROR("Can't load symbol CreateWebEnginePlugin(), error: %s\n", dlerror()); + return; + } + + mDestroyWebEnginePtr = reinterpret_cast(dlsym(mHandle, "DestroyWebEnginePlugin")); + if(mDestroyWebEnginePtr == nullptr) + { + DALI_LOG_ERROR("Can't load symbol DestroyWebEnginePlugin(), error: %s\n", dlerror()); + return; + } + + mLoadSuccess = true; } - mHandle = dlopen(pluginName.c_str(), RTLD_LAZY); - if(!mHandle) + ~WebEnginePluginObject() { - DALI_LOG_ERROR("Can't load %s : %s\n", pluginName.c_str(), dlerror()); - return false; + if(mHandle) + { + dlclose(mHandle); + mHandle = nullptr; + mLoadSuccess = false; + } } - // Make sure that mHandle would be closed. - Dali::LifecycleController::Get().TerminateSignal().Connect(&WebEngine::ClosePluginHandle); + WebEnginePluginObject(const WebEnginePluginObject&) = delete; + WebEnginePluginObject(WebEnginePluginObject&&) = delete; + WebEnginePluginObject& operator=(const WebEnginePluginObject&) = delete; + WebEnginePluginObject& operator=(WebEnginePluginObject&&) = delete; + +private: + std::string mPluginName; ///< Name of web engine plugin + /// Note: Dali WebView policy does not allow to use multiple web engines in an application. + /// So once pluginName is set to non-empty string, it will not change. + + bool mLoadSuccess; ///< True if library loaded successfully. False otherwise. + +public: + using CreateWebEngineFunction = Dali::WebEnginePlugin* (*)(); + using DestroyWebEngineFunction = void (*)(Dali::WebEnginePlugin* plugin); + + using GetWebEngineContext = Dali::WebEngineContext* (*)(); + using GetWebEngineCookieManager = Dali::WebEngineCookieManager* (*)(); + + void* mHandle; ///< Handle for the loaded library + CreateWebEngineFunction mCreateWebEnginePtr; ///< Function to create plugin instance + DestroyWebEngineFunction mDestroyWebEnginePtr; ///< Function to destroy plugin instance - mCreateWebEnginePtr = reinterpret_cast(dlsym(mHandle, "CreateWebEnginePlugin")); - if(mCreateWebEnginePtr == nullptr) + GetWebEngineContext mGetWebEngineContextPtr; ///< Function to get WebEngineContext + GetWebEngineCookieManager mGetWebEngineCookieManagerPtr; ///< Function to get WebEngineCookieManager +}; + +} // unnamed namespace + +WebEnginePtr WebEngine::New() +{ + WebEngine* instance = new WebEngine(); + if(!instance->Initialize()) { - DALI_LOG_ERROR("Can't load symbol CreateWebEnginePlugin(), error: %s\n", dlerror()); - return false; + delete instance; + return nullptr; } - mDestroyWebEnginePtr = reinterpret_cast(dlsym(mHandle, "DestroyWebEnginePlugin")); - if(mDestroyWebEnginePtr == nullptr) + return instance; +} + +Dali::WebEngineContext* WebEngine::GetContext() +{ + if(!WebEnginePluginObject::GetInstance().InitializeContextHandle()) { - DALI_LOG_ERROR("Can't load symbol DestroyWebEnginePlugin(), error: %s\n", dlerror()); - return false; + return nullptr; } - return true; + if(WebEnginePluginObject::GetInstance().mGetWebEngineContextPtr) + { + return WebEnginePluginObject::GetInstance().mGetWebEngineContextPtr(); + } + + return nullptr; } -void WebEngine::ClosePluginHandle() +Dali::WebEngineCookieManager* WebEngine::GetCookieManager() { - if(mHandle) + if(!WebEnginePluginObject::GetInstance().InitializeCookieManagerHandle()) + { + return nullptr; + } + + if(WebEnginePluginObject::GetInstance().mGetWebEngineCookieManagerPtr) { - dlclose(mHandle); - mHandle = nullptr; + return WebEnginePluginObject::GetInstance().mGetWebEngineCookieManagerPtr(); } + + return nullptr; } WebEngine::WebEngine() @@ -188,27 +271,32 @@ WebEngine::WebEngine() WebEngine::~WebEngine() { - if(mPlugin != nullptr && mDestroyWebEnginePtr != nullptr) + if(mPlugin != nullptr) { mPlugin->Destroy(); - mDestroyWebEnginePtr(mPlugin); + // Check whether plugin load sccess or not. + if(DALI_LIKELY(WebEnginePluginObject::GetInstance())) + { + WebEnginePluginObject::GetInstance().mDestroyWebEnginePtr(mPlugin); + } + mPlugin = nullptr; } } bool WebEngine::Initialize() { - if(!InitializePluginHandle()) + // Check whether plugin load sccess or not. + if(!WebEnginePluginObject::GetInstance()) { return false; } - mPlugin = mCreateWebEnginePtr(); + mPlugin = WebEnginePluginObject::GetInstance().mCreateWebEnginePtr(); if(mPlugin == nullptr) { DALI_LOG_ERROR("Can't create the WebEnginePlugin object\n"); return false; } - return true; } diff --git a/dali/internal/web-engine/common/web-engine-impl.h b/dali/internal/web-engine/common/web-engine-impl.h index 085c28a..96e6eac 100755 --- a/dali/internal/web-engine/common/web-engine-impl.h +++ b/dali/internal/web-engine/common/web-engine-impl.h @@ -576,27 +576,8 @@ private: */ bool Initialize(); - /** - * @brief Initialize library handle by loading web engine plugin. - * - * @return Whether the initialization succeed or not. - */ - static bool InitializePluginHandle(); - - /** - * @brief Close library handle. - */ - static void ClosePluginHandle(); - private: - using CreateWebEngineFunction = Dali::WebEnginePlugin* (*)(); - using DestroyWebEngineFunction = void (*)(Dali::WebEnginePlugin* plugin); - Dali::WebEnginePlugin* mPlugin; ///< WebEnginePlugin instance - - static void* mHandle; ///< Handle for the loaded library - static CreateWebEngineFunction mCreateWebEnginePtr; ///< Function to create plugin instance - static DestroyWebEngineFunction mDestroyWebEnginePtr; ///< Function to destroy plugin instance }; } // namespace Adaptor -- 2.7.4