Revert "Revert "[Tizen] Revert "[Web] Fix WebView terminate crash"""
authorBowon Ryu <bowon.ryu@samsung.com>
Tue, 6 Dec 2022 06:18:09 +0000 (15:18 +0900)
committerBowon Ryu <bowon.ryu@samsung.com>
Tue, 6 Dec 2022 06:18:09 +0000 (15:18 +0900)
This reverts commit 2cb56dc33e626bbb591354e3144db5e9e380b3b6.

dali/internal/web-engine/common/web-engine-impl.cpp [changed mode: 0644->0755]
dali/internal/web-engine/common/web-engine-impl.h

old mode 100644 (file)
new mode 100755 (executable)
index 3d5e300..558dac7
@@ -26,6 +26,7 @@
 
 // INTERNAL INCLUDES
 #include <dali/devel-api/adaptor-framework/environment-variable.h>
+#include <dali/devel-api/adaptor-framework/lifecycle-controller.h>
 #include <dali/devel-api/adaptor-framework/web-engine/web-engine-back-forward-list.h>
 #include <dali/devel-api/adaptor-framework/web-engine/web-engine-certificate.h>
 #include <dali/devel-api/adaptor-framework/web-engine/web-engine-console-message.h>
@@ -52,6 +53,10 @@ 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;
@@ -66,202 +71,114 @@ Dali::BaseHandle Create()
 
 Dali::TypeRegistration type(typeid(Dali::WebEngine), typeid(Dali::BaseHandle), Create);
 
-/**
- * @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
+} // unnamed namespace
+
+void*                               WebEngine::mHandle              = nullptr;
+WebEngine::CreateWebEngineFunction  WebEngine::mCreateWebEnginePtr  = nullptr;
+WebEngine::DestroyWebEngineFunction WebEngine::mDestroyWebEnginePtr = nullptr;
+
+WebEnginePtr WebEngine::New()
 {
-public:
-  static WebEnginePluginObject& GetInstance()
+  WebEngine* instance = new WebEngine();
+  if(!instance->Initialize())
   {
-    static WebEnginePluginObject gPluginHandle;
-    return gPluginHandle;
+    delete instance;
+    return nullptr;
   }
 
-  /**
-   * @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 instance;
+}
+
+Dali::WebEngineContext* WebEngine::GetContext()
+{
+  if(!InitializePluginHandle())
   {
-    return mLoadSuccess;
+    return nullptr;
   }
 
-  bool InitializeContextHandle()
+  using GetWebEngineContext                  = Dali::WebEngineContext* (*)();
+  GetWebEngineContext getWebEngineContextPtr = reinterpret_cast<GetWebEngineContext>(dlsym(mHandle, "GetWebEngineContext"));
+  if(getWebEngineContextPtr)
   {
-    if(!mHandle)
-    {
-      return false;
-    }
-
-    if(!mGetWebEngineContextPtr)
-    {
-      mGetWebEngineContextPtr = reinterpret_cast<GetWebEngineContext>(dlsym(mHandle, "GetWebEngineContext"));
+    return getWebEngineContextPtr();
+  }
 
-      if(!mGetWebEngineContextPtr)
-      {
-        DALI_LOG_ERROR("Can't load symbol GetWebEngineContext(), error: %s\n", dlerror());
-        return false;
-      }
-    }
+  return nullptr;
+}
 
-    return true;
+Dali::WebEngineCookieManager* WebEngine::GetCookieManager()
+{
+  if(!InitializePluginHandle())
+  {
+    return nullptr;
   }
 
-  bool InitializeCookieManagerHandle()
+  using GetWebEngineCookieManager                        = Dali::WebEngineCookieManager* (*)();
+  GetWebEngineCookieManager getWebEngineCookieManagerPtr = reinterpret_cast<GetWebEngineCookieManager>(dlsym(mHandle, "GetWebEngineCookieManager"));
+  if(getWebEngineCookieManagerPtr)
   {
-    if(!mHandle)
-    {
-      return false;
-    }
-
-    if(!mGetWebEngineCookieManagerPtr)
-    {
-      mGetWebEngineCookieManagerPtr = reinterpret_cast<GetWebEngineCookieManager>(dlsym(mHandle, "GetWebEngineCookieManager"));
+    return getWebEngineCookieManagerPtr();
+  }
 
-      if(!mGetWebEngineCookieManagerPtr)
-      {
-        DALI_LOG_ERROR("Can't load symbol GetWebEngineCookieManager(), error: %s\n", dlerror());
-        return false;
-      }
-    }
+  return nullptr;
+}
 
+bool WebEngine::InitializePluginHandle()
+{
+  if(mHandle)
+  {
+    DALI_LOG_ERROR("Plugin.so has been opened already.\n");
     return true;
   }
 
-private:
-  // Private constructor / destructor
-  WebEnginePluginObject()
-  : mPluginName{},
-    mLoadSuccess{false},
-    mHandle{nullptr},
-    mCreateWebEnginePtr{nullptr},
-    mDestroyWebEnginePtr{nullptr},
-    mGetWebEngineContextPtr{nullptr},
-    mGetWebEngineCookieManagerPtr{nullptr}
+  if(pluginName.length() == 0)
   {
-    if(mPluginName.length() == 0)
+    // pluginName is not initialized yet.
+    const char* name = EnvironmentVariable::GetEnvironmentVariable(DALI_ENV_WEB_ENGINE_NAME);
+    if(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);
-      }
+      pluginName = MakePluginName(name);
     }
-
-    mHandle = dlopen(mPluginName.c_str(), RTLD_LAZY);
-    if(!mHandle)
+    else
     {
-      DALI_LOG_ERROR("Can't load %s : %s\n", mPluginName.c_str(), dlerror());
-      return;
+      pluginName = std::string(kPluginFullNameDefault);
     }
-
-    mCreateWebEnginePtr = reinterpret_cast<CreateWebEngineFunction>(dlsym(mHandle, "CreateWebEnginePlugin"));
-    if(mCreateWebEnginePtr == nullptr)
-    {
-      DALI_LOG_ERROR("Can't load symbol CreateWebEnginePlugin(), error: %s\n", dlerror());
-      return;
-    }
-
-    mDestroyWebEnginePtr = reinterpret_cast<DestroyWebEngineFunction>(dlsym(mHandle, "DestroyWebEnginePlugin"));
-    if(mDestroyWebEnginePtr == nullptr)
-    {
-      DALI_LOG_ERROR("Can't load symbol DestroyWebEnginePlugin(), error: %s\n", dlerror());
-      return;
-    }
-
-    mLoadSuccess = true;
   }
 
-  ~WebEnginePluginObject()
-  {
-    if(mHandle)
-    {
-      dlclose(mHandle);
-      mHandle      = nullptr;
-      mLoadSuccess = false;
-    }
-  }
-
-  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
-
-  GetWebEngineContext       mGetWebEngineContextPtr;       ///< Function to get WebEngineContext
-  GetWebEngineCookieManager mGetWebEngineCookieManagerPtr; ///< Function to get WebEngineCookieManager
-};
-
-} // unnamed namespace
-
-WebEnginePtr WebEngine::New()
-{
-  WebEngine* instance = new WebEngine();
-  if(!instance->Initialize())
+  mHandle = dlopen(pluginName.c_str(), RTLD_LAZY);
+  if(!mHandle)
   {
-    delete instance;
-    return nullptr;
+    DALI_LOG_ERROR("Can't load %s : %s\n", pluginName.c_str(), dlerror());
+    return false;
   }
 
-  return instance;
-}
+  // Make sure that mHandle would be closed.
+  Dali::LifecycleController::Get().TerminateSignal().Connect(&WebEngine::ClosePluginHandle);
 
-Dali::WebEngineContext* WebEngine::GetContext()
-{
-  if(!WebEnginePluginObject::GetInstance().InitializeContextHandle())
+  mCreateWebEnginePtr = reinterpret_cast<CreateWebEngineFunction>(dlsym(mHandle, "CreateWebEnginePlugin"));
+  if(mCreateWebEnginePtr == nullptr)
   {
-    return nullptr;
+    DALI_LOG_ERROR("Can't load symbol CreateWebEnginePlugin(), error: %s\n", dlerror());
+    return false;
   }
 
-  if(WebEnginePluginObject::GetInstance().mGetWebEngineContextPtr)
+  mDestroyWebEnginePtr = reinterpret_cast<DestroyWebEngineFunction>(dlsym(mHandle, "DestroyWebEnginePlugin"));
+  if(mDestroyWebEnginePtr == nullptr)
   {
-    return WebEnginePluginObject::GetInstance().mGetWebEngineContextPtr();
+    DALI_LOG_ERROR("Can't load symbol DestroyWebEnginePlugin(), error: %s\n", dlerror());
+    return false;
   }
 
-  return nullptr;
+  return true;
 }
 
-Dali::WebEngineCookieManager* WebEngine::GetCookieManager()
+void WebEngine::ClosePluginHandle()
 {
-  if(!WebEnginePluginObject::GetInstance().InitializeCookieManagerHandle())
-  {
-    return nullptr;
-  }
-
-  if(WebEnginePluginObject::GetInstance().mGetWebEngineCookieManagerPtr)
+  if(mHandle)
   {
-    return WebEnginePluginObject::GetInstance().mGetWebEngineCookieManagerPtr();
+    dlclose(mHandle);
+    mHandle = nullptr;
   }
-
-  return nullptr;
 }
 
 WebEngine::WebEngine()
@@ -271,32 +188,27 @@ WebEngine::WebEngine()
 
 WebEngine::~WebEngine()
 {
-  if(mPlugin != nullptr)
+  if(mPlugin != nullptr && mDestroyWebEnginePtr != nullptr)
   {
     mPlugin->Destroy();
-    // Check whether plugin load sccess or not.
-    if(DALI_LIKELY(WebEnginePluginObject::GetInstance()))
-    {
-      WebEnginePluginObject::GetInstance().mDestroyWebEnginePtr(mPlugin);
-    }
-    mPlugin = nullptr;
+    mDestroyWebEnginePtr(mPlugin);
   }
 }
 
 bool WebEngine::Initialize()
 {
-  // Check whether plugin load sccess or not.
-  if(!WebEnginePluginObject::GetInstance())
+  if(!InitializePluginHandle())
   {
     return false;
   }
 
-  mPlugin = WebEnginePluginObject::GetInstance().mCreateWebEnginePtr();
+  mPlugin = mCreateWebEnginePtr();
   if(mPlugin == nullptr)
   {
     DALI_LOG_ERROR("Can't create the WebEnginePlugin object\n");
     return false;
   }
+
   return true;
 }
 
index 96e6eac..085c28a 100755 (executable)
@@ -576,8 +576,27 @@ 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