webview2: Add user-data-folder property

Adding a propery to specify location of WebView2's user data folder
location.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6921>
This commit is contained in:
Seungha Yang 2024-05-25 16:58:17 +09:00 committed by GStreamer Marge Bot
parent 05f9eadcaf
commit a4dfca3ae4
3 changed files with 60 additions and 6 deletions

View file

@ -30,6 +30,7 @@
#include "gstwebview2object.h"
#include <gst/d3d11/gstd3d11-private.h>
#include <webview2.h>
#include <WebView2EnvironmentOptions.h>
#include <dcomp.h>
#include <wrl.h>
#include <mutex>
@ -76,6 +77,7 @@ enum
{
PROP_0,
PROP_DEVICE,
PROP_USER_DATA_FOLDER,
};
template < typename InterfaceType, PCNZWCH runtime_class_id > static HRESULT
@ -132,7 +134,7 @@ public:
STDMETHODIMP
RuntimeClassInitialize (GstWebView2Object * obj, GstD3D11Device * device,
HANDLE event_handle, HWND hwnd)
HANDLE event_handle, HWND hwnd, PCWSTR user_data_folder)
{
obj_ = obj;
device_ = device;
@ -186,6 +188,12 @@ public:
hr = webview_visual_->put_IsVisible (TRUE);
CHECK_HR_AND_RETURN (hr, put_IsVisible);
if (user_data_folder) {
auto option = Make<CoreWebView2EnvironmentOptions>();
return CreateCoreWebView2EnvironmentWithOptions (nullptr,
user_data_folder, option.Get (), this);
}
return CreateCoreWebView2Environment (this);
}
@ -712,6 +720,7 @@ struct GstWebView2ObjectPrivate
ComPtr<IDispatcherQueue> queue;
GThread *main_thread = nullptr;
std::string location;
std::string user_data_folder;
HANDLE shutdown_begin_handle;
HANDLE shutdown_end_handle;
WebView2State state = WEBVIEW2_STATE_INIT;
@ -750,6 +759,13 @@ gst_webview2_object_class_init (GstWebView2ObjectClass * klass)
GST_TYPE_D3D11_DEVICE, (GParamFlags)
(G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS)));
g_object_class_install_property (object_class, PROP_USER_DATA_FOLDER,
g_param_spec_string ("user-data-folder", "User Data Folder",
"User data folder location. Default location is ${APP_EXE}.WebView2 "
"but can be varying depending on platform",
nullptr, (GParamFlags) (G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS)));
}
static void
@ -801,6 +817,13 @@ gst_webview2_set_property (GObject * object, guint prop_id,
case PROP_DEVICE:
priv->device = (GstD3D11Device *) g_value_dup_object (value);
break;
case PROP_USER_DATA_FOLDER:
{
auto udf = g_value_get_string (value);
if (udf)
priv->user_data_folder = udf;
break;
}
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -820,6 +843,12 @@ gst_webview2_event_loop (GstWebView2Object * self)
HANDLE waitables[] = { priv->shutdown_begin_handle,
priv->shutdown_end_handle
};
gunichar2 *udf_location = nullptr;
if (!priv->user_data_folder.empty ()) {
udf_location = g_utf8_to_utf16 (priv->user_data_folder.c_str (),
-1, nullptr, nullptr, nullptr);
}
GST_D3D11_CALL_ONCE_BEGIN {
WNDCLASSEXA wc = { };
@ -864,7 +893,7 @@ gst_webview2_event_loop (GstWebView2Object * self)
}
hr = MakeAndInitialize < GstWebView2Item > (&priv->item, self, priv->device,
priv->shutdown_begin_handle, hwnd);
priv->shutdown_begin_handle, hwnd, (PCWSTR) udf_location);
if (FAILED (hr)) {
GST_ERROR_OBJECT (self, "Couldn't initialize item");
goto out;
@ -919,6 +948,8 @@ out:
priv->queue = nullptr;
if (hwnd)
CloseWindow (hwnd);
g_free (udf_location);
}
static gpointer
@ -964,14 +995,16 @@ gst_webview2_object_frame_arrived (GstWebView2Object * obj,
}
GstWebView2Object *
gst_webview2_object_new (GstD3D11Device * device)
gst_webview2_object_new (GstD3D11Device * device,
const std::string & user_data_folder)
{
GstWebView2Object *self;
g_return_val_if_fail (GST_IS_D3D11_DEVICE (device), nullptr);
self = (GstWebView2Object *)
g_object_new (GST_TYPE_WEBVIEW2_OBJECT, "device", device, nullptr);
g_object_new (GST_TYPE_WEBVIEW2_OBJECT, "device", device,
"user-data-folder", user_data_folder.c_str (), nullptr);
gst_object_ref_sink (self);
if (self->priv->state != WEBVIEW2_STATE_RUNNING) {

View file

@ -31,7 +31,8 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (GstWebView2Object, gst_webview2_object,
GST, WEBVIEW2_OBJECT, GstObject);
GstWebView2Object * gst_webview2_object_new (GstD3D11Device * device);
GstWebView2Object * gst_webview2_object_new (GstD3D11Device * device,
const std::string & user_data_folder);
gboolean gst_webview2_object_set_location (GstWebView2Object * client,
const std::string & location,

View file

@ -61,6 +61,7 @@ enum
PROP_LOCATION,
PROP_PROCESSING_DEADLINE,
PROP_JAVASCRIPT,
PROP_USER_DATA_FOLDER,
};
#define DEFAULT_LOCATION "about:blank"
@ -130,6 +131,7 @@ struct GstWebView2SrcPrivate
std::string location = DEFAULT_LOCATION;
GstClockTime processing_deadline = DEFAULT_PROCESSING_DEADLINE;
std::string script;
std::string user_data_folder;
};
/* *INDENT-ON* */
@ -205,6 +207,12 @@ gst_webview2_src_class_init (GstWebView2SrcClass * klass)
nullptr, (GParamFlags) (G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS | GST_PARAM_MUTABLE_PLAYING)));
g_object_class_install_property (object_class, PROP_USER_DATA_FOLDER,
g_param_spec_string ("user-data-folder", "User Data Folder",
"Absolute path to WebView2 user data folder location.", nullptr,
(GParamFlags) (G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS | GST_PARAM_MUTABLE_READY)));
gst_element_class_set_static_metadata (element_class,
"WebView2 Source", "Source/Video",
"Creates a video stream rendered by WebView2",
@ -314,6 +322,15 @@ gst_webview2_src_set_property (GObject * object, guint prop_id,
}
break;
}
case PROP_USER_DATA_FOLDER:
{
auto udf = g_value_get_string (value);
if (udf)
priv->user_data_folder = udf;
else
priv->user_data_folder.clear ();
break;
}
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -341,6 +358,9 @@ gst_win32_video_src_get_property (GObject * object, guint prop_id,
case PROP_JAVASCRIPT:
g_value_set_string (value, priv->script.c_str ());
break;
case PROP_USER_DATA_FOLDER:
g_value_set_string (value, priv->script.c_str ());
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -417,7 +437,7 @@ gst_webview2_src_start (GstBaseSrc * src)
GST_DEBUG_OBJECT (self, "D3D12 copy support: %d", priv->can_d3d12_copy);
std::lock_guard < std::mutex > lk (priv->lock);
priv->object = gst_webview2_object_new (priv->device);
priv->object = gst_webview2_object_new (priv->device, priv->user_data_folder);
if (!priv->object) {
GST_ERROR_OBJECT (self, "Couldn't create object");
return FALSE;