/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
// INTERNAL INCLUDES
#include <dali/devel-api/adaptor-framework/environment-variable.h>
-#include <dali/devel-api/adaptor-framework/web-engine-back-forward-list.h>
-#include <dali/devel-api/adaptor-framework/web-engine-certificate.h>
-#include <dali/devel-api/adaptor-framework/web-engine-console-message.h>
-#include <dali/devel-api/adaptor-framework/web-engine-context-menu.h>
-#include <dali/devel-api/adaptor-framework/web-engine-context.h>
-#include <dali/devel-api/adaptor-framework/web-engine-cookie-manager.h>
-#include <dali/devel-api/adaptor-framework/web-engine-http-auth-handler.h>
-#include <dali/devel-api/adaptor-framework/web-engine-load-error.h>
-#include <dali/devel-api/adaptor-framework/web-engine-policy-decision.h>
-#include <dali/devel-api/adaptor-framework/web-engine-request-interceptor.h>
-#include <dali/devel-api/adaptor-framework/web-engine-settings.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>
+#include <dali/devel-api/adaptor-framework/web-engine/web-engine-context-menu.h>
+#include <dali/devel-api/adaptor-framework/web-engine/web-engine-context.h>
+#include <dali/devel-api/adaptor-framework/web-engine/web-engine-cookie-manager.h>
+#include <dali/devel-api/adaptor-framework/web-engine/web-engine-http-auth-handler.h>
+#include <dali/devel-api/adaptor-framework/web-engine/web-engine-load-error.h>
+#include <dali/devel-api/adaptor-framework/web-engine/web-engine-policy-decision.h>
+#include <dali/devel-api/adaptor-framework/web-engine/web-engine-settings.h>
#include <dali/internal/system/common/environment-variables.h>
#include <dali/public-api/adaptor-framework/native-image-source.h>
#include <dali/public-api/images/pixel-data.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
-
-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();
+public:
+ static WebEnginePluginObject& GetInstance()
+ {
+ static WebEnginePluginObject gPluginHandle;
+ return gPluginHandle;
+ }
- if(!instance->Initialize())
+ /**
+ * @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
{
- delete instance;
- return nullptr;
+ return mLoadSuccess;
}
- return instance;
-}
+ bool InitializeContextHandle()
+ {
+ if(!mHandle)
+ {
+ return false;
+ }
-WebEngine::WebEngine()
-: mPlugin(NULL),
- mHandle(NULL),
- mCreateWebEnginePtr(NULL),
- mDestroyWebEnginePtr(NULL)
-{
-}
+ if(!mGetWebEngineContextPtr)
+ {
+ mGetWebEngineContextPtr = reinterpret_cast<GetWebEngineContext>(dlsym(mHandle, "GetWebEngineContext"));
-WebEngine::~WebEngine()
-{
- if(mHandle != NULL)
+ if(!mGetWebEngineContextPtr)
+ {
+ DALI_LOG_ERROR("Can't load symbol GetWebEngineContext(), error: %s\n", dlerror());
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ bool InitializeCookieManagerHandle()
{
- if(mDestroyWebEnginePtr != NULL)
+ if(!mHandle)
{
- mPlugin->Destroy();
- mDestroyWebEnginePtr(mPlugin);
+ return false;
}
- dlclose(mHandle);
+ 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;
+ }
+ }
+
+ return true;
}
-}
-bool WebEngine::InitializePluginHandle()
-{
- 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);
- mHandle = dlopen(pluginName.c_str(), RTLD_LAZY);
- if(mHandle)
+ // mPluginName is not initialized yet.
+ const char* name = EnvironmentVariable::GetEnvironmentVariable(DALI_ENV_WEB_ENGINE_NAME);
+ if(name)
+ {
+ mPluginName = MakePluginName(name);
+ }
+ else
{
- return true;
+ mPluginName = std::string(kPluginFullNameDefault);
}
}
- pluginName = std::string(kPluginFullNameDefault);
+
+ mHandle = dlopen(mPluginName.c_str(), RTLD_LAZY);
+ if(!mHandle)
+ {
+ 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;
+ }
}
- return true;
+ 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())
+ {
+ delete instance;
+ return nullptr;
+ }
+
+ return instance;
}
-bool WebEngine::Initialize()
+Dali::WebEngineContext* WebEngine::GetContext()
{
- char* error = NULL;
+ if(!WebEnginePluginObject::GetInstance().InitializeContextHandle())
+ {
+ return nullptr;
+ }
- if(!InitializePluginHandle())
+ if(WebEnginePluginObject::GetInstance().mGetWebEngineContextPtr)
{
- return false;
+ return WebEnginePluginObject::GetInstance().mGetWebEngineContextPtr();
}
- mCreateWebEnginePtr = reinterpret_cast<CreateWebEngineFunction>(dlsym(mHandle, "CreateWebEnginePlugin"));
- if(mCreateWebEnginePtr == NULL)
+ return nullptr;
+}
+
+Dali::WebEngineCookieManager* WebEngine::GetCookieManager()
+{
+ if(!WebEnginePluginObject::GetInstance().InitializeCookieManagerHandle())
{
- DALI_LOG_ERROR("Can't load symbol CreateWebEnginePlugin(), error: %s\n", error);
- return false;
+ return nullptr;
}
- mDestroyWebEnginePtr = reinterpret_cast<DestroyWebEngineFunction>(dlsym(mHandle, "DestroyWebEnginePlugin"));
+ if(WebEnginePluginObject::GetInstance().mGetWebEngineCookieManagerPtr)
+ {
+ return WebEnginePluginObject::GetInstance().mGetWebEngineCookieManagerPtr();
+ }
+
+ return nullptr;
+}
- if(mDestroyWebEnginePtr == NULL)
+WebEngine::WebEngine()
+: mPlugin(nullptr)
+{
+}
+
+WebEngine::~WebEngine()
+{
+ if(mPlugin != nullptr)
{
- DALI_LOG_ERROR("Can't load symbol DestroyWebEnginePlugin(), error: %s\n", error);
- return false;
+ mPlugin->Destroy();
+ // Check whether plugin load sccess or not.
+ if(DALI_LIKELY(WebEnginePluginObject::GetInstance()))
+ {
+ WebEnginePluginObject::GetInstance().mDestroyWebEnginePtr(mPlugin);
+ }
+ mPlugin = nullptr;
}
+}
- mPlugin = mCreateWebEnginePtr();
+bool WebEngine::Initialize()
+{
+ // Check whether plugin load sccess or not.
+ if(!WebEnginePluginObject::GetInstance())
+ {
+ return false;
+ }
- if(mPlugin == NULL)
+ mPlugin = WebEnginePluginObject::GetInstance().mCreateWebEnginePtr();
+ if(mPlugin == nullptr)
{
DALI_LOG_ERROR("Can't create the WebEnginePlugin object\n");
return false;
}
-
return true;
}
mPlugin->Destroy();
}
-Dali::NativeImageInterfacePtr WebEngine::GetNativeImageSource()
+Dali::WebEnginePlugin* WebEngine::GetPlugin() const
{
- return mPlugin->GetNativeImageSource();
-}
-
-Dali::WebEngineSettings& WebEngine::GetSettings() const
-{
- return mPlugin->GetSettings();
+ return mPlugin;
}
-Dali::WebEngineContext& WebEngine::GetContext() const
+Dali::NativeImageSourcePtr WebEngine::GetNativeImageSource()
{
- return mPlugin->GetContext();
+ return mPlugin->GetNativeImageSource();
}
-Dali::WebEngineCookieManager& WebEngine::GetCookieManager() const
+Dali::WebEngineSettings& WebEngine::GetSettings() const
{
- return mPlugin->GetCookieManager();
+ return mPlugin->GetSettings();
}
Dali::WebEngineBackForwardList& WebEngine::GetBackForwardList() const
mPlugin->ActivateAccessibility(activated);
}
+Accessibility::Address WebEngine::GetAccessibilityAddress()
+{
+ return mPlugin->GetAccessibilityAddress();
+}
+
bool WebEngine::SetVisibility(bool visible)
{
return mPlugin->SetVisibility(visible);
mPlugin->RegisterFormRepostDecidedCallback(callback);
}
-void WebEngine::RegisterRequestInterceptorCallback(Dali::WebEnginePlugin::WebEngineRequestInterceptorCallback callback)
-{
- mPlugin->RegisterRequestInterceptorCallback(callback);
-}
-
void WebEngine::RegisterConsoleMessageReceivedCallback(Dali::WebEnginePlugin::WebEngineConsoleMessageReceivedCallback callback)
{
mPlugin->RegisterConsoleMessageReceivedCallback(callback);
mPlugin->RegisterResponsePolicyDecidedCallback(callback);
}
+void WebEngine::RegisterNavigationPolicyDecidedCallback(Dali::WebEnginePlugin::WebEngineNavigationPolicyDecidedCallback callback)
+{
+ mPlugin->RegisterNavigationPolicyDecidedCallback(callback);
+}
+
void WebEngine::RegisterCertificateConfirmedCallback(Dali::WebEnginePlugin::WebEngineCertificateCallback callback)
{
mPlugin->RegisterCertificateConfirmedCallback(callback);
mPlugin->RegisterContextMenuHiddenCallback(callback);
}
+void WebEngine::GetPlainTextAsynchronously(Dali::WebEnginePlugin::PlainTextReceivedCallback callback)
+{
+ mPlugin->GetPlainTextAsynchronously(callback);
+}
+
} // namespace Adaptor
} // namespace Internal
} // namespace Dali