/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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 mLoadSucceeded;
}
- 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"));
+ if(!mGetWebEngineContextPtr)
+ {
+ DALI_LOG_ERROR("Can't load symbol GetWebEngineContext(), error: %s\n", dlerror());
+ return false;
+ }
+ }
-WebEngine::~WebEngine()
-{
- if(mHandle != NULL)
+ return true;
+ }
+
+ bool InitializeCookieManagerHandle()
{
- if(mDestroyWebEnginePtr != NULL)
+ if(!mHandle)
+ {
+ return false;
+ }
+
+ if(!mGetWebEngineCookieManagerPtr)
{
- mPlugin->Destroy();
- mDestroyWebEnginePtr(mPlugin);
+ mGetWebEngineCookieManagerPtr = reinterpret_cast<GetWebEngineCookieManager>(dlsym(mHandle, "GetWebEngineCookieManager"));
+ if(!mGetWebEngineCookieManagerPtr)
+ {
+ DALI_LOG_ERROR("Can't load symbol GetWebEngineCookieManager(), error: %s\n", dlerror());
+ return false;
+ }
}
- dlclose(mHandle);
+ return true;
}
-}
-bool WebEngine::InitializePluginHandle()
-{
- if(pluginName.length() == 0)
+private:
+ // Private constructor / destructor
+ WebEnginePluginObject()
+ : mLoadSucceeded{false},
+ mHandle{nullptr},
+ mCreateWebEnginePtr{nullptr},
+ mDestroyWebEnginePtr{nullptr},
+ mGetWebEngineContextPtr{nullptr},
+ mGetWebEngineCookieManagerPtr{nullptr}
{
- // pluginName is not initialized yet.
+ std::string pluginName;
const char* name = EnvironmentVariable::GetEnvironmentVariable(DALI_ENV_WEB_ENGINE_NAME);
if(name)
{
pluginName = MakePluginName(name);
- mHandle = dlopen(pluginName.c_str(), RTLD_LAZY);
- if(mHandle)
- {
- return true;
- }
}
- pluginName = std::string(kPluginFullNameDefault);
+ else
+ {
+ pluginName = std::string(kPluginFullNameDefault);
+ }
+
+ mHandle = dlopen(pluginName.c_str(), RTLD_LAZY);
+ if(!mHandle)
+ {
+ DALI_LOG_ERROR("Can't load %s : %s\n", pluginName.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;
+ }
+
+ mLoadSucceeded = 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;
+ mLoadSucceeded = false;
+ }
}
- return true;
+ WebEnginePluginObject(const WebEnginePluginObject&) = delete;
+ WebEnginePluginObject(WebEnginePluginObject&&) = delete;
+ WebEnginePluginObject& operator=(const WebEnginePluginObject&) = delete;
+ WebEnginePluginObject& operator=(WebEnginePluginObject&&) = delete;
+
+private:
+ bool mLoadSucceeded; ///< 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();
+ return mPlugin;
}
-Dali::WebEngineSettings& WebEngine::GetSettings() const
+Dali::NativeImageSourcePtr WebEngine::GetNativeImageSource()
{
- return mPlugin->GetSettings();
-}
-
-Dali::WebEngineContext& WebEngine::GetContext() const
-{
- 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
return mPlugin->GetFavicon();
}
-const std::string& WebEngine::GetUrl()
+std::string WebEngine::GetUrl() const
{
return mPlugin->GetUrl();
}
-const std::string& WebEngine::GetUserAgent() const
+std::string WebEngine::GetUserAgent() const
{
return mPlugin->GetUserAgent();
}
return mPlugin->LoadHtmlStringOverrideCurrentEntry(html, basicUri, unreachableUrl);
}
-bool WebEngine::LoadContents(const std::string& contents, uint32_t contentSize, const std::string& mimeType, const std::string& encoding, const std::string& baseUri)
+bool WebEngine::LoadContents(const int8_t* contents, uint32_t contentSize, const std::string& mimeType, const std::string& encoding, const std::string& baseUri)
{
return mPlugin->LoadContents(contents, contentSize, mimeType, encoding, baseUri);
}
mPlugin->GoBack();
}
-void WebEngine::EvaluateJavaScript(const std::string& script, std::function<void(const std::string&)> resultHandler)
+void WebEngine::EvaluateJavaScript(const std::string& script, Dali::WebEnginePlugin::JavaScriptMessageHandlerCallback resultHandler)
{
mPlugin->EvaluateJavaScript(script, resultHandler);
}
-void WebEngine::AddJavaScriptMessageHandler(const std::string& exposedObjectName, std::function<void(const std::string&)> handler)
+void WebEngine::AddJavaScriptMessageHandler(const std::string& exposedObjectName, Dali::WebEnginePlugin::JavaScriptMessageHandlerCallback handler)
{
mPlugin->AddJavaScriptMessageHandler(exposedObjectName, handler);
}
mPlugin->ActivateAccessibility(activated);
}
+Accessibility::Address WebEngine::GetAccessibilityAddress()
+{
+ return mPlugin->GetAccessibilityAddress();
+}
+
bool WebEngine::SetVisibility(bool visible)
{
return mPlugin->SetVisibility(visible);
return mPlugin->SendWheelEvent(event);
}
-Dali::WebEnginePlugin::WebEnginePageLoadSignalType& WebEngine::PageLoadStartedSignal()
+void WebEngine::ExitFullscreen()
+{
+ mPlugin->ExitFullscreen();
+}
+
+void WebEngine::RegisterFrameRenderedCallback(Dali::WebEnginePlugin::WebEngineFrameRenderedCallback callback)
+{
+ mPlugin->RegisterFrameRenderedCallback(callback);
+}
+
+void WebEngine::RegisterPageLoadStartedCallback(Dali::WebEnginePlugin::WebEnginePageLoadCallback callback)
+{
+ mPlugin->RegisterPageLoadStartedCallback(callback);
+}
+
+void WebEngine::RegisterPageLoadInProgressCallback(Dali::WebEnginePlugin::WebEnginePageLoadCallback callback)
+{
+ mPlugin->RegisterPageLoadInProgressCallback(callback);
+}
+
+void WebEngine::RegisterPageLoadFinishedCallback(Dali::WebEnginePlugin::WebEnginePageLoadCallback callback)
+{
+ mPlugin->RegisterPageLoadFinishedCallback(callback);
+}
+
+void WebEngine::RegisterPageLoadErrorCallback(Dali::WebEnginePlugin::WebEnginePageLoadErrorCallback callback)
+{
+ mPlugin->RegisterPageLoadErrorCallback(callback);
+}
+
+void WebEngine::RegisterScrollEdgeReachedCallback(Dali::WebEnginePlugin::WebEngineScrollEdgeReachedCallback callback)
+{
+ mPlugin->RegisterScrollEdgeReachedCallback(callback);
+}
+
+void WebEngine::RegisterUrlChangedCallback(Dali::WebEnginePlugin::WebEngineUrlChangedCallback callback)
{
- return mPlugin->PageLoadStartedSignal();
+ mPlugin->RegisterUrlChangedCallback(callback);
}
-Dali::WebEnginePlugin::WebEnginePageLoadSignalType& WebEngine::PageLoadInProgressSignal()
+void WebEngine::RegisterFormRepostDecidedCallback(Dali::WebEnginePlugin::WebEngineFormRepostDecidedCallback callback)
{
- return mPlugin->PageLoadInProgressSignal();
+ mPlugin->RegisterFormRepostDecidedCallback(callback);
}
-Dali::WebEnginePlugin::WebEnginePageLoadSignalType& WebEngine::PageLoadFinishedSignal()
+void WebEngine::RegisterConsoleMessageReceivedCallback(Dali::WebEnginePlugin::WebEngineConsoleMessageReceivedCallback callback)
{
- return mPlugin->PageLoadFinishedSignal();
+ mPlugin->RegisterConsoleMessageReceivedCallback(callback);
}
-Dali::WebEnginePlugin::WebEnginePageLoadErrorSignalType& WebEngine::PageLoadErrorSignal()
+void WebEngine::RegisterResponsePolicyDecidedCallback(Dali::WebEnginePlugin::WebEngineResponsePolicyDecidedCallback callback)
{
- return mPlugin->PageLoadErrorSignal();
+ mPlugin->RegisterResponsePolicyDecidedCallback(callback);
}
-Dali::WebEnginePlugin::WebEngineScrollEdgeReachedSignalType& WebEngine::ScrollEdgeReachedSignal()
+void WebEngine::RegisterNavigationPolicyDecidedCallback(Dali::WebEnginePlugin::WebEngineNavigationPolicyDecidedCallback callback)
{
- return mPlugin->ScrollEdgeReachedSignal();
+ mPlugin->RegisterNavigationPolicyDecidedCallback(callback);
}
-Dali::WebEnginePlugin::WebEngineUrlChangedSignalType& WebEngine::UrlChangedSignal()
+void WebEngine::RegisterNewWindowPolicyDecidedCallback(Dali::WebEnginePlugin::WebEngineNewWindowPolicyDecidedCallback callback)
{
- return mPlugin->UrlChangedSignal();
+ mPlugin->RegisterNewWindowPolicyDecidedCallback(callback);
}
-Dali::WebEnginePlugin::WebEngineFormRepostDecisionSignalType& WebEngine::FormRepostDecisionSignal()
+void WebEngine::RegisterNewWindowCreatedCallback(Dali::WebEnginePlugin::WebEngineNewWindowCreatedCallback callback)
{
- return mPlugin->FormRepostDecisionSignal();
+ mPlugin->RegisterNewWindowCreatedCallback(callback);
}
-Dali::WebEnginePlugin::WebEngineFrameRenderedSignalType& WebEngine::FrameRenderedSignal()
+void WebEngine::RegisterCertificateConfirmedCallback(Dali::WebEnginePlugin::WebEngineCertificateCallback callback)
{
- return mPlugin->FrameRenderedSignal();
+ mPlugin->RegisterCertificateConfirmedCallback(callback);
}
-Dali::WebEnginePlugin::WebEngineRequestInterceptorSignalType& WebEngine::RequestInterceptorSignal()
+void WebEngine::RegisterSslCertificateChangedCallback(Dali::WebEnginePlugin::WebEngineCertificateCallback callback)
{
- return mPlugin->RequestInterceptorSignal();
+ mPlugin->RegisterSslCertificateChangedCallback(callback);
}
-Dali::WebEnginePlugin::WebEngineConsoleMessageSignalType& WebEngine::ConsoleMessageSignal()
+void WebEngine::RegisterHttpAuthHandlerCallback(Dali::WebEnginePlugin::WebEngineHttpAuthHandlerCallback callback)
{
- return mPlugin->ConsoleMessageSignal();
+ mPlugin->RegisterHttpAuthHandlerCallback(callback);
}
-Dali::WebEnginePlugin::WebEnginePolicyDecisionSignalType& WebEngine::PolicyDecisionSignal()
+void WebEngine::RegisterContextMenuShownCallback(Dali::WebEnginePlugin::WebEngineContextMenuShownCallback callback)
{
- return mPlugin->PolicyDecisionSignal();
+ mPlugin->RegisterContextMenuShownCallback(callback);
}
-Dali::WebEnginePlugin::WebEngineCertificateSignalType& WebEngine::CertificateConfirmSignal()
+void WebEngine::RegisterContextMenuHiddenCallback(Dali::WebEnginePlugin::WebEngineContextMenuHiddenCallback callback)
{
- return mPlugin->CertificateConfirmSignal();
+ mPlugin->RegisterContextMenuHiddenCallback(callback);
}
-Dali::WebEnginePlugin::WebEngineCertificateSignalType& WebEngine::SslCertificateChangedSignal()
+void WebEngine::RegisterFullscreenEnteredCallback(Dali::WebEnginePlugin::WebEngineFullscreenEnteredCallback callback)
{
- return mPlugin->SslCertificateChangedSignal();
+ mPlugin->RegisterFullscreenEnteredCallback(callback);
}
-Dali::WebEnginePlugin::WebEngineHttpAuthHandlerSignalType& WebEngine::HttpAuthHandlerSignal()
+void WebEngine::RegisterFullscreenExitedCallback(Dali::WebEnginePlugin::WebEngineFullscreenExitedCallback callback)
{
- return mPlugin->HttpAuthHandlerSignal();
+ mPlugin->RegisterFullscreenExitedCallback(callback);
}
-Dali::WebEnginePlugin::WebEngineContextMenuCustomizedSignalType& WebEngine::ContextMenuCustomizedSignal()
+void WebEngine::RegisterTextFoundCallback(Dali::WebEnginePlugin::WebEngineTextFoundCallback callback)
{
- return mPlugin->ContextMenuCustomizedSignal();
+ mPlugin->RegisterTextFoundCallback(callback);
}
-Dali::WebEnginePlugin::WebEngineContextMenuItemSelectedSignalType& WebEngine::ContextMenuItemSelectedSignal()
+void WebEngine::GetPlainTextAsynchronously(Dali::WebEnginePlugin::PlainTextReceivedCallback callback)
{
- return mPlugin->ContextMenuItemSelectedSignal();
+ mPlugin->GetPlainTextAsynchronously(callback);
}
} // namespace Adaptor