Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Williams2019-12-03 21:11:55 +0000
committerEric Williams2019-12-13 21:31:42 +0000
commit558be9a19c6de3c914ccbed0ac541d5c849bf1f5 (patch)
tree599a513d65d4b11a8c98627082db8d2a7856a5b3
parent2448b23298cb6461d8084ff2593718867e03fc48 (diff)
downloadeclipse.platform.swt-558be9a19c6de3c914ccbed0ac541d5c849bf1f5.tar.gz
eclipse.platform.swt-558be9a19c6de3c914ccbed0ac541d5c849bf1f5.tar.xz
eclipse.platform.swt-558be9a19c6de3c914ccbed0ac541d5c849bf1f5.zip
Bug 540060: The webkit dbus IPC should use a private bus
Convert WebKit code in SWT to use a private bus system instead of registering a public GDBus service on the system. How this works: 1) SWT creates a GDBusServer with an address. 2) This address is passed to the web extension on initialization. 3) The web extension creates its own GDBusServer with its own address. 4) The web extension then connects back to the SWT main process (recall step 2) with its own server address created in 3). 5) The SWT main process connects to the web extension via GDBusConnection. 6) Methods defined in the SWT GDBusServer and the web extension's GDBusServer are called via g_dbus_connection_call* methods. In summary: -SWT main process has a server and a connection to the extension -SWT web extension has a server and a connection to the SWT main process All functionality operates as before, just instead of registering a proxy with the system, the communication happens over private GDBusConnections. Some implementation notes: - We need to worry about disposing GDBus related objects to prevent leaks. - Disposal happens in the SWT main process, the only thing the web extension disposes is its own server (all connections are disposed of in SWT). - Disposal won't happen until the Display is released. - Authentication is a thing now: only processes owned by the same user as the SWT main process can connect to any of these DBus services. - Communication happens on GDBus services via a unix socket created in the /tmp directory. Tested on GTK3.24 with Fedora 30 and 31. No AllBrowserTests fail. Snippets from BrowserFunction related bugs maintain functionality. Red Hat Central in JBoss Tools also works as expected. Change-Id: Ife2c5260b22d927cc95aecc710f808e9e5bf89d7 Signed-off-by: Eric Williams <ericwill@redhat.com>
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c309
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c23
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h23
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java333
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_extension.c292
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_extension.h14
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java41
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebkitGDBus.java463
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java67
9 files changed, 1204 insertions, 361 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c
index 859f6fbdd1..613f2ed389 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c
@@ -14629,6 +14629,171 @@ fail:
}
#endif
+#ifndef NO__1g_1credentials_1is_1same_1user
+JNIEXPORT jboolean JNICALL OS_NATIVE(_1g_1credentials_1is_1same_1user)
+ (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlongArray arg2)
+{
+ jlong *lparg2=NULL;
+ jboolean rc = 0;
+ OS_NATIVE_ENTER(env, that, _1g_1credentials_1is_1same_1user_FUNC);
+ if (arg2) if ((lparg2 = (*env)->GetLongArrayElements(env, arg2, NULL)) == NULL) goto fail;
+ rc = (jboolean)g_credentials_is_same_user((GCredentials *)arg0, (GCredentials *)arg1, (GError **)lparg2);
+fail:
+ if (arg2 && lparg2) (*env)->ReleaseLongArrayElements(env, arg2, lparg2, 0);
+ OS_NATIVE_EXIT(env, that, _1g_1credentials_1is_1same_1user_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO__1g_1credentials_1new
+JNIEXPORT jlong JNICALL OS_NATIVE(_1g_1credentials_1new)
+ (JNIEnv *env, jclass that)
+{
+ jlong rc = 0;
+ OS_NATIVE_ENTER(env, that, _1g_1credentials_1new_FUNC);
+ rc = (jlong)g_credentials_new();
+ OS_NATIVE_EXIT(env, that, _1g_1credentials_1new_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO__1g_1dbus_1auth_1observer_1new
+JNIEXPORT jlong JNICALL OS_NATIVE(_1g_1dbus_1auth_1observer_1new)
+ (JNIEnv *env, jclass that)
+{
+ jlong rc = 0;
+ OS_NATIVE_ENTER(env, that, _1g_1dbus_1auth_1observer_1new_FUNC);
+ rc = (jlong)g_dbus_auth_observer_new();
+ OS_NATIVE_EXIT(env, that, _1g_1dbus_1auth_1observer_1new_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO__1g_1dbus_1connection_1call
+JNIEXPORT void JNICALL OS_NATIVE(_1g_1dbus_1connection_1call)
+ (JNIEnv *env, jclass that, jlong arg0, jbyteArray arg1, jbyteArray arg2, jbyteArray arg3, jbyteArray arg4, jlong arg5, jlong arg6, jint arg7, jint arg8, jlong arg9, jlong arg10, jlong arg11)
+{
+ jbyte *lparg1=NULL;
+ jbyte *lparg2=NULL;
+ jbyte *lparg3=NULL;
+ jbyte *lparg4=NULL;
+ OS_NATIVE_ENTER(env, that, _1g_1dbus_1connection_1call_FUNC);
+ if (arg1) if ((lparg1 = (*env)->GetByteArrayElements(env, arg1, NULL)) == NULL) goto fail;
+ if (arg2) if ((lparg2 = (*env)->GetByteArrayElements(env, arg2, NULL)) == NULL) goto fail;
+ if (arg3) if ((lparg3 = (*env)->GetByteArrayElements(env, arg3, NULL)) == NULL) goto fail;
+ if (arg4) if ((lparg4 = (*env)->GetByteArrayElements(env, arg4, NULL)) == NULL) goto fail;
+ g_dbus_connection_call((GDBusConnection *)arg0, (const gchar *)lparg1, (const gchar *)lparg2, (const gchar *)lparg3, (const gchar *)lparg4, (GVariant *)arg5, (const GVariantType *)arg6, arg7, arg8, (GCancellable *)arg9, (GAsyncReadyCallback)arg10, (gpointer)arg11);
+fail:
+ if (arg4 && lparg4) (*env)->ReleaseByteArrayElements(env, arg4, lparg4, 0);
+ if (arg3 && lparg3) (*env)->ReleaseByteArrayElements(env, arg3, lparg3, 0);
+ if (arg2 && lparg2) (*env)->ReleaseByteArrayElements(env, arg2, lparg2, 0);
+ if (arg1 && lparg1) (*env)->ReleaseByteArrayElements(env, arg1, lparg1, 0);
+ OS_NATIVE_EXIT(env, that, _1g_1dbus_1connection_1call_FUNC);
+}
+#endif
+
+#ifndef NO__1g_1dbus_1connection_1call_1finish
+JNIEXPORT jlong JNICALL OS_NATIVE(_1g_1dbus_1connection_1call_1finish)
+ (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlongArray arg2)
+{
+ jlong *lparg2=NULL;
+ jlong rc = 0;
+ OS_NATIVE_ENTER(env, that, _1g_1dbus_1connection_1call_1finish_FUNC);
+ if (arg2) if ((lparg2 = (*env)->GetLongArrayElements(env, arg2, NULL)) == NULL) goto fail;
+ rc = (jlong)g_dbus_connection_call_finish((GDBusConnection *)arg0, (GAsyncResult *)arg1, (GError **)lparg2);
+fail:
+ if (arg2 && lparg2) (*env)->ReleaseLongArrayElements(env, arg2, lparg2, 0);
+ OS_NATIVE_EXIT(env, that, _1g_1dbus_1connection_1call_1finish_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO__1g_1dbus_1connection_1call_1sync
+JNIEXPORT jlong JNICALL OS_NATIVE(_1g_1dbus_1connection_1call_1sync)
+ (JNIEnv *env, jclass that, jlong arg0, jbyteArray arg1, jbyteArray arg2, jbyteArray arg3, jbyteArray arg4, jlong arg5, jlong arg6, jint arg7, jint arg8, jlong arg9, jlongArray arg10)
+{
+ jbyte *lparg1=NULL;
+ jbyte *lparg2=NULL;
+ jbyte *lparg3=NULL;
+ jbyte *lparg4=NULL;
+ jlong *lparg10=NULL;
+ jlong rc = 0;
+ OS_NATIVE_ENTER(env, that, _1g_1dbus_1connection_1call_1sync_FUNC);
+ if (arg1) if ((lparg1 = (*env)->GetByteArrayElements(env, arg1, NULL)) == NULL) goto fail;
+ if (arg2) if ((lparg2 = (*env)->GetByteArrayElements(env, arg2, NULL)) == NULL) goto fail;
+ if (arg3) if ((lparg3 = (*env)->GetByteArrayElements(env, arg3, NULL)) == NULL) goto fail;
+ if (arg4) if ((lparg4 = (*env)->GetByteArrayElements(env, arg4, NULL)) == NULL) goto fail;
+ if (arg10) if ((lparg10 = (*env)->GetLongArrayElements(env, arg10, NULL)) == NULL) goto fail;
+ rc = (jlong)g_dbus_connection_call_sync((GDBusConnection *)arg0, (const gchar *)lparg1, (const gchar *)lparg2, (const gchar *)lparg3, (const gchar *)lparg4, (GVariant *)arg5, (const GVariantType *)arg6, arg7, arg8, (GCancellable *)arg9, (GError **)lparg10);
+fail:
+ if (arg10 && lparg10) (*env)->ReleaseLongArrayElements(env, arg10, lparg10, 0);
+ if (arg4 && lparg4) (*env)->ReleaseByteArrayElements(env, arg4, lparg4, 0);
+ if (arg3 && lparg3) (*env)->ReleaseByteArrayElements(env, arg3, lparg3, 0);
+ if (arg2 && lparg2) (*env)->ReleaseByteArrayElements(env, arg2, lparg2, 0);
+ if (arg1 && lparg1) (*env)->ReleaseByteArrayElements(env, arg1, lparg1, 0);
+ OS_NATIVE_EXIT(env, that, _1g_1dbus_1connection_1call_1sync_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO__1g_1dbus_1connection_1close_1sync
+JNIEXPORT jboolean JNICALL OS_NATIVE(_1g_1dbus_1connection_1close_1sync)
+ (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlongArray arg2)
+{
+ jlong *lparg2=NULL;
+ jboolean rc = 0;
+ OS_NATIVE_ENTER(env, that, _1g_1dbus_1connection_1close_1sync_FUNC);
+ if (arg2) if ((lparg2 = (*env)->GetLongArrayElements(env, arg2, NULL)) == NULL) goto fail;
+ rc = (jboolean)g_dbus_connection_close_sync((GDBusConnection *)arg0, (GCancellable *)arg1, (GError **)lparg2);
+fail:
+ if (arg2 && lparg2) (*env)->ReleaseLongArrayElements(env, arg2, lparg2, 0);
+ OS_NATIVE_EXIT(env, that, _1g_1dbus_1connection_1close_1sync_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO__1g_1dbus_1connection_1is_1closed
+JNIEXPORT jboolean JNICALL OS_NATIVE(_1g_1dbus_1connection_1is_1closed)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ jboolean rc = 0;
+ OS_NATIVE_ENTER(env, that, _1g_1dbus_1connection_1is_1closed_FUNC);
+ rc = (jboolean)g_dbus_connection_is_closed((GDBusConnection *)arg0);
+ OS_NATIVE_EXIT(env, that, _1g_1dbus_1connection_1is_1closed_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO__1g_1dbus_1connection_1new_1for_1address
+JNIEXPORT void JNICALL OS_NATIVE(_1g_1dbus_1connection_1new_1for_1address)
+ (JNIEnv *env, jclass that, jbyteArray arg0, jint arg1, jlong arg2, jlong arg3, jlong arg4, jlong arg5)
+{
+ jbyte *lparg0=NULL;
+ OS_NATIVE_ENTER(env, that, _1g_1dbus_1connection_1new_1for_1address_FUNC);
+ if (arg0) if ((lparg0 = (*env)->GetByteArrayElements(env, arg0, NULL)) == NULL) goto fail;
+ g_dbus_connection_new_for_address((const gchar *)lparg0, arg1, (GDBusAuthObserver *)arg2, (GCancellable *)arg3, (GAsyncReadyCallback)arg4, (gpointer)arg5);
+fail:
+ if (arg0 && lparg0) (*env)->ReleaseByteArrayElements(env, arg0, lparg0, 0);
+ OS_NATIVE_EXIT(env, that, _1g_1dbus_1connection_1new_1for_1address_FUNC);
+}
+#endif
+
+#ifndef NO__1g_1dbus_1connection_1new_1for_1address_1finish
+JNIEXPORT jlong JNICALL OS_NATIVE(_1g_1dbus_1connection_1new_1for_1address_1finish)
+ (JNIEnv *env, jclass that, jlong arg0, jlongArray arg1)
+{
+ jlong *lparg1=NULL;
+ jlong rc = 0;
+ OS_NATIVE_ENTER(env, that, _1g_1dbus_1connection_1new_1for_1address_1finish_FUNC);
+ if (arg1) if ((lparg1 = (*env)->GetLongArrayElements(env, arg1, NULL)) == NULL) goto fail;
+ rc = (jlong)g_dbus_connection_new_for_address_finish((GAsyncResult *)arg0, (GError **)lparg1);
+fail:
+ if (arg1 && lparg1) (*env)->ReleaseLongArrayElements(env, arg1, lparg1, 0);
+ OS_NATIVE_EXIT(env, that, _1g_1dbus_1connection_1new_1for_1address_1finish_FUNC);
+ return rc;
+}
+#endif
+
#ifndef NO__1g_1dbus_1connection_1register_1object
JNIEXPORT jint JNICALL OS_NATIVE(_1g_1dbus_1connection_1register_1object)
(JNIEnv *env, jclass that, jlong arg0, jbyteArray arg1, jlong arg2, jlongArray arg3, jlong arg4, jlong arg5, jlongArray arg6)
@@ -14651,6 +14816,18 @@ fail:
}
#endif
+#ifndef NO__1g_1dbus_1generate_1guid
+JNIEXPORT jlong JNICALL OS_NATIVE(_1g_1dbus_1generate_1guid)
+ (JNIEnv *env, jclass that)
+{
+ jlong rc = 0;
+ OS_NATIVE_ENTER(env, that, _1g_1dbus_1generate_1guid_FUNC);
+ rc = (jlong)g_dbus_generate_guid();
+ OS_NATIVE_EXIT(env, that, _1g_1dbus_1generate_1guid_FUNC);
+ return rc;
+}
+#endif
+
#ifndef NO__1g_1dbus_1method_1invocation_1return_1value
JNIEXPORT void JNICALL OS_NATIVE(_1g_1dbus_1method_1invocation_1return_1value)
(JNIEnv *env, jclass that, jlong arg0, jlong arg1)
@@ -14749,6 +14926,70 @@ fail:
}
#endif
+#ifndef NO__1g_1dbus_1server_1get_1client_1address
+JNIEXPORT jlong JNICALL OS_NATIVE(_1g_1dbus_1server_1get_1client_1address)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ jlong rc = 0;
+ OS_NATIVE_ENTER(env, that, _1g_1dbus_1server_1get_1client_1address_FUNC);
+ rc = (jlong)g_dbus_server_get_client_address((GDBusServer *)arg0);
+ OS_NATIVE_EXIT(env, that, _1g_1dbus_1server_1get_1client_1address_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO__1g_1dbus_1server_1new_1sync
+JNIEXPORT jlong JNICALL OS_NATIVE(_1g_1dbus_1server_1new_1sync)
+ (JNIEnv *env, jclass that, jlong arg0, jint arg1, jlong arg2, jlong arg3, jlong arg4, jlongArray arg5)
+{
+ jlong *lparg5=NULL;
+ jlong rc = 0;
+ OS_NATIVE_ENTER(env, that, _1g_1dbus_1server_1new_1sync_FUNC);
+ if (arg5) if ((lparg5 = (*env)->GetLongArrayElements(env, arg5, NULL)) == NULL) goto fail;
+ rc = (jlong)g_dbus_server_new_sync((const gchar *)arg0, (GDBusServerFlags)arg1, (const gchar *)arg2, (GDBusAuthObserver *)arg3, (GCancellable *)arg4, (GError **)lparg5);
+fail:
+ if (arg5 && lparg5) (*env)->ReleaseLongArrayElements(env, arg5, lparg5, 0);
+ OS_NATIVE_EXIT(env, that, _1g_1dbus_1server_1new_1sync_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO__1g_1dbus_1server_1start
+JNIEXPORT void JNICALL OS_NATIVE(_1g_1dbus_1server_1start)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ OS_NATIVE_ENTER(env, that, _1g_1dbus_1server_1start_FUNC);
+ g_dbus_server_start((GDBusServer *)arg0);
+ OS_NATIVE_EXIT(env, that, _1g_1dbus_1server_1start_FUNC);
+}
+#endif
+
+#ifndef NO__1g_1dbus_1server_1stop
+JNIEXPORT void JNICALL OS_NATIVE(_1g_1dbus_1server_1stop)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ OS_NATIVE_ENTER(env, that, _1g_1dbus_1server_1stop_FUNC);
+ g_dbus_server_stop((GDBusServer *)arg0);
+ OS_NATIVE_EXIT(env, that, _1g_1dbus_1server_1stop_FUNC);
+}
+#endif
+
+#ifndef NO__1g_1dir_1make_1tmp
+JNIEXPORT jlong JNICALL OS_NATIVE(_1g_1dir_1make_1tmp)
+ (JNIEnv *env, jclass that, jlong arg0, jlongArray arg1)
+{
+ jlong *lparg1=NULL;
+ jlong rc = 0;
+ OS_NATIVE_ENTER(env, that, _1g_1dir_1make_1tmp_FUNC);
+ if (arg1) if ((lparg1 = (*env)->GetLongArrayElements(env, arg1, NULL)) == NULL) goto fail;
+ rc = (jlong)g_dir_make_tmp((const gchar *)arg0, (GError **)lparg1);
+fail:
+ if (arg1 && lparg1) (*env)->ReleaseLongArrayElements(env, arg1, lparg1, 0);
+ OS_NATIVE_EXIT(env, that, _1g_1dir_1make_1tmp_FUNC);
+ return rc;
+}
+#endif
+
#ifndef NO__1g_1error_1free
JNIEXPORT void JNICALL OS_NATIVE(_1g_1error_1free)
(JNIEnv *env, jclass that, jlong arg0)
@@ -14976,6 +15217,18 @@ JNIEXPORT void JNICALL OS_NATIVE(_1g_1get_1current_1time)
}
#endif
+#ifndef NO__1g_1get_1user_1name
+JNIEXPORT jlong JNICALL OS_NATIVE(_1g_1get_1user_1name)
+ (JNIEnv *env, jclass that)
+{
+ jlong rc = 0;
+ OS_NATIVE_ENTER(env, that, _1g_1get_1user_1name_FUNC);
+ rc = (jlong)g_get_user_name();
+ OS_NATIVE_EXIT(env, that, _1g_1get_1user_1name_FUNC);
+ return rc;
+}
+#endif
+
#ifndef NO__1g_1getenv
JNIEXPORT jlong JNICALL OS_NATIVE(_1g_1getenv)
(JNIEnv *env, jclass that, jbyteArray arg0)
@@ -15896,6 +16149,30 @@ JNIEXPORT jboolean JNICALL OS_NATIVE(_1g_1source_1remove)
}
#endif
+#ifndef NO__1g_1strconcat__JJJ
+JNIEXPORT jlong JNICALL OS_NATIVE(_1g_1strconcat__JJJ)
+ (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlong arg2)
+{
+ jlong rc = 0;
+ OS_NATIVE_ENTER(env, that, _1g_1strconcat__JJJ_FUNC);
+ rc = (jlong)g_strconcat((const gchar *)arg0, (const gchar *)arg1, (const gchar *)NULL);
+ OS_NATIVE_EXIT(env, that, _1g_1strconcat__JJJ_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO__1g_1strconcat__JJJJ
+JNIEXPORT jlong JNICALL OS_NATIVE(_1g_1strconcat__JJJJ)
+ (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlong arg2, jlong arg3)
+{
+ jlong rc = 0;
+ OS_NATIVE_ENTER(env, that, _1g_1strconcat__JJJJ_FUNC);
+ rc = (jlong)g_strconcat((const gchar *)arg0, (const gchar *)arg1, (const gchar *)arg2, (const gchar *)NULL);
+ OS_NATIVE_EXIT(env, that, _1g_1strconcat__JJJJ_FUNC);
+ return rc;
+}
+#endif
+
#ifndef NO__1g_1strfreev
JNIEXPORT void JNICALL OS_NATIVE(_1g_1strfreev)
(JNIEnv *env, jclass that, jlong arg0)
@@ -16475,18 +16752,30 @@ JNIEXPORT jlong JNICALL OS_NATIVE(_1g_1variant_1new_1int32)
}
#endif
-#ifndef NO__1g_1variant_1new_1string
-JNIEXPORT jlong JNICALL OS_NATIVE(_1g_1variant_1new_1string)
+#ifndef NO__1g_1variant_1new_1string__J
+JNIEXPORT jlong JNICALL OS_NATIVE(_1g_1variant_1new_1string__J)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ jlong rc = 0;
+ OS_NATIVE_ENTER(env, that, _1g_1variant_1new_1string__J_FUNC);
+ rc = (jlong)g_variant_new_string((const gchar *)arg0);
+ OS_NATIVE_EXIT(env, that, _1g_1variant_1new_1string__J_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO__1g_1variant_1new_1string___3B
+JNIEXPORT jlong JNICALL OS_NATIVE(_1g_1variant_1new_1string___3B)
(JNIEnv *env, jclass that, jbyteArray arg0)
{
jbyte *lparg0=NULL;
jlong rc = 0;
- OS_NATIVE_ENTER(env, that, _1g_1variant_1new_1string_FUNC);
+ OS_NATIVE_ENTER(env, that, _1g_1variant_1new_1string___3B_FUNC);
if (arg0) if ((lparg0 = (*env)->GetByteArrayElements(env, arg0, NULL)) == NULL) goto fail;
rc = (jlong)g_variant_new_string((const gchar *)lparg0);
fail:
if (arg0 && lparg0) (*env)->ReleaseByteArrayElements(env, arg0, lparg0, 0);
- OS_NATIVE_EXIT(env, that, _1g_1variant_1new_1string_FUNC);
+ OS_NATIVE_EXIT(env, that, _1g_1variant_1new_1string___3B_FUNC);
return rc;
}
#endif
@@ -16555,18 +16844,6 @@ JNIEXPORT void JNICALL OS_NATIVE(_1g_1variant_1unref)
}
#endif
-#ifndef NO__1getpid
-JNIEXPORT jint JNICALL OS_NATIVE(_1getpid)
- (JNIEnv *env, jclass that)
-{
- jint rc = 0;
- OS_NATIVE_ENTER(env, that, _1getpid_FUNC);
- rc = (jint)getpid();
- OS_NATIVE_EXIT(env, that, _1getpid_FUNC);
- return rc;
-}
-#endif
-
#ifndef NO__1glib_1major_1version
JNIEXPORT jint JNICALL OS_NATIVE(_1glib_1major_1version)
(JNIEnv *env, jclass that)
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c
index 6e34c81e90..ab0481d139 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c
@@ -1218,13 +1218,29 @@ char * OS_nativeFunctionNames[] = {
"_1g_1closure_1unref",
"_1g_1content_1type_1equals",
"_1g_1content_1type_1is_1a",
+ "_1g_1credentials_1is_1same_1user",
+ "_1g_1credentials_1new",
+ "_1g_1dbus_1auth_1observer_1new",
+ "_1g_1dbus_1connection_1call",
+ "_1g_1dbus_1connection_1call_1finish",
+ "_1g_1dbus_1connection_1call_1sync",
+ "_1g_1dbus_1connection_1close_1sync",
+ "_1g_1dbus_1connection_1is_1closed",
+ "_1g_1dbus_1connection_1new_1for_1address",
+ "_1g_1dbus_1connection_1new_1for_1address_1finish",
"_1g_1dbus_1connection_1register_1object",
+ "_1g_1dbus_1generate_1guid",
"_1g_1dbus_1method_1invocation_1return_1value",
"_1g_1dbus_1node_1info_1lookup_1interface",
"_1g_1dbus_1node_1info_1new_1for_1xml",
"_1g_1dbus_1proxy_1call_1finish",
"_1g_1dbus_1proxy_1get_1name_1owner",
"_1g_1dbus_1proxy_1new_1for_1bus_1sync",
+ "_1g_1dbus_1server_1get_1client_1address",
+ "_1g_1dbus_1server_1new_1sync",
+ "_1g_1dbus_1server_1start",
+ "_1g_1dbus_1server_1stop",
+ "_1g_1dir_1make_1tmp",
"_1g_1error_1free",
"_1g_1error_1get_1message",
"_1g_1file_1get_1uri",
@@ -1240,6 +1256,7 @@ char * OS_nativeFunctionNames[] = {
"_1g_1filename_1to_1uri",
"_1g_1filename_1to_1utf8",
"_1g_1get_1current_1time",
+ "_1g_1get_1user_1name",
"_1g_1getenv",
"_1g_1icon_1new_1for_1string",
"_1g_1icon_1to_1string",
@@ -1310,6 +1327,8 @@ char * OS_nativeFunctionNames[] = {
"_1g_1slist_1length",
"_1g_1slist_1next",
"_1g_1source_1remove",
+ "_1g_1strconcat__JJJ",
+ "_1g_1strconcat__JJJJ",
"_1g_1strfreev",
"_1g_1string_1free",
"_1g_1string_1new_1len",
@@ -1356,13 +1375,13 @@ char * OS_nativeFunctionNames[] = {
"_1g_1variant_1new_1byte",
"_1g_1variant_1new_1double",
"_1g_1variant_1new_1int32",
- "_1g_1variant_1new_1string",
+ "_1g_1variant_1new_1string__J",
+ "_1g_1variant_1new_1string___3B",
"_1g_1variant_1new_1tuple",
"_1g_1variant_1new_1uint64",
"_1g_1variant_1type_1free",
"_1g_1variant_1type_1new",
"_1g_1variant_1unref",
- "_1getpid",
"_1glib_1major_1version",
"_1glib_1micro_1version",
"_1glib_1minor_1version",
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h
index e82617572e..10903b9c97 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h
@@ -1192,13 +1192,29 @@ typedef enum {
_1g_1closure_1unref_FUNC,
_1g_1content_1type_1equals_FUNC,
_1g_1content_1type_1is_1a_FUNC,
+ _1g_1credentials_1is_1same_1user_FUNC,
+ _1g_1credentials_1new_FUNC,
+ _1g_1dbus_1auth_1observer_1new_FUNC,
+ _1g_1dbus_1connection_1call_FUNC,
+ _1g_1dbus_1connection_1call_1finish_FUNC,
+ _1g_1dbus_1connection_1call_1sync_FUNC,
+ _1g_1dbus_1connection_1close_1sync_FUNC,
+ _1g_1dbus_1connection_1is_1closed_FUNC,
+ _1g_1dbus_1connection_1new_1for_1address_FUNC,
+ _1g_1dbus_1connection_1new_1for_1address_1finish_FUNC,
_1g_1dbus_1connection_1register_1object_FUNC,
+ _1g_1dbus_1generate_1guid_FUNC,
_1g_1dbus_1method_1invocation_1return_1value_FUNC,
_1g_1dbus_1node_1info_1lookup_1interface_FUNC,
_1g_1dbus_1node_1info_1new_1for_1xml_FUNC,
_1g_1dbus_1proxy_1call_1finish_FUNC,
_1g_1dbus_1proxy_1get_1name_1owner_FUNC,
_1g_1dbus_1proxy_1new_1for_1bus_1sync_FUNC,
+ _1g_1dbus_1server_1get_1client_1address_FUNC,
+ _1g_1dbus_1server_1new_1sync_FUNC,
+ _1g_1dbus_1server_1start_FUNC,
+ _1g_1dbus_1server_1stop_FUNC,
+ _1g_1dir_1make_1tmp_FUNC,
_1g_1error_1free_FUNC,
_1g_1error_1get_1message_FUNC,
_1g_1file_1get_1uri_FUNC,
@@ -1214,6 +1230,7 @@ typedef enum {
_1g_1filename_1to_1uri_FUNC,
_1g_1filename_1to_1utf8_FUNC,
_1g_1get_1current_1time_FUNC,
+ _1g_1get_1user_1name_FUNC,
_1g_1getenv_FUNC,
_1g_1icon_1new_1for_1string_FUNC,
_1g_1icon_1to_1string_FUNC,
@@ -1284,6 +1301,8 @@ typedef enum {
_1g_1slist_1length_FUNC,
_1g_1slist_1next_FUNC,
_1g_1source_1remove_FUNC,
+ _1g_1strconcat__JJJ_FUNC,
+ _1g_1strconcat__JJJJ_FUNC,
_1g_1strfreev_FUNC,
_1g_1string_1free_FUNC,
_1g_1string_1new_1len_FUNC,
@@ -1330,13 +1349,13 @@ typedef enum {
_1g_1variant_1new_1byte_FUNC,
_1g_1variant_1new_1double_FUNC,
_1g_1variant_1new_1int32_FUNC,
- _1g_1variant_1new_1string_FUNC,
+ _1g_1variant_1new_1string__J_FUNC,
+ _1g_1variant_1new_1string___3B_FUNC,
_1g_1variant_1new_1tuple_FUNC,
_1g_1variant_1new_1uint64_FUNC,
_1g_1variant_1type_1free_FUNC,
_1g_1variant_1type_1new_FUNC,
_1g_1variant_1unref_FUNC,
- _1getpid_FUNC,
_1glib_1major_1version_FUNC,
_1glib_1micro_1version_FUNC,
_1glib_1minor_1version_FUNC,
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java
index 55b22cc276..01362f35b1 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java
@@ -222,6 +222,10 @@ public class OS extends C {
public static final int G_DBUS_CALL_FLAGS_NONE = 0;
public static final int G_DBUS_CALL_FLAGS_NO_AUTO_START = (1<<0);
+ public static final int G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT = 1;
+
+ public static final int G_DBUS_SERVER_FLAGS_NONE = 0;
+
/**
* DBus Data types as defined by:
* https://dbus.freedesktop.org/doc/dbus-specification.html#idm423
@@ -279,6 +283,7 @@ public class OS extends C {
public static final byte[] accel_closures_changed = ascii("accel-closures-changed"); // Gtk2,3,4
public static final byte[] activate = ascii("activate"); // ?
public static final byte[] angle_changed = ascii("angle_changed"); // Gtk3/4, Guesture related.
+ public static final byte[] authorize_authenticated_peer = ascii("authorize-authenticated-peer");
public static final byte[] backspace = ascii("backspace");
public static final byte[] begin = ascii("begin");
public static final byte[] button_press_event = ascii("button-press-event");
@@ -346,6 +351,7 @@ public class OS extends C {
public static final byte[] motion = ascii("motion");
public static final byte[] move_cursor = ascii("move-cursor");
public static final byte[] move_focus = ascii("move-focus");
+ public static final byte[] new_connection = ascii("new-connection");
public static final byte[] output = ascii("output");
public static final byte[] paste_clipboard = ascii("paste-clipboard");
public static final byte[] pressed = ascii("pressed");
@@ -1378,6 +1384,29 @@ public static final boolean g_content_type_is_a(long type, byte[] supertype) {
lock.unlock();
}
}
+public static final native long _g_credentials_new();
+public static final long g_credentials_new() {
+ lock.lock();
+ try {
+ return _g_credentials_new();
+ } finally {
+ lock.unlock();
+ }
+}
+/**
+ * @param credentials cast=(GCredentials *)
+ * @param other_credentials cast=(GCredentials *)
+ * @param error cast=(GError **)
+ */
+public static final native boolean _g_credentials_is_same_user(long credentials, long other_credentials, long [] error);
+public static final boolean g_credentials_is_same_user(long credentials, long other_credentials, long [] error) {
+ lock.lock();
+ try {
+ return _g_credentials_is_same_user(credentials, other_credentials, error);
+ } finally {
+ lock.unlock();
+ }
+}
/**
* @param info cast=(GFileInfo *)
*/
@@ -1745,6 +1774,15 @@ public static final void g_get_current_time(long result) {
lock.unlock();
}
}
+public static final native long _g_get_user_name();
+public static final long g_get_user_name() {
+ lock.lock();
+ try {
+ return _g_get_user_name();
+ } finally {
+ lock.unlock();
+ }
+}
/**
* @param result cast=(GTimeVal *)
* @param microseconds cast=(glong)
@@ -2582,6 +2620,35 @@ public static final double g_strtod(long str, long [] endptr) {
lock.unlock();
}
}
+/**
+ * @param str cast=(const gchar *)
+ * @param str2 cast=(const gchar *)
+ * @param str3 cast=(const gchar *)
+ * @param terminator cast=(const gchar *),flags=sentinel
+ */
+public static final native long _g_strconcat(long str, long str2, long str3, long terminator);
+public static final long g_strconcat(long str, long str2, long str3, long terminator) {
+ lock.lock();
+ try {
+ return _g_strconcat(str, str2, str3, terminator);
+ } finally {
+ lock.unlock();
+ }
+}
+/**
+ * @param str cast=(const gchar *)
+ * @param str2 cast=(const gchar *)
+ * @param terminator cast=(const gchar *),flags=sentinel
+ */
+public static final native long _g_strconcat(long str, long str2, long terminator);
+public static final long g_strconcat(long str, long str2, long terminator) {
+ lock.lock();
+ try {
+ return _g_strconcat(str, str2, terminator);
+ } finally {
+ lock.unlock();
+ }
+}
/** @param str cast=(char *) */
public static final native long g_strdup (long str);
/**
@@ -2865,20 +2932,6 @@ public static final boolean FcConfigAppFontAddFile(long config, byte[] file) {
}
}
-
-// Technically works on OSX also, but currently only used on Linux.
-// Once SWT is moved to Java 9, consider using 'ProcessHandle.current().getPid();' instead,
-// but for now getpid() should do.
-// https://stackoverflow.com/questions/35842/how-can-a-java-program-get-its-own-process-id
-public static final native int _getpid ();
-public static final int getpid() {
- lock.lock();
- try {
- return _getpid();
- } finally {
- lock.unlock();
- }
-}
/**
* @param dest cast=(void *)
* @param src cast=(const void *),flags=no_out
@@ -4194,6 +4247,20 @@ public static final byte [] getThemeNameBytes() {
}
/**
+ * @param tmpl cast=(const gchar *)
+ * @param error cast=(GError **)
+ */
+public static final native long _g_dir_make_tmp (long tmpl, long [] error);
+public static final long g_dir_make_tmp (long tmpl, long [] error) {
+ lock.lock();
+ try {
+ return _g_dir_make_tmp (tmpl, error);
+ } finally {
+ lock.unlock();
+ }
+}
+
+/**
* @param info cast=(GDBusInterfaceInfo *)
* @param name cast=(const gchar *)
* @param object_path cast=(const gchar *)
@@ -4307,6 +4374,136 @@ public static final int g_bus_own_name (int bus_type, byte[] name, int flags, lo
/**
* @param connection cast=(GDBusConnection *)
+ * @param bus_name cast=(const gchar *)
+ * @param object_path cast=(const gchar *)
+ * @param interface_name cast=(const gchar *)
+ * @param method_name cast=(const gchar *)
+ * @param param cast=(GVariant *)
+ * @param reply_type cast=(const GVariantType *)
+ * @param cancellable cast=(GCancellable *)
+ * @param callback cast=(GAsyncReadyCallback)
+ * @param user_data cast=(gpointer)
+ * @category gdbus
+ */
+public static final native void _g_dbus_connection_call (long connection, byte [] bus_name, byte [] object_path, byte [] interface_name, byte [] method_name, long param, long reply_type, int flag, int timeout, long cancellable, long callback, long user_data);
+/** @category gdbus */
+public static final void g_dbus_connection_call (long connection, byte [] bus_name, byte [] object_path, byte [] interface_name, byte [] method_name, long param, long reply_type, int flag, int timeout, long cancellable, long callback, long user_data) {
+ lock.lock();
+ try {
+ _g_dbus_connection_call(connection, bus_name, object_path, interface_name, method_name, param, reply_type, flag, timeout, cancellable, callback, user_data);
+ } finally {
+ lock.unlock();
+ }
+}
+
+/**
+ * @param proxy cast=(GDBusConnection *)
+ * @param res cast=(GAsyncResult *)
+ * @param error cast=(GError **)
+ * @category gdbus
+ */
+public static final native long _g_dbus_connection_call_finish (long proxy, long res, long [] error);
+public static final long g_dbus_connection_call_finish (long proxy, long res, long [] error) {
+ lock.lock();
+ try {
+ return _g_dbus_connection_call_finish (proxy, res, error);
+ } finally {
+ lock.unlock();
+ }
+}
+
+/**
+ * @param connection cast=(GDBusConnection *)
+ * @param bus_name cast=(const gchar *)
+ * @param object_path cast=(const gchar *)
+ * @param interface_name cast=(const gchar *)
+ * @param method_name cast=(const gchar *)
+ * @param param cast=(GVariant *)
+ * @param reply_type cast=(const GVariantType *)
+ * @param cancellable cast=(GCancellable *)
+ * @param error cast=(GError **)
+ * @category gdbus
+ */
+public static final native long _g_dbus_connection_call_sync (long connection, byte [] bus_name, byte [] object_path, byte [] interface_name, byte [] method_name, long param, long reply_type, int flag, int timeout, long cancellable, long [] error);
+/** @category gdbus */
+public static final long g_dbus_connection_call_sync (long connection, byte [] bus_name, byte [] object_path, byte [] interface_name, byte [] method_name, long param, long reply_type, int flag, int timeout, long cancellable, long [] error) {
+ lock.lock();
+ try {
+ return _g_dbus_connection_call_sync(connection, bus_name, object_path, interface_name, method_name, param, reply_type, flag, timeout, cancellable, error);
+ } finally {
+ lock.unlock();
+ }
+}
+
+/**
+ * @param connection cast=(GDBusConnection *)
+ * @param cancellable cast=(GCancellable *)
+ * @param error cast=(GError **)
+ * @category gdbus
+ */
+public static final native boolean _g_dbus_connection_close_sync (long connection, long cancellable, long [] error);
+/** @category gdbus */
+public static final boolean g_dbus_connection_close_sync (long connection, long cancellable, long [] error) {
+ lock.lock();
+ try {
+ return _g_dbus_connection_close_sync(connection, cancellable, error);
+ } finally {
+ lock.unlock();
+ }
+}
+
+/**
+ * @param connection cast=(GDBusConnection *)
+ * @category gdbus
+ */
+public static final native boolean _g_dbus_connection_is_closed (long connection);
+/** @category gdbus */
+public static final boolean g_dbus_connection_is_closed (long connection) {
+ lock.lock();
+ try {
+ return _g_dbus_connection_is_closed(connection);
+ } finally {
+ lock.unlock();
+ }
+}
+
+/**
+ * @param address cast=(const gchar *)
+ * @param observer cast=(GDBusAuthObserver *)
+ * @param cancellable cast=(GCancellable *)
+ * @param callback cast=(GAsyncReadyCallback)
+ * @param user_data cast=(gpointer)
+ * @category gdbus
+ */
+public static final native void _g_dbus_connection_new_for_address (byte[] address, int flags, long observer, long cancellable, long callback, long user_data);
+/** @category gdbus */
+public static final void g_dbus_connection_new_for_address (byte[] address, int flags, long observer, long cancellable, long callback, long user_data) {
+ lock.lock();
+ try {
+ _g_dbus_connection_new_for_address(address, flags, observer, cancellable, callback, user_data);
+ } finally {
+ lock.unlock();
+ }
+}
+
+/**
+ * @param result cast=(GAsyncResult *)
+ * @param error cast=(GError **)
+ * @category gdbus
+ */
+public static final native long _g_dbus_connection_new_for_address_finish (long result, long [] error);
+/** @category gdbus */
+public static final long g_dbus_connection_new_for_address_finish (long result, long [] error) {
+ lock.lock();
+ try {
+ return _g_dbus_connection_new_for_address_finish(result, error);
+ } finally {
+ lock.unlock();
+ }
+}
+
+/**
+ * @param connection cast=(GDBusConnection *)
* @param object_path cast=(const gchar *)
* @param interface_info cast=(GDBusInterfaceInfo *)
* @param vtable cast=(const GDBusInterfaceVTable *)
@@ -4359,6 +4556,99 @@ public static final void g_dbus_method_invocation_return_value (long invocation,
}
/**
+ * @param address cast=(const gchar *)
+ * @param flags cast=(GDBusServerFlags)
+ * @param guid cast=(const gchar *)
+ * @param observer cast=(GDBusAuthObserver *)
+ * @param cancellable cast=(GCancellable *)
+ * @param error cast=(GError **)
+ * @category gdbus
+ */
+public static final native long _g_dbus_server_new_sync (long address, int flags, long guid, long observer, long cancellable, long [] error);
+/** @category gdbus */
+public static final long g_dbus_server_new_sync (long address, int flags, long guid, long observer, long cancellable, long [] error) {
+ lock.lock();
+ try {
+ return _g_dbus_server_new_sync(address, flags, guid, observer, cancellable, error);
+ } finally {
+ lock.unlock();
+ }
+}
+
+/**
+ * @param server cast=(GDBusServer *)
+ * @category gdbus
+ */
+public static final native void _g_dbus_server_start (long server);
+/** @category gdbus */
+public static final void g_dbus_server_start (long server) {
+ lock.lock();
+ try {
+ _g_dbus_server_start(server);
+ } finally {
+ lock.unlock();
+ }
+}
+
+/**
+ * @param server cast=(GDBusServer *)
+ * @category gdbus
+ */
+public static final native void _g_dbus_server_stop (long server);
+/** @category gdbus */
+public static final void g_dbus_server_stop (long server) {
+ lock.lock();
+ try {
+ _g_dbus_server_stop(server);
+ } finally {
+ lock.unlock();
+ }
+}
+
+/**
+ * @param server cast=(GDBusServer *)
+ * @category gdbus
+ */
+public static final native long _g_dbus_server_get_client_address (long server);
+/** @category gdbus */
+public static final long g_dbus_server_get_client_address (long server) {
+ lock.lock();
+ try {
+ return _g_dbus_server_get_client_address(server);
+ } finally {
+ lock.unlock();
+ }
+}
+
+/**
+ * @category gdbus
+ */
+public static final native long _g_dbus_auth_observer_new ();
+/** @category gdbus */
+public static final long g_dbus_auth_observer_new () {
+ lock.lock();
+ try {
+ return _g_dbus_auth_observer_new();
+ } finally {
+ lock.unlock();
+ }
+}
+
+/**
+ * @category gdbus
+ */
+public static final native long _g_dbus_generate_guid ();
+/** @category gdbus */
+public static final long g_dbus_generate_guid () {
+ lock.lock();
+ try {
+ return _g_dbus_generate_guid();
+ } finally {
+ lock.unlock();
+ }
+}
+
+/**
* @param type cast=(const GVariantType *)
* @category gdbus
*/
@@ -4749,6 +5039,21 @@ public static final long g_variant_new_string (byte[] string) {
}
/**
+ * @param string cast=(const gchar *)
+ * @category gdbus
+ */
+public static final native long _g_variant_new_string (long string);
+/** @category gdbus */
+public static final long g_variant_new_string (long string) {
+ lock.lock();
+ try {
+ return _g_variant_new_string (string);
+ } finally {
+ lock.unlock();
+ }
+}
+
+/**
* @param value cast=(GVariant *)
* @category gdbus
*/
diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_extension.c b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_extension.c
index e7d122c17a..e4595767c3 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_extension.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_extension.c
@@ -1,98 +1,68 @@
#include "webkitgtk_extension.h"
-/**
- * Note: g_asserts() are active/working. (i.e not dissabled)
+/*
+ * To debug this extension:
+ * -ensure this is built with debug flags (look for '-g*' in make_linux, or 'SWT_LIB_DEBUG' macro)
+ * -connect to the WebKitWebProcess with the PID of this extension. It can be found as follows:
+ g_print("Extension PID: %d\n", getpid());
*/
-// +-------------+----------------------------------------------------------------
-// | Misc Globals|
-// +-------------+
-gint32 parentUniqueId = 0;
+// Client address of the main process GDBusServer -- the extension connects to this
+const gchar *swt_main_proc_client_address = NULL;
-// see: WebKitGTK.java 'TYPE NOTES'
+// Client address of the extension's GDBusServer -- SWT main process connects to this
+const gchar *extension_server_address = NULL;
+
+// See: WebKitGTK.java's 'TYPE NOTES'
guchar SWT_DBUS_MAGIC_NUMBER_EMPTY_ARRAY = 101;
guchar SWT_DBUS_MAGIC_NUMBER_NULL = 48;
-// +-------------+----------------------------------------------------------------
-// | Misc Helpers|
-// +-------------+
-
-/* Combine String and int.
- * @return char * should be free()'ed.
- */
-char * combineStrInt(char * in_str, gint32 in_i) {
- int new_str_len = strlen(in_str) + snprintf(NULL, 0, "%d", in_i) + 1; // str + int + \0
- char * out_str = malloc (new_str_len);
- snprintf( out_str, new_str_len, "%s%d", in_str, in_i);
- return out_str;
-}
-
-// +-------------+----------------------------------------------------------------
-// | GDBus logic |
-// +-------------+
-static const gchar base_service_name[] = "org.eclipse.swt"; // Base name. Full name has uniqueID appended.
-static const gchar object_name[] = "/org/eclipse/swt/gdbus";
-static const gchar interface[] = "org.eclipse.swt.gdbusInterface";
-
+// This struct represents a BrowserFunction
typedef struct {
- guint64 page_id;
- gchar *function;
- gchar *url;
+ guint64 page_id; // page ID
+ gchar *function; // JS function
+ gchar *url; // URL the function belongs to
} BrowserFunction;
+// The list of BrowserFunctions registered to this extension
GSList *function_list = NULL;
-GDBusProxy *proxy = NULL; // The proxy that we work with
-void proxy_init () {
- g_assert(parentUniqueId != 0);
+// GDBusConnection to the SWT main process
+GDBusConnection *connection_to_main_proc = NULL;
- if (proxy != NULL) { // Already initialized.
- return;
- }
- const char * full_service_name = combineStrInt((char *) base_service_name, parentUniqueId);
-
- GError *error = NULL; // Some functions return errors through params
-
- // g_type_init(); // Not needed as of glib 2.36
- proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, NULL, full_service_name, object_name, interface, NULL, &error);
- if ((proxy == NULL) || (error != NULL)) {
- fprintf(stderr, "SWT Webextension: GDBus setupServer error. Could not connect to %s:%s on %s.\n", full_service_name, object_name, interface);
- if (error != NULL) {
- fprintf(stderr, " %s\n", error->message);
- }
- exit(0);
- }
-}
+// This extension's GDBusServer and related resources
+GDBusServer *server = NULL;
+GDBusAuthObserver *auth_observer = NULL;
+gchar *guid = NULL;
+// GDBusConnection from SWT main process
+GDBusConnection *connection_from_main_proc = NULL;
/**
- * Caller should free the returned GVariant *.
+ * Caller should free the returned GVariant
*/
-GVariant * callMainProc(char * methodName, GVariant * params) {
- proxy_init();
+GVariant *call_main_proc_sync(char * method_name, GVariant *parameters) {
GError *error = NULL; // Some functions return errors through params
GVariant *result; // The value result from a call
// Send a message
- result = g_dbus_proxy_call_sync(proxy, methodName, params, 0, -1, NULL, &error); // You can make multiple calls
-
+ result = g_dbus_connection_call_sync(connection_to_main_proc, WEBKIT_MAIN_PROCESS_DBUS_NAME,
+ WEBKIT_MAIN_PROCESS_OBJECT_PATH, WEBKIT_MAIN_PROCESS_INTERFACE_NAME, method_name, parameters,
+ NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
// Error checking.
if (result == NULL) {
if (error != NULL) {
- g_error("SWT web extension: Call failed because '%s.'\n", error->message);
- }
- else {
- g_error("SWT web extension: Call failed for an unknown reason.\n");
+ g_error("call_main_proc_sync failed because '%s.'\n", error->message);
+ } else {
+ g_error("call_main_proc_sync failed for an unknown reason.\n");
}
return NULL;
}
- // Deal with result
return result;
}
-
-// +--------------------------------------------------+-------------------------------------
+// +--------------------------------------------------+
// | JavaScriptCore to/from conversion GVariant logic |
// +--------------------------------------------------+
@@ -188,7 +158,7 @@ static GVariant * convert_js_to_gvariant (JSContextRef context, JSValueRef value
char* valueUTF8 = (char*) malloc(valueUTF8Size);
JSStringGetUTF8CString(valueIString, valueUTF8, valueUTF8Size);
- g_warning("SWT Webextension: Unhandled type %d value: %s \n", type, valueUTF8);
+ g_warning("Unhandled type %d value: %s \n", type, valueUTF8);
free(valueUTF8);
JSStringRelease(valueIString);
@@ -261,7 +231,7 @@ static JSValueRef webkit2callJava (JSContextRef context,
// Need to ensure user arguments won't break gdbus.
if (!is_js_valid(context, arguments[3])) {
- g_warning("SWT Webextension: Arguments contain an invalid type (object). Only Number,Boolean,null,String and (mixed) arrays of basic types are supported");
+ g_warning("Arguments contain an invalid type (object). Only Number,Boolean,null,String and (mixed) arrays of basic types are supported");
return 0;
}
@@ -272,9 +242,9 @@ static JSValueRef webkit2callJava (JSContextRef context,
convert_js_to_gvariant(context, arguments[3]) // js args
);
- GVariant *g_var_result = callMainProc("webkit2callJava", g_var_params);
+ GVariant *g_var_result = call_main_proc_sync("webkit2callJava", g_var_params);
if (g_var_result == NULL) {
- g_error("SWT Webextension: Java call returned NULL. This should never happpen\n");
+ g_error("Java call returned NULL. This should never happpen\n");
return 0;
}
@@ -290,7 +260,7 @@ static JSValueRef webkit2callJava (JSContextRef context,
}
retVal = convert_gvariant_to_js(context, g_variant_get_child_value(g_var_result, 0));
} else {
- g_error("SWT Webextension: Unsupported return type. Should be an array, but received a single type.\n");
+ g_error("Unsupported return type. Should be an array, but received a single type.\n");
}
g_variant_unref(g_var_result);
@@ -327,7 +297,7 @@ static gboolean webkitgtk_extension_execute_script (const guint64 page_id, gchar
size_t exceptionUTF8Size = JSStringGetMaximumUTF8CStringSize(exceptionIString);
char* exceptionUTF8 = (char*)malloc(exceptionUTF8Size);
JSStringGetUTF8CString(exceptionIString, exceptionUTF8, exceptionUTF8Size);
- g_error("SWT web extension: failed to execute script exception: %s\n", exceptionUTF8);
+ g_error("Failed to execute script exception: %s\n", exceptionUTF8);
free(exceptionUTF8);
JSStringRelease(exceptionIString);
}
@@ -390,7 +360,7 @@ void unpack_browser_function_array(GVariant *array) {
gsize length = (int)g_variant_n_children (child);
if (length > 3) {
// If the length is longer than three, something went wrong and this tuple should be skipped
- g_warning("SWT web extension: there was an error unpacking the GVariant tuple for a BrowserFunction in the web extension.\n");
+ g_warning("There was an error unpacking the GVariant tuple for a BrowserFunction in the web extension.\n");
continue;
}
guint64 page = g_variant_get_uint64(g_variant_get_child_value(child, 0));
@@ -403,7 +373,7 @@ void unpack_browser_function_array(GVariant *array) {
if (function != NULL && url != NULL) {
add_browser_function(page, function, url);
} else {
- g_warning("SWT web extension: there was an error unpacking the function string or URL.\n");
+ g_warning("There was an error unpacking the function string or URL.\n");
}
}
g_variant_unref (child);
@@ -444,7 +414,7 @@ static void window_object_cleared_callback (WebKitScriptWorld *world, WebKitWebP
if (page_id != -1) {
g_slist_foreach(function_list, (GFunc)execute_browser_functions, GUINT_TO_POINTER(page_id));
} else {
- g_warning("SWT web extension: there was an error fetching the page ID in the object_cleared callback.\n");
+ g_warning("There was an error fetching the page ID in the object_cleared callback.\n");
}
}
}
@@ -486,61 +456,153 @@ webkitgtk_extension_handle_method_call (GDBusConnection *connection, const gchar
g_dbus_method_invocation_return_value(invocation, g_variant_new("(b)", result));
return;
}
- g_error ("UNKNOWN method %s\n", method_name);
+ g_error ("Unknown method %s\n", method_name);
}
static const GDBusInterfaceVTable interface_vtable = {webkitgtk_extension_handle_method_call, NULL, NULL};
-static void on_bus_acquired (GDBusConnection *connection, const gchar *name, gpointer user_data) {
- dbus_interface = g_dbus_node_info_lookup_interface(dbus_node, WEBKITGTK_EXTENSION_DBUS_INTERFACE);
- guint registration_id = g_dbus_connection_register_object(connection,
- webkitgtk_extension_dbus_path,
- dbus_interface,
- &interface_vtable, NULL, /* user_data */
- NULL, /* user_data_free_func */
- NULL); /* GError** */
+static void connection_closed_cb (GDBusConnection *connection, gboolean remote_peer_vanished, GError *error,
+ gpointer user_data) {
+ /*
+ * If this connection is closed we can shut the server down. NOTE: all connections are freed in the main
+ * SWT process, including connections created here in this extension. This is done for the sake of
+ * consistency to avoid double frees.
+ */
+ if (connection == connection_from_main_proc) {
+ // Free server and its objects
+ g_dbus_server_stop(server);
+ g_object_unref(auth_observer);
+ g_object_unref(server);
+ g_free(guid);
+ }
+}
+
+static gboolean new_connection_cb (GDBusServer *server, GDBusConnection *connection, gpointer user_data) {
+ // Create introspection XML
+ dbus_introspection_xml = g_new (gchar, strlen(dbus_introspection_xml_template) +
+ strlen(WEBKITGTK_EXTENSION_INTERFACE_NAME) + 1);
+ g_sprintf (dbus_introspection_xml, dbus_introspection_xml_template, WEBKITGTK_EXTENSION_INTERFACE_NAME);
+
+ // Create DBus node
+ dbus_node = g_dbus_node_info_new_for_xml (dbus_introspection_xml, NULL);
+ g_assert (dbus_node != NULL);
+
+ // Register node on the connection that was just created
+ dbus_interface = g_dbus_node_info_lookup_interface(dbus_node, WEBKITGTK_EXTENSION_INTERFACE_NAME);
+ guint registration_id = g_dbus_connection_register_object(connection, WEBKITGTK_EXTENSION_OBJECT_PATH,
+ dbus_interface,
+ &interface_vtable, NULL, /* user_data */
+ NULL, /* user_data_free_func */
+ NULL); /* GError** */
g_assert(registration_id > 0);
- GVariant *g_var_result = callMainProc("webkitWebExtensionIdentifer", g_variant_new ("(ss)",
- webkitgtk_extension_dbus_name, webkitgtk_extension_dbus_path));
- if (g_variant_is_of_type(g_var_result, G_VARIANT_TYPE_TUPLE)) {
- unpack_browser_function_array(g_variant_get_child_value(g_var_result, 0));
+ // This connection will be the one from the main SWT process
+ connection_from_main_proc = g_object_ref(connection);
+
+ // Listen to the "close" signal on this connection so we can free resources in the extension when
+ // the time comes.
+ g_signal_connect(connection_from_main_proc, "closed", G_CALLBACK (connection_closed_cb), NULL);
+
+ return 1;
+}
+
+static gboolean extension_authorize_peer (GDBusAuthObserver *observer, GIOStream *stream, GCredentials *credentials,
+ gpointer user_data) {
+ g_autoptr (GError) error = NULL;
+ gboolean authorized = FALSE;
+ if (credentials != NULL) {
+ GCredentials *own_credentials;
+ own_credentials = g_credentials_new ();
+ if (g_credentials_is_same_user (credentials, own_credentials, &error)) {
+ authorized = TRUE;
+ }
+ g_object_unref (own_credentials);
+ }
+ if (error) {
+ g_warning ("Error authenticating client connection: %s", error->message);
+ }
+ return authorized;
+}
+
+// Returns a valid GDBusServer address -- this will be the address used to connect to the extension's
+// GDBusServer
+gchar *construct_server_address () {
+ g_autoptr (GError) error = NULL;
+ gchar *partial_name = g_strconcat ("SWT-WebExtensionGDBusServer-", g_get_user_name (), "-XXXXXX", NULL);
+ gchar *temp_path = g_dir_make_tmp (partial_name, &error);
+ if (error) {
+ g_error("There was an error creating the server address: %s\n", error->message);
+ }
+ g_free (partial_name);
+ return g_strdup_printf ("unix:tmpdir=%s", temp_path);
+}
+
+// Creates the GDBusServer for this web extension
+static void create_server () {
+ g_autoptr (GError) error = NULL;
+ extension_server_address = construct_server_address();
+ auth_observer = g_dbus_auth_observer_new();
+
+ guid = g_dbus_generate_guid();
+ server = g_dbus_server_new_sync(extension_server_address, G_DBUS_SERVER_FLAGS_NONE, guid,
+ auth_observer, NULL, &error);
+
+ if (error) {
+ g_error ("Failed to create server: %s", error->message);
+ }
+
+ if (server) {
+ g_signal_connect(server, "new-connection", G_CALLBACK(new_connection_cb), NULL);
+ g_dbus_server_start(server);
+ g_signal_connect (auth_observer, "authorize-authenticated-peer", G_CALLBACK(extension_authorize_peer), NULL);
+ }
+}
+
+// Identifies this web extension to the main SWT process by sending its
+// server address over DBus.
+static void identify_extension_to_main_proc () {
+ const gchar *client_address_for_extension_server = g_dbus_server_get_client_address(server);
+ GVariant *result = call_main_proc_sync("webkitWebExtensionIdentifier", g_variant_new ("(s)",
+ client_address_for_extension_server));
+
+ // Process and register any pending BrowserFunctions from the main SWT process
+ if (g_variant_is_of_type(result, G_VARIANT_TYPE_TUPLE)) {
+ unpack_browser_function_array(g_variant_get_child_value(result, 0));
} else {
- g_warning("SWT web extension: on_bus_acquired return value from SWT was an unexpected type (not a tuple).\n");
+ g_warning("webkitWebExtensionIdentifier return value from SWT was an unexpected type""(not a tuple).\n");
}
- return;
}
-G_MODULE_EXPORT void webkit_web_extension_initialize_with_user_data(WebKitWebExtension *extension, GVariant *user_data) {
- // To debug this extension:
- // - ensure this is build with debug flags (look for '-g*' in make_linux, or 'SWT_LIB_DEBUG' macro.
- // - connect to WebKitWebProcess with pid of this extension. Use below to print it:
- // g_print("Webext pid: %d (To debug, attach to WebKitWebProcess with this pid)\n", getpid());
+// Creates a GDBusConnection to the main SWT process
+static void connect_to_main_proc (GVariant *user_data) {
+ swt_main_proc_client_address = g_variant_get_string(user_data, NULL);
+
+ g_autoptr (GError) error = NULL;
+ connection_to_main_proc = g_dbus_connection_new_for_address_sync (swt_main_proc_client_address,
+ G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, NULL, NULL, &error);
+
+ if (error) {
+ g_error ("Failed to create connection: %s", error->message);
+ }
+
+ if (connection_to_main_proc && g_dbus_connection_is_closed(connection_to_main_proc)) {
+ g_error ("Failed to created connection: connection is closed");
+ }
+}
+G_MODULE_EXPORT void webkit_web_extension_initialize_with_user_data(WebKitWebExtension *extension, GVariant *user_data) {
this_extension = extension;
- parentUniqueId = g_variant_get_int32(user_data);
- g_signal_connect(extension, "page-created", G_CALLBACK(web_page_created_callback), NULL);
- // To hook into javascript execution:
- g_signal_connect (webkit_script_world_get_default (), "window-object-cleared", G_CALLBACK (window_object_cleared_callback), NULL);
+ // Connect to the main SWT process
+ connect_to_main_proc(user_data);
+
+ // Create this extension's GDBusServer
+ create_server();
- // Create DBus server for this web extension
- webkitgtk_extension_dbus_name = combineStrInt((char *) WEBKITGTK_EXTENSION_DBUS_NAME_PREFIX, (gint32) getpid());
- webkitgtk_extension_dbus_path = combineStrInt((char *) WEBKITGTK_EXTENSION_DBUS_PATH_PREFIX, (gint32) getpid());
-
- dbus_introspection_xml = g_new (gchar, strlen(dbus_introspection_xml_template) + strlen(WEBKITGTK_EXTENSION_DBUS_INTERFACE) + 1);
- g_sprintf (dbus_introspection_xml, dbus_introspection_xml_template, WEBKITGTK_EXTENSION_DBUS_INTERFACE);
- dbus_node = g_dbus_node_info_new_for_xml (dbus_introspection_xml, NULL);
- g_assert (dbus_node != NULL);
-
- guint owner_id;
- owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
- webkitgtk_extension_dbus_name,
- G_BUS_NAME_OWNER_FLAGS_REPLACE | G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT,
- on_bus_acquired,
- NULL, /* on_name_acquired */
- NULL, /* on_name_lost */
- NULL,
- NULL);
- g_assert (owner_id != 0);
+ // Identify this extension's server address to the main process
+ identify_extension_to_main_proc();
+
+ // WebKit callbacks
+ g_signal_connect(extension, "page-created", G_CALLBACK(web_page_created_callback), NULL);
+ g_signal_connect (webkit_script_world_get_default (), "window-object-cleared", G_CALLBACK (window_object_cleared_callback), NULL);
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_extension.h b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_extension.h
index 4d2713cd76..3edca55451 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_extension.h
+++ b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_extension.h
@@ -37,15 +37,13 @@
#include <JavaScriptCore/JSObjectRef.h>
#include <JavaScriptCore/JSStringRef.h>
-#define WEBKITGTK_EXTENSION_DBUS_NAME_PREFIX "org.eclipse.swt.webkitgtk_extension"
-#define WEBKITGTK_EXTENSION_DBUS_PATH_PREFIX "/org/eclipse/swt/webkitgtk_extension/gdbus/"
-#define WEBKITGTK_EXTENSION_DBUS_INTERFACE "org.eclipse.swt.webkitgtk_extension.gdbusInterface"
+#define WEBKITGTK_EXTENSION_DBUS_NAME "org.eclipse.swt.webkitgtk_extension"
+#define WEBKITGTK_EXTENSION_OBJECT_PATH "/org/eclipse/swt/webkitgtk_extension/gdbus"
+#define WEBKITGTK_EXTENSION_INTERFACE_NAME "org.eclipse.swt.webkitgtk_extension.gdbusInterface"
-#define WEBKIT_MAIN_PROCESS_DBUS_NAME_PREFIX "org.eclipse.swt"
-#define WEBKIT_MAIN_PROCESS_DBUS_PATH_PREFIX "/org/eclipse/swt/gdbus/"
-
-static gchar* webkitgtk_extension_dbus_name;
-static gchar* webkitgtk_extension_dbus_path;
+#define WEBKIT_MAIN_PROCESS_DBUS_NAME "org.eclipse.swt"
+#define WEBKIT_MAIN_PROCESS_OBJECT_PATH "/org/eclipse/swt/gdbus"
+#define WEBKIT_MAIN_PROCESS_INTERFACE_NAME "org.eclipse.swt.gdbusInterface"
static WebKitWebExtension *this_extension;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java
index 0ccf9394b1..4a7ec142a0 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java
@@ -292,6 +292,7 @@ class WebKit extends WebBrowser {
}
if (WEBKIT2) {
+ // Note: this will also initialize WebkitGDBus
Webkit2Extension.init();
} else {
JSObjectHasPropertyProc = new Callback (WebKit.class, "JSObjectHasPropertyProc", 3); //$NON-NLS-1$
@@ -437,7 +438,7 @@ class WebKit extends WebBrowser {
* function string, and URL in a HashMap. Once the proxy to the extension is loaded, these
* functions will be sent to and registered in the extension.
*/
- if (!WebkitGDBus.proxyToExtension) {
+ if (!WebkitGDBus.connectionToExtensionCreated) {
WebkitGDBus.functionsPending = true;
ArrayList<ArrayList<String>> list = new ArrayList<>();
ArrayList<String> functionAndUrl = new ArrayList<>();
@@ -461,7 +462,7 @@ class WebKit extends WebBrowser {
@Override
public void destroyFunction (BrowserFunction function) {
// Only deregister functions if the proxy to the extension has been loaded
- if (WebkitGDBus.proxyToExtension && WEBKIT2) {
+ if (WebkitGDBus.connectionToExtensionCreated && WEBKIT2) {
String url = this.getUrl().isEmpty() ? "nullURL" : this.getUrl();
boolean successful = webkit_extension_modify_function(this.pageId, function.functionString, url, "deregister");
if (!successful) {
@@ -502,9 +503,11 @@ class WebKit extends WebBrowser {
static class Webkit2Extension {
/** Note, if updating this, you need to change it also in webkitgtk_extension.c */
private static final String javaScriptFunctionName = "webkit2callJava"; // $NON-NLS-1$
- private static final String webkitWebExtensionIdentifier = "webkitWebExtensionIdentifer"; // $NON-NLS-1$
+ private static final String webkitWebExtensionIdentifier = "webkitWebExtensionIdentifier"; // $NON-NLS-1$
private static Callback initializeWebExtensions_callback;
- private static int uniqueID = OS.getpid();
+
+ /** GDBusServer returned by WebkitGDBus */
+ private static long dBusServer = 0;
/**
* Don't continue initialization if something failed. This allows Browser to carryout some functionality
@@ -515,7 +518,7 @@ class WebKit extends WebBrowser {
static String getJavaScriptFunctionName() {
return javaScriptFunctionName;
}
- static String getWebExtensionIdentifer() {
+ static String getWebExtensionIdentifier() {
return webkitWebExtensionIdentifier;
}
static String getJavaScriptFunctionDeclaration(long webView) {
@@ -532,7 +535,10 @@ class WebKit extends WebBrowser {
* sends data back to SWT via GDBus. Failure to load GDBus here will result in crashes.
* See bug 536141.
*/
- gdbus_init();
+ dBusServer = gdbus_init();
+ if (dBusServer == 0) {
+ System.err.println("SWT WebKit: error initializing DBus server, dBusServer == 0");
+ }
initializeWebExtensions_callback = new Callback(Webkit2Extension.class, "initializeWebExtensions_callback", void.class, new Type [] {long.class, long.class});
if (initializeWebExtensions_callback.getAddress() == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS);
if (WebKitGTK.webkit_get_minor_version() >= 4) { // Callback exists only since 2.04
@@ -544,19 +550,18 @@ class WebKit extends WebBrowser {
* GDbus initialization can cause performance slow downs. So we int GDBus in lazy way.
* It can be initialized upon first use of BrowserFunction.
*/
- static boolean gdbus_init() {
+ static long gdbus_init() {
if (WebKitGTK.webkit_get_minor_version() < 4) {
System.err.println("SWT Webkit: Warning, You are using an old version of webkitgtk. (pre 2.4)"
+ " BrowserFunction functionality will not be avaliable");
- return false;
+ return 0;
}
if (!loadFailed) {
- WebkitGDBus.init(String.valueOf(uniqueID));
- return true;
+ return WebkitGDBus.init();
} else {
- return false;
+ return 0;
}
}
@@ -608,7 +613,9 @@ class WebKit extends WebBrowser {
* (as a note, the webprocess would have to load the gmodule).
*/
WebKitGTK.webkit_web_context_set_web_extensions_directory(WebKitGTK.webkit_web_context_get_default(), Converter.wcsToMbcs (extensionsFolder, true));
- long gvariantUserData = OS.g_variant_new_int32(uniqueID);
+ long clientAddress = OS.g_dbus_server_get_client_address(dBusServer);
+ String clientAddressJava = Converter.cCharPtrToJavaString(clientAddress, false);
+ long gvariantUserData = OS.g_variant_new_string(clientAddress);
WebKitGTK.webkit_web_context_set_web_extensions_initialization_user_data(WebKitGTK.webkit_web_context_get_default(), gvariantUserData);
}
@@ -1174,6 +1181,14 @@ public void create (Composite parent, int style) {
C.memmove (webViewData, new long [] {webView}, C.PTR_SIZEOF);
}
+ /*
+ * Set the Display for this WebKit class, so we can safely dispose of GDBus objects later.
+ * See bug 540060 for more info.
+ */
+ if (WEBKIT2 && !WebkitGDBus.attachedToDisplay) {
+ WebkitGDBus.setDisplay(browser.getDisplay());
+ }
+
// Documentation for these signals/properties is usually found under signal/property of WebKitWebView.
// notify_* usually implies a property change. For these, the first arg is typically the webview handle.
if (WEBKIT1){
@@ -1203,8 +1218,6 @@ public void create (Composite parent, int style) {
OS.g_signal_connect (webView, WebKitGTK.mouse_target_changed, Proc4.getAddress (), MOUSE_TARGET_CHANGED);
OS.g_signal_connect (webView, WebKitGTK.context_menu, Proc5.getAddress (), CONTEXT_MENU);
OS.g_signal_connect (webView, WebKitGTK.load_failed_with_tls_errors, Proc5.getAddress (), LOAD_FAILED_TLS);
-
-
}
// Proc3 is overloaded in that not only Webview connects to it,
diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebkitGDBus.java b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebkitGDBus.java
index 3c39022fcd..7213b3ffc3 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebkitGDBus.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebkitGDBus.java
@@ -20,6 +20,7 @@ import java.util.*;
import org.eclipse.swt.*;
import org.eclipse.swt.internal.*;
import org.eclipse.swt.internal.gtk.*;
+import org.eclipse.swt.widgets.*;
/**
* Logic for Webkit to interact with it's Webkit extension via GDBus.
@@ -34,21 +35,52 @@ import org.eclipse.swt.internal.gtk.*;
* @category gdbus
*/
class WebkitGDBus {
- private static String DBUS_SERVICE_NAME;
- private static final String DBUS_OBJECT_PATH = "/org/eclipse/swt/gdbus";
- private static final String INTERFACE_NAME = "org.eclipse.swt.gdbusInterface";
- private static final String EXTENSION_INTERFACE_NAME = "org.eclipse.swt.webkitgtk_extension.gdbusInterface";
- private static String EXTENSION_DBUS_NAME;
- private static String EXTENSION_DBUS_PATH;
-
- /** Accepted methods over gdbus */
+ /*
+ * If any of the GDBus names/paths/interfaces need to be changed, then they also need to be changed
+ * in the extension (webkitgtk_extension.c).
+ */
+
+ /* WEBKITGDBUS_DBUS_NAME isn't actually used but is here for informative purposes */
+ @SuppressWarnings("unused")
+ private static final String WEBKITGDBUS_DBUS_NAME = "org.eclipse.swt";
+ private static final byte [] WEBKITGDBUS_OBJECT_PATH = Converter.javaStringToCString("/org/eclipse/swt/gdbus");
+ private static final String WEBKITGDBUS_INTERFACE_NAME_JAVA = "org.eclipse.swt.gdbusInterface";
+ private static final byte [] WEBKITGDBUS_INTERFACE_NAME = Converter.javaStringToCString("org.eclipse.swt.gdbusInterface");
+
+ /* Extension connection details, in byte [] form */
+ private static final byte [] EXTENSION_DBUS_NAME = Converter.javaStringToCString("org.eclipse.swt.webkitgtk_extension");
+ private static final byte [] EXTENSION_OBJECT_PATH = Converter.javaStringToCString("/org/eclipse/swt/webkitgtk_extension/gdbus");
+ private static final byte [] EXTENSION_INTERFACE_NAME = Converter.javaStringToCString("org.eclipse.swt.webkitgtk_extension.gdbusInterface");
+
+ /** Extension GDBusServer client address */
+ private static String EXTENSION_DBUS_SERVER_CLIENT_ADDRESS;
+
+ /* Accepted GDBus methods */
private static final String webkit2callJava = WebKit.Webkit2Extension.getJavaScriptFunctionName();
- private static final String webkitWebExtensionIdentifier = WebKit.Webkit2Extension.getWebExtensionIdentifer();
+ private static final String webkitWebExtensionIdentifier = WebKit.Webkit2Extension.getWebExtensionIdentifier();
+
+ /* Connections */
+ /** GDBusConnection from the web extension */
+ static long connectionFromExtension;
+ /** GDBusConnection to the web extension */
+ static long connectionToExtension;
+ /** A field that is set to true if the proxy connection has been established, false otherwise. */
+ static boolean connectionToExtensionCreated;
+
+ /* Server related objects */
+ /** GDBusServer for the main SWT process */
+ private static long gDBusServer = 0;
+ /** GDBusAuthObserver for the server */
+ private static long authObserver = 0;
+ /** GUID of the GDBusServer */
+ private static long guid = 0;
+
+ /** Display this GDBus class is "attached" to */
+ static Display display;
+
- /** Proxy connection to the web extension.*/
- static long proxy;
- /** A field that is set to true if the proxy connection has been established, false otherwise */
- static boolean proxyToExtension;
+
+ // BrowserFunction logic
/** Set to true if there are <code>BrowserFunction</code> objects waiting to be registered with the web extension.*/
static boolean functionsPending;
/**
@@ -87,9 +119,9 @@ class WebkitGDBus {
* Be mindful about only using supported DBUS_TYPE_* , as convert* methods might fail otherwise.
* Alternatively, modify convert* methods.
*/
- private static final String dbus_introspection_xml =
+ private static final byte [] WEBKITGDBUS_INTROSPECTION_XML = Converter.javaStringToCString(
"<node>"
- + " <interface name='" + INTERFACE_NAME + "'>"
+ + " <interface name='" + WEBKITGDBUS_INTERFACE_NAME_JAVA + "'>"
+ " <method name='" + webkit2callJava + "'>"
+ " <arg type='"+ OS.DBUS_TYPE_STRING + "' name='webViewPtr' direction='in'/>"
+ " <arg type='"+ OS.DBUS_TYPE_DOUBLE + "' name='index' direction='in'/>"
@@ -98,12 +130,11 @@ class WebkitGDBus {
+ " <arg type='" + OS.DBUS_TYPE_SINGLE_COMPLETE + "' name='result' direction='out'/>"
+ " </method>"
+ " <method name='" + webkitWebExtensionIdentifier + "'>"
- + " <arg type='"+ OS.DBUS_TYPE_STRING + "' name='webExtensionDbusName' direction='in'/>"
- + " <arg type='"+ OS.DBUS_TYPE_STRING + "' name='webExtensionDbusPath' direction='in'/>"
+ + " <arg type='"+ OS.DBUS_TYPE_STRING + "' name='webExtensionServerAddress' direction='in'/>"
+ " <arg type='"+ OS.DBUS_TYPE_STRUCT_ARRAY_BROWSER_FUNCS + "' name='result' direction='out'/>"
+ " </method>"
+ " </interface>"
- + "</node>";
+ + "</node>");
/**
* GDBus/DBus doesn't have a notion of Null.
@@ -115,130 +146,125 @@ class WebkitGDBus {
private static final byte SWT_DBUS_MAGIC_NUMBER_NULL = 48;
- /** GDBusNodeInfo */
- private static Callback onBusAcquiredCallback;
- private static Callback onNameAcquiredCallback;
- private static Callback onNameLostCallback;
- private static Callback handleMethodCallback;
-
+ /** Callback for GDBus method handling */
+ private static Callback handleMethodCB;
+ /** Callback for incoming connections to WebkitGDBus' server */
+ private static Callback newConnectionCB;
+ /** Callback for creating a new connection to the web extension */
+ private static Callback newConnectionToExtensionCB;
+ /** Callback for authenticating connections to WebkitGDBus' server */
+ private static Callback authenticatePeerCB;
/** Callback for asynchronous proxy calls to the extension */
- private static Callback callExtensionAsyncCallback;
+ private static Callback callExtensionAsyncCB;
static {
- onBusAcquiredCallback = new Callback (WebkitGDBus.class, "onBusAcquiredCallback", 3); //$NON-NLS-1$
- if (onBusAcquiredCallback.getAddress () == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS);
+ handleMethodCB = new Callback (WebkitGDBus.class, "handleMethodCB", 8); //$NON-NLS-1$
+ if (handleMethodCB.getAddress () == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS);
- onNameAcquiredCallback = new Callback (WebkitGDBus.class, "onNameAcquiredCallback", 3); //$NON-NLS-1$
- if (onNameAcquiredCallback.getAddress () == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS);
+ callExtensionAsyncCB = new Callback (WebkitGDBus.class, "callExtensionAsyncCB", 3); //$NON-NLS-1$
+ if (callExtensionAsyncCB.getAddress () == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS);
- onNameLostCallback = new Callback (WebkitGDBus.class, "onNameLostCallback", 3); //$NON-NLS-1$
- if (onNameLostCallback.getAddress () == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS);
+ newConnectionCB = new Callback (WebkitGDBus.class, "newConnectionCB", 3); //$NON-NLS-1$
+ if (newConnectionCB.getAddress () == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS);
- handleMethodCallback = new Callback (WebkitGDBus.class, "handleMethodCallback", 8); //$NON-NLS-1$
- if (handleMethodCallback.getAddress () == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS);
+ newConnectionToExtensionCB = new Callback (WebkitGDBus.class, "newConnectionToExtensionCB", 3); //$NON-NLS-1$
+ if (newConnectionToExtensionCB.getAddress () == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS);
- callExtensionAsyncCallback = new Callback (WebkitGDBus.class, "callExtensionAsyncCallback", 3); //$NON-NLS-1$
- if (callExtensionAsyncCallback.getAddress () == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS);
+ authenticatePeerCB = new Callback (WebkitGDBus.class, "authenticatePeerCB", 4); //$NON-NLS-1$
+ if (authenticatePeerCB.getAddress () == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS);
}
+ /** True iff the GDBusServer has been initialized */
static boolean initialized;
+ /** True iff this class has been attached to a Display */
+ static boolean attachedToDisplay;
- /** This method is not intended to be referenced by clients. Internal class. */
- static void init(String uniqueId) {
- if (initialized)
- return;
+ /** This method is in an internal class and is not intended to be referenced by clients. */
+ static long init () {
+ if (initialized) {
+ return gDBusServer;
+ }
initialized = true;
- DBUS_SERVICE_NAME = "org.eclipse.swt" + uniqueId;
- int owner_id = OS.g_bus_own_name(OS.G_BUS_TYPE_SESSION,
- Converter.javaStringToCString(DBUS_SERVICE_NAME),
- OS.G_BUS_NAME_OWNER_FLAGS_REPLACE | OS.G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT,
- onBusAcquiredCallback.getAddress(),
- onNameAcquiredCallback.getAddress(), // name_acquired_handler
- onNameLostCallback.getAddress(), // name_lost_handler
- 0, // user_data
- 0); // user_data_free_func
- if (owner_id == 0) {
- System.err.println("SWT WebkitGDBus: Failed to aquire bus name: " + DBUS_SERVICE_NAME);
- }
- }
+ // Generate address and GUID
+ long address = construct_server_address();
+ authObserver = OS.g_dbus_auth_observer_new();
+ guid = OS.g_dbus_generate_guid();
- @SuppressWarnings("unused")
- private static void teardown_gdbus() {
- // Currently GDBus is persistent across browser instances.
- // If ever needed, gdbus can be disposed via:
- // g_bus_unown_name (owner_id); // owner_id would need to be made global
- // g_dbus_node_info_unref (gdBusNodeInfo); // introspection_data Would need to be made global
+ // Create server
+ long [] error = new long [1];
+ gDBusServer = OS.g_dbus_server_new_sync(address, OS.G_DBUS_SERVER_FLAGS_NONE, guid, authObserver, 0, error);
+
+ // Connect authentication and incoming connections signals to the newly created server, and start it
+ if (gDBusServer != 0) {
+ OS.g_signal_connect(gDBusServer, OS.new_connection, newConnectionCB.getAddress(), 0);
+ OS.g_signal_connect(authObserver, OS.authorize_authenticated_peer, authenticatePeerCB.getAddress(), 0);
+ OS.g_dbus_server_start(gDBusServer);
+ } else {
+ System.err.println("SWT WebKitGDBus: error creating DBus server " + Display.extractFreeGError(error[0]));
+ }
+ return gDBusServer;
}
/**
- * @param connection GDBusConnection *
- * @param name const gchar *
- * @param user_data gpointer
- * @return void.
+ * Sets the Display for this class. This allows WebkitGDBus to attach its servers and related objects
+ * to the provided Display. When the Display is disposed, it will will release the GDBus related
+ * resources.
+ *
+ * @param displayToSet the Display to set
*/
- @SuppressWarnings("unused") // Callback Only called directly by JNI.
- private static long onBusAcquiredCallback (long connection, long name, long user_data) {
- long gdBusNodeInfo;
-
- // Parse XML
- {
- long [] error = new long [1];
- gdBusNodeInfo = OS.g_dbus_node_info_new_for_xml(Converter.javaStringToCString(dbus_introspection_xml), error);
- if (gdBusNodeInfo == 0 || error[0] != 0) {
- System.err.println("SWT WebkitGDBus: Failed to get introspection data");
- }
- assert gdBusNodeInfo != 0 : "SWT WebkitGDBus: introspection data should not be 0";
- }
-
- // Register object
- {
- long [] error = new long [1];
- long interface_info = OS.g_dbus_node_info_lookup_interface(gdBusNodeInfo, Converter.javaStringToCString(INTERFACE_NAME));
- long vtable [] = { handleMethodCallback.getAddress(), 0, 0 };
- // SWT Dev Note: SWT Tool's "32/64 bit" checking mechanism sometimes get's confused by this method signature and shows an incorrect warning.
- // Other times it validates it fine. We ignore for now as 32bit will be dropped anyway.
- OS.g_dbus_connection_register_object(
- connection,
- Converter.javaStringToCString(DBUS_OBJECT_PATH),
- interface_info,
- vtable,
- 0, // user_data
- 0, // user_data_free_func
- error);
+ static void setDisplay (Display displayToSet) {
+ if (attachedToDisplay) {
+ return;
+ } else {
+ display = displayToSet;
- if (error[0] != 0) {
- System.err.println("SWT WebkitGDBus: Failed to register object: " + DBUS_OBJECT_PATH);
- return 0;
- }
+ /*
+ * Add the GDBusServer, GDBusAuthObserver, and GUID to the Display.
+ * Note that we don't add the connections yet, because they likely
+ * don't exist. Those are added in callbacks as they come in.
+ */
+ if (gDBusServer != 0) display.dBusServers.add(gDBusServer);
+ if (authObserver != 0) display.dBusAuthObservers.add(authObserver);
+ if (guid != 0) display.dBusGUIDS.add(guid);
+ attachedToDisplay = true;
}
-
- // Developer note:
- // To verify that a gdbus interface is regisetered on the gdbus, you can use the 'gdbus' utility.
- // e.g:
- // gdbus introspect --session --dest org.eclipse <Press TAB KEY> // it should expand to something like: (uniqueID might be appended at the end).
- // gdbus introspect --session --dest org.eclipse.swt // you can then get object info like:
- // gdbus introspect --session --dest org.eclipse.swt --object-path /org/eclipse/swt/gdbus
-
- return 0; // Actual callback is void.
- }
-
-
- @SuppressWarnings("unused") // Callback Only called directly by JNI.
- private static long onNameAcquiredCallback (long connection, long name, long user_data) {
- // Currently not used, but can be used if acquring the gdbus name should trigger something to load.
- return 0;
}
-
- @SuppressWarnings("unused") // Callback Only called directly by JNI.
- private static long onNameLostCallback (long connection, long name, long user_data) {
- System.err.println("SWT WebkitGDBus.java: Lost GDBus name. This should never occur");
- return 0;
+ /**
+ * Constructs an address at which the GDBus server for the SWT main process
+ * can be reached.
+ *
+ * @return a pointer to the address
+ */
+ private static long construct_server_address () {
+ byte [] swt = Converter.wcsToMbcs("SWT-GDBusServer-", true);
+ long swtPtr = OS.g_malloc(swt.length);
+ C.memmove(swtPtr, swt, swt.length);
+ long user = OS.g_get_user_name();
+ byte [] template = Converter.wcsToMbcs("-XXXXXX", true);
+ long templatePtr = OS.g_malloc(template.length);
+ C.memmove(templatePtr, template, template.length);
+ long fileName = OS.g_strconcat(swtPtr, user, templatePtr, 0);
+ long [] error = new long [1];
+ long address = OS.g_dir_make_tmp(fileName, error);
+ if (address == 0) {
+ System.err.println("SWT WebkitGDBus: error creating temp folder " + Display.extractFreeGError(error[0]));
+ }
+ byte [] socket = Converter.wcsToMbcs("unix:tmpdir=", true);
+ long socketPtr = OS.g_malloc(socket.length);
+ C.memmove(socketPtr, socket, socket.length);
+ long finalAddress = OS.g_strconcat(socketPtr, address, 0);
+
+ // Clean up temporary string pointers and return result
+ OS.g_free(swtPtr);
+ OS.g_free(user);
+ OS.g_free(templatePtr);
+ OS.g_free(fileName);
+ OS.g_free(socketPtr);
+ return finalAddress;
}
-
-
/**
* This is called when a client call one of the GDBus methods.
*
@@ -257,8 +283,8 @@ class WebkitGDBus {
* @param user_data gpointer
* @return
*/
- @SuppressWarnings("unused") // Callback only called directly by JNI.
- private static long handleMethodCallback (
+ @SuppressWarnings("unused") // callback not directly called by SWT
+ private static long handleMethodCB (
long connection, long sender,
long object_path, long interface_name,
long method_name, long gvar_parameters,
@@ -274,39 +300,111 @@ class WebkitGDBus {
} catch (Exception e) {
// gdbus should always return to prevent extension from hanging.
result = (String) WebBrowser.CreateErrorString (e.getLocalizedMessage ());
- System.err.println("SWT Webkit: Exception occured in Webkit2 callback logic. Bug?");
+ System.err.println("SWT WebkitGDBus: Exception occured in Webkit2 callback logic.");
}
} else if (java_method_name.equals(webkitWebExtensionIdentifier)) {
- Object [] nameArray = (Object []) convertGVariantToJava(gvar_parameters);
- if (nameArray [0] != null && nameArray[0] instanceof String) EXTENSION_DBUS_NAME = (String) nameArray[0];
- if (nameArray [1] != null && nameArray[1] instanceof String) EXTENSION_DBUS_PATH = (String) nameArray[1];
- proxyToExtension = proxyToExtensionInit();
- if (proxyToExtension) {
+ Object [] serverAddress = (Object []) convertGVariantToJava(gvar_parameters);
+ if (serverAddress[0] != null && serverAddress[0] instanceof String) {
+ EXTENSION_DBUS_SERVER_CLIENT_ADDRESS = (String) serverAddress[0];
+ // Connect to the extension's server by creating a connection asynchronously
+ createConnectionToExtension();
+ /*
+ * Return any pending BrowserFunctions that were created before WebkitGDBus
+ * was initialized.
+ */
invokeReturnValueExtensionIdentifier(pendingBrowserFunctions, invocation);
} else {
- invokeReturnValueExtensionIdentifier(null, invocation);
- System.err.println("SWT webkit: proxy to web extension failed to load, BrowserFunction may not work.");
+ System.err.println("SWT WebkitGDBus: error in web extension identification process."
+ + " BrowserFunction may not work.");
}
return 0;
}
} else {
- result = (String) "SWT webkit: GDBus called an unknown method?";
- System.err.println("SWT webkit: Received a call from an unknown method: " + java_method_name);
+ result = (String) "SWT WebkitGDBus: GDBus called an unknown method?";
+ System.err.println("SWT WebkitGDBus: Received a call from an unknown method: " + java_method_name);
}
invokeReturnValue(result, invocation);
return 0;
}
- @SuppressWarnings("unused")
- private static long callExtensionAsyncCallback (long source_object, long res, long user_data) {
- long [] gerror = new long [1];
- long result = OS.g_dbus_proxy_call_finish (proxy, res, gerror);
- if (gerror[0] != 0){
- long errMsg = OS.g_error_get_message(gerror[0]);
- String msg = Converter.cCharPtrToJavaString(errMsg, false);
- System.err.println("SWT webkit: There was an error executing something asynchronously with the extension (Java callback).");
- System.err.println("SWT webkit: the error message provided is " + msg);
- OS.g_error_free(gerror[0]);
+ @SuppressWarnings("unused") // callback not directly called by SWT
+ private static long callExtensionAsyncCB (long source_object, long result, long user_data) {
+ long [] error = new long [1];
+ long gVariantResult = OS.g_dbus_connection_call_finish (connectionToExtension, result, error);
+ if (error[0] != 0) {
+ String msg = Display.extractFreeGError(error[0]);
+ System.err.println("SWT WebkitGDBus: there was an error executing something asynchronously with the extension (Java callback).");
+ System.err.println("SWT WebkitGDBus: the error message provided is " + msg);
+ }
+ OS.g_variant_unref(gVariantResult);
+ return 0;
+ }
+
+ @SuppressWarnings("unused") // callback not directly called by SWT
+ private static long authenticatePeerCB (long observer, long stream, long credentials, long user_data) {
+ boolean authorized = false;
+ if (credentials != 0) {
+ long error [] = new long [1];
+ long ownCredentials = OS.g_credentials_new();
+ authorized = OS.g_credentials_is_same_user(credentials, ownCredentials, error);
+ if (error[0] != 0) {
+ String msg = Display.extractFreeGError(error[0]);
+ System.err.println("SWT WebkitGDBus: error authenticating client connection to server " + msg);
+ }
+ OS.g_object_unref(ownCredentials);
+ }
+ return authorized ? 1 : 0;
+ }
+
+ @SuppressWarnings("unused") // callback not directly called by SWT
+ private static long newConnectionCB (long server, long connection, long user_data) {
+ long gdBusNodeInfo;
+ long [] error = new long [1];
+ gdBusNodeInfo = OS.g_dbus_node_info_new_for_xml(WEBKITGDBUS_INTROSPECTION_XML, error);
+ if (gdBusNodeInfo == 0 || error[0] != 0) {
+ System.err.println("SWT WebkitGDBus: failed to get introspection data");
+ }
+ assert gdBusNodeInfo != 0 : "SWT WebKitGDBus: introspection data should not be 0";
+
+ long interface_info = OS.g_dbus_node_info_lookup_interface(gdBusNodeInfo, WEBKITGDBUS_INTERFACE_NAME);
+ long vtable [] = { handleMethodCB.getAddress(), 0, 0 };
+
+ OS.g_dbus_connection_register_object(
+ connection,
+ WEBKITGDBUS_OBJECT_PATH,
+ interface_info,
+ vtable,
+ 0, // user_data
+ 0, // user_data_free_func
+ error);
+
+ if (error[0] != 0) {
+ System.err.println("SWT WebKitGDBus: failed to register object: " + WEBKITGDBUS_OBJECT_PATH);
+ return 0;
+ }
+
+ // Ref the connection and add it to the Display's list of connections
+ connectionFromExtension = OS.g_object_ref(connection);
+ if (attachedToDisplay && display != null) {
+ if (!display.dBusConnections.contains(connection)) display.dBusConnections.add(connectionFromExtension);
+ }
+ return 1;
+ }
+
+ @SuppressWarnings("unused") // callback not directly called by SWT
+ private static long newConnectionToExtensionCB (long sourceObject, long result, long user_data) {
+ long [] error = new long [1];
+ connectionToExtension = OS.g_dbus_connection_new_for_address_finish(result, error);
+ if (error[0] != 0) {
+ System.err.println("SWT WebKitGDBus: error finishing connection: " + Display.extractFreeGError(error[0]));
+ return 0;
+ } else {
+ connectionToExtensionCreated = true;
+ }
+
+ // Add the connections to the Display's list of connections
+ if (attachedToDisplay && display != null) {
+ if (!display.dBusConnections.contains(connectionToExtension)) display.dBusConnections.add(connectionToExtension);
}
return 0;
}
@@ -346,7 +444,7 @@ class WebkitGDBus {
if (tupleGVariant != 0) {
OS.g_variant_builder_add_value(builder, tupleGVariant);
} else {
- System.err.println("SWT webkit: error creating empty BrowserFunction GVariant tuple, skipping.");
+ System.err.println("SWT WebKitGDBus: error creating empty BrowserFunction GVariant tuple, skipping.");
}
} else {
for (long id : map.keySet()) {
@@ -355,7 +453,7 @@ class WebkitGDBus {
for (ArrayList<String> stringList : list) {
Object [] stringArray = stringList.toArray();
if (stringArray.length > 2) {
- System.err.println("SWT webkit: String array with BrowserFunction and URL should never have"
+ System.err.println("SWT WebKitGDBus: String array with BrowserFunction and URL should never have"
+ "more than 2 Strings");
}
tupleArray[0] = id;
@@ -364,7 +462,7 @@ class WebkitGDBus {
if (tupleGVariant != 0) {
OS.g_variant_builder_add_value(builder, tupleGVariant);
} else {
- System.err.println("SWT webkit: error creating BrowserFunction GVariant tuple, skipping.");
+ System.err.println("SWT WebKitGDBus: error creating BrowserFunction GVariant tuple, skipping.");
}
}
}
@@ -373,7 +471,7 @@ class WebkitGDBus {
resultGVariant = OS.g_variant_builder_end(builder);
String typeString = Converter.cCharPtrToJavaString(OS.g_variant_get_type_string(resultGVariant), false);
if (!OS.DBUS_TYPE_STRUCT_ARRAY_BROWSER_FUNCS.equals(typeString)) {
- System.err.println("An error packaging the GVariant occurred: type mismatch.");
+ System.err.println("SWT WebKitGDBus: an error packaging the GVariant occurred: type mismatch.");
}
long [] variants = {resultGVariant};
long finalGVariant = OS.g_variant_new_tuple(variants, 1);
@@ -397,34 +495,20 @@ class WebkitGDBus {
}
/**
- * Initializes the proxy connection to the web extension.
- *
- * @return true if establishing the proxy connections succeeded,
- * false otherwise
+ * Asynchronously initializes a GDBusConnection to the web extension. Connection process
+ * will be confirmed when the newConnectionToExtension callback is called.
*/
- private static boolean proxyToExtensionInit() {
- if (proxy != 0) {
- return true;
- } else {
- if (EXTENSION_DBUS_NAME != null && EXTENSION_DBUS_PATH != null) {
- long [] error = new long [1];
- byte [] name = Converter.javaStringToCString(EXTENSION_DBUS_NAME);
- byte [] path = Converter.javaStringToCString(EXTENSION_DBUS_PATH);
- byte [] interfaceName = Converter.javaStringToCString(EXTENSION_INTERFACE_NAME);
- proxy = OS.g_dbus_proxy_new_for_bus_sync(OS.G_BUS_TYPE_SESSION, OS.G_DBUS_PROXY_FLAGS_NONE, 0, name, path, interfaceName, 0, error);
- if (error[0] != 0) {
- long errMsg = OS.g_error_get_message(error[0]);
- String msg = Converter.cCharPtrToJavaString(errMsg, false);
- OS.g_error_free(error[0]);
- System.err.println("SWT webkit: there was an error establishing the proxy connection to the extension. " +
- " The error is " + msg);
- return false;
- } else {
- return true;
- }
- }
+ private static void createConnectionToExtension() {
+ byte [] address = Converter.javaStringToCString(EXTENSION_DBUS_SERVER_CLIENT_ADDRESS);
+ long [] error = new long [1];
+ // Create connection asynchronously to avoid deadlock issues
+ OS.g_dbus_connection_new_for_address (address, OS.G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
+ 0, 0, newConnectionToExtensionCB.getAddress(), 0);
+
+ if (error[0] != 0) {
+ System.err.println("SWT WebkitGDBus: error creating connection to the extension "
+ + Display.extractFreeGError(error[0]));
}
- return false;
}
/**
@@ -436,22 +520,21 @@ class WebkitGDBus {
* @return an Object representing the return value from DBus in boolean form
*/
static Object callExtensionSync (long params, String methodName) {
- long [] gerror = new long [1]; // GError **
- long gVariant = OS.g_dbus_proxy_call_sync(proxy, Converter.javaStringToCString(methodName),
- params, OS.G_DBUS_CALL_FLAGS_NO_AUTO_START, 1000, 0, gerror);
- if (gerror[0] != 0) {
- long errMsg = OS.g_error_get_message(gerror[0]);
- String msg = Converter.cCharPtrToJavaString(errMsg, false);
+ long [] error = new long [1]; // GError **
+ long gVariant = OS.g_dbus_connection_call_sync(connectionToExtension, EXTENSION_DBUS_NAME, EXTENSION_OBJECT_PATH,
+ EXTENSION_INTERFACE_NAME, Converter.javaStringToCString(methodName), params,
+ 0, OS.G_DBUS_CALL_FLAGS_NO_AUTO_START, 1000, 0, error);
+ if (error[0] != 0) {
+ String msg = Display.extractFreeGError(error[0]);
/*
* Don't print console warnings for timeout errors, as we can handle these ourselves.
* Note, most timeout errors happen only when running test cases, not during "normal" use.
*/
if (msg != null && (!msg.contains("Timeout") && !msg.contains("timeout"))) {
- System.err.println("SWT webkit: There was an error executing something synchronously with the extension.");
- System.err.println("SWT webkit: The error message is: " + msg);
+ System.err.println("SWT WebKitGDBus: there was an error executing something synchronously with the extension.");
+ System.err.println("SWT WebKitGDBus: the error message is: " + msg);
return (Object) false;
}
- OS.g_error_free(gerror[0]);
return (Object) "timeout";
}
Object resultObject = gVariant != 0 ? convertGVariantToJava(gVariant) : (Object) false;
@@ -472,15 +555,15 @@ class WebkitGDBus {
* @return true if the extension was called without errors, false otherwise
*/
static boolean callExtensionAsync (long params, String methodName) {
- long [] gerror = new long [1]; // GError **
- OS.g_dbus_proxy_call(proxy, Converter.javaStringToCString(methodName),
- params, OS.G_DBUS_CALL_FLAGS_NO_AUTO_START, 1000, 0, callExtensionAsyncCallback.getAddress(), gerror);
- if (gerror[0] != 0) {
- long errMsg = OS.g_error_get_message(gerror[0]);
- String msg = Converter.cCharPtrToJavaString(errMsg, false);
- System.err.println("SWT webkit: There was an error executing something asynchronously with the extension.");
- System.err.println("SWT webkit: The error message is: " + msg);
- OS.g_error_free(gerror[0]);
+ long [] error = new long [1]; // GError **
+ OS.g_dbus_connection_call(connectionToExtension, EXTENSION_DBUS_NAME, EXTENSION_OBJECT_PATH,
+ EXTENSION_INTERFACE_NAME, Converter.javaStringToCString(methodName), params,
+ 0, OS.G_DBUS_CALL_FLAGS_NO_AUTO_START, 1000, 0, callExtensionAsyncCB.getAddress(), 0);
+ if (error[0] != 0) {
+ String msg = Display.extractFreeGError(error[0]);
+ System.err.println("SWT WebKitGDBus: there was an error executing something asynchronously "
+ + "with the extension.");
+ System.err.println("SWT WebKitGDBus: the error message is: " + msg);
return false;
}
return true;
@@ -528,7 +611,7 @@ class WebkitGDBus {
case WebkitGDBus.SWT_DBUS_MAGIC_NUMBER_EMPTY_ARRAY:
return new Object [0];
default:
- System.err.println("SWT Error, received unsupported byte type via gdbus: " + byteVal);
+ System.err.println("SWT WebKitGDBus: received an unsupported byte type via GDBus: " + byteVal);
break;
}
}
@@ -607,7 +690,7 @@ class WebkitGDBus {
return OS.g_variant_new_tuple(variants, length);
}
- System.err.println("SWT Webkit: Invalid object being returned to javascript: " + javaObject.toString() + "\n"
+ System.err.println("SWT WebKitGDBus: invalid object being returned to JavaScript: " + javaObject.toString() + "\n"
+ "Only the following are supported: null, String, Boolean, Number(Long,Integer,Double...), Object[] of basic types");
throw new SWTException(SWT.ERROR_INVALID_ARGUMENT, "Given object is not valid: " + javaObject.toString());
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java
index 7d32b7d38c..c617cc3355 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java
@@ -219,6 +219,19 @@ public class Display extends Device {
SessionManagerListener sessionManagerListener;
Runnable [] disposeList;
+ /*
+ * DBus objects to be freed upong Display release. Only public for use in
+ * other areas of SWT (i.e. WebKit). See bug 540060.
+ */
+ /** @noreference */
+ public ArrayList<Long> dBusServers = new ArrayList<>();
+ /** @noreference */
+ public ArrayList<Long> dBusAuthObservers = new ArrayList<>();
+ /** @noreference */
+ public ArrayList<Long> dBusGUIDS = new ArrayList<>();
+ /** @noreference */
+ public ArrayList<Long> dBusConnections = new ArrayList<>();
+
/* Deferred Layout list */
Composite[] layoutDeferred;
int layoutDeferredCount;
@@ -3761,6 +3774,59 @@ void initializeSessionManager() {
sessionManagerDBus.addListener(sessionManagerListener);
}
+/**
+ * Some parts of SWT (like WebKit) use GDBus for IPC. Some of these objects
+ * cannot be disposed of in their own classes due to design challenges.
+ * In these instances we release them along with this Display. This ensures
+ * no Browser will be using them at disposal time.
+ */
+void releaseDBusServices() {
+ releaseSessionManager();
+ for (long connection : dBusConnections) {
+ if (OS.g_dbus_connection_is_closed(connection)) continue;
+ long [] error = new long [1];
+ boolean closed = OS.g_dbus_connection_close_sync(connection, 0, error);
+ if (error[0] != 0) {
+ String msg = extractFreeGError(error[0]);
+ System.err.println("SWT Display: error closing connection: " + msg);
+ }
+ if (closed) {
+ // Free this as we added a reference to it
+ OS.g_object_unref(connection);
+ }
+ }
+ for (long server : dBusServers) {
+ OS.g_dbus_server_stop(server);
+ OS.g_object_unref(server);
+ }
+ for (long authObserver : dBusAuthObservers) {
+ OS.g_object_unref(authObserver);
+ }
+ for (long guid : dBusGUIDS) {
+ OS.g_free(guid);
+ }
+ dBusConnections.clear();
+ dBusServers.clear();
+ dBusAuthObservers.clear();
+ dBusGUIDS.clear();
+ dBusServers = dBusAuthObservers = dBusGUIDS = dBusConnections = null;
+}
+
+/**
+ * Helper method to extract GError messages. Only call if the pointer is valid (i.e. non-zero).
+ *
+ * @param errorPtr pointer to the GError
+ * @return a String representing the error message that was set
+ *
+ * @noreference This method is not intended to be referenced by clients.
+ */
+public static String extractFreeGError(long errorPtr) {
+ long errorMessageC = OS.g_error_get_message(errorPtr);
+ String errorMessageStr = Converter.cCharPtrToJavaString(errorMessageC, false);
+ OS.g_error_free(errorPtr);
+ return errorMessageStr;
+}
+
void releaseSessionManager() {
if (sessionManagerDBus != null) {
sessionManagerDBus.dispose();
@@ -4497,6 +4563,7 @@ protected void release () {
disposeList = null;
synchronizer.releaseSynchronizer ();
synchronizer = null;
+ releaseDBusServices ();
releaseSessionManager ();
releaseDisplay ();
super.release ();

Back to the top