// 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>
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;
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<GetWebEngineContext>(dlsym(mHandle, "GetWebEngineContext"));
- if(getWebEngineContextPtr)
+ bool InitializeContextHandle()
{
- return getWebEngineContextPtr();
- }
+ if(!mHandle)
+ {
+ return false;
+ }
- return nullptr;
-}
+ if(!mGetWebEngineContextPtr)
+ {
+ mGetWebEngineContextPtr = reinterpret_cast<GetWebEngineContext>(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<GetWebEngineCookieManager>(dlsym(mHandle, "GetWebEngineCookieManager"));
- if(getWebEngineCookieManagerPtr)
+ bool InitializeCookieManagerHandle()
{
- return getWebEngineCookieManagerPtr();
- }
+ if(!mHandle)
+ {
+ return false;
+ }
- return nullptr;
-}
+ if(!mGetWebEngineCookieManagerPtr)
+ {
+ mGetWebEngineCookieManagerPtr = reinterpret_cast<GetWebEngineCookieManager>(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<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;
}
- 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<CreateWebEngineFunction>(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<DestroyWebEngineFunction>(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()
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;
}