OpenJDK / jdk8u / jdk8u / jdk
changeset 8969:c8ec5c070592
8029263: user's default browser can not launch after we click the button, and there is an IOException shown in the log text (java.io.IOException)
Reviewed-by: anthony, serb
author | azvegint |
---|---|
date | Wed, 18 Dec 2013 11:09:31 +0000 |
parents | 20d504a20a87 |
children | 4ee27281d27d 75142ce752da |
files | src/solaris/classes/sun/awt/X11/XDesktopPeer.java src/solaris/native/sun/awt/gtk2_interface.c src/solaris/native/sun/awt/gtk2_interface.h src/solaris/native/sun/xawt/awt_Desktop.c test/java/awt/Desktop/OpenByUNCPathNameTest/OpenByUNCPathNameTest.java |
diffstat | 5 files changed, 89 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/src/solaris/classes/sun/awt/X11/XDesktopPeer.java Fri Dec 13 14:29:17 2013 +0400 +++ b/src/solaris/classes/sun/awt/X11/XDesktopPeer.java Wed Dec 18 11:09:31 2013 +0000 @@ -33,6 +33,9 @@ import java.awt.Desktop.Action; import java.awt.peer.DesktopPeer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; /** @@ -43,6 +46,10 @@ */ public class XDesktopPeer implements DesktopPeer { + // supportedActions may be changed from native within an init() call + private static final List<Action> supportedActions + = new ArrayList<>(Arrays.asList(Action.OPEN, Action.MAIL, Action.BROWSE)); + private static boolean nativeLibraryLoaded = false; private static boolean initExecuted = false; @@ -65,11 +72,11 @@ static boolean isDesktopSupported() { initWithLock(); - return nativeLibraryLoaded; + return nativeLibraryLoaded && !supportedActions.isEmpty(); } public boolean isSupported(Action type) { - return type != Action.PRINT && type != Action.EDIT; + return supportedActions.contains(type); } public void open(File file) throws IOException {
--- a/src/solaris/native/sun/awt/gtk2_interface.c Fri Dec 13 14:29:17 2013 +0400 +++ b/src/solaris/native/sun/awt/gtk2_interface.c Wed Dec 18 11:09:31 2013 +0000 @@ -438,10 +438,76 @@ } } +#define ADD_SUPPORTED_ACTION(actionStr) \ +do { \ + jfieldID fld_action = (*env)->GetStaticFieldID(env, cls_action, actionStr, "Ljava/awt/Desktop$Action;"); \ + if (!(*env)->ExceptionCheck(env)) { \ + jobject action = (*env)->GetStaticObjectField(env, cls_action, fld_action); \ + (*env)->CallBooleanMethod(env, supportedActions, mid_arrayListAdd, action); \ + } else { \ + (*env)->ExceptionClear(env); \ + } \ +} while(0); + + +void update_supported_actions(JNIEnv *env) { + GVfs * (*fp_g_vfs_get_default) (void); + const gchar * const * (*fp_g_vfs_get_supported_uri_schemes) (GVfs * vfs); + const gchar * const * schemes = NULL; + + jclass cls_action = (*env)->FindClass(env, "java/awt/Desktop$Action"); + jclass cls_xDesktopPeer = (*env)->FindClass(env, "sun/awt/X11/XDesktopPeer"); + jfieldID fld_supportedActions = (*env)->GetStaticFieldID(env, cls_xDesktopPeer, "supportedActions", "Ljava/util/List;"); + jobject supportedActions = (*env)->GetStaticObjectField(env, cls_xDesktopPeer, fld_supportedActions); + + jclass cls_arrayList = (*env)->FindClass(env, "java/util/ArrayList"); + jmethodID mid_arrayListAdd = (*env)->GetMethodID(env, cls_arrayList, "add", "(Ljava/lang/Object;)Z"); + jmethodID mid_arrayListClear = (*env)->GetMethodID(env, cls_arrayList, "clear", "()V"); + + (*env)->CallVoidMethod(env, supportedActions, mid_arrayListClear); + + ADD_SUPPORTED_ACTION("OPEN"); + + /** + * gtk_show_uri() documentation says: + * + * > you need to install gvfs to get support for uri schemes such as http:// + * > or ftp://, as only local files are handled by GIO itself. + * + * So OPEN action was safely added here. + * However, it looks like Solaris 11 have gvfs support only for 32-bit + * applications only by default. + */ + + fp_g_vfs_get_default = dl_symbol("g_vfs_get_default"); + fp_g_vfs_get_supported_uri_schemes = dl_symbol("g_vfs_get_supported_uri_schemes"); + dlerror(); + + if (fp_g_vfs_get_default && fp_g_vfs_get_supported_uri_schemes) { + GVfs * vfs = fp_g_vfs_get_default(); + schemes = vfs ? fp_g_vfs_get_supported_uri_schemes(vfs) : NULL; + if (schemes) { + int i = 0; + while (schemes[i]) { + if (strcmp(schemes[i], "http") == 0) { + ADD_SUPPORTED_ACTION("BROWSE"); + ADD_SUPPORTED_ACTION("MAIL"); + break; + } + i++; + } + } + } else { +#ifdef INTERNAL_BUILD + fprintf(stderr, "Cannot load g_vfs_get_supported_uri_schemes\n"); +#endif /* INTERNAL_BUILD */ + } + +} /** * Functions for awt_Desktop.c */ -gboolean gtk2_show_uri_load() { +gboolean gtk2_show_uri_load(JNIEnv *env) { gboolean success = FALSE; dlerror(); const char *gtk_version = fp_gtk_check_version(2, 14, 0); @@ -464,9 +530,12 @@ #ifdef INTERNAL_BUILD fprintf(stderr, "dlsym(gtk_show_uri) returned NULL\n"); #endif /* INTERNAL_BUILD */ - } else { - success = TRUE; - } + } else { +#ifdef __solaris__ + update_supported_actions(env); +#endif + success = TRUE; + } } return success; }
--- a/src/solaris/native/sun/awt/gtk2_interface.h Fri Dec 13 14:29:17 2013 +0400 +++ b/src/solaris/native/sun/awt/gtk2_interface.h Wed Dec 18 11:09:31 2013 +0000 @@ -270,6 +270,7 @@ /* We define all structure pointers to be void* */ typedef void GError; typedef void GMainContext; +typedef void GVfs; typedef struct _GSList GSList; struct _GSList @@ -689,7 +690,7 @@ * gtk2_load, so it must be invoked only after a successful gtk2_load * invocation */ -gboolean gtk2_show_uri_load(); +gboolean gtk2_show_uri_load(JNIEnv *env); /* * Unload the gtk2 library. If the library is already unloaded this method has
--- a/src/solaris/native/sun/xawt/awt_Desktop.c Fri Dec 13 14:29:17 2013 +0400 +++ b/src/solaris/native/sun/xawt/awt_Desktop.c Wed Dec 18 11:09:31 2013 +0000 @@ -42,7 +42,7 @@ return JNI_TRUE; } - if (gtk2_load(env) && gtk2_show_uri_load()) { + if (gtk2_load(env) && gtk2_show_uri_load(env)) { gtk_has_been_loaded = TRUE; return JNI_TRUE; } else if (gnome_load()) {
--- a/test/java/awt/Desktop/OpenByUNCPathNameTest/OpenByUNCPathNameTest.java Fri Dec 13 14:29:17 2013 +0400 +++ b/test/java/awt/Desktop/OpenByUNCPathNameTest/OpenByUNCPathNameTest.java Wed Dec 18 11:09:31 2013 +0000 @@ -45,6 +45,10 @@ System.out.println("java.awt.Desktop is not supported on this platform."); } else { Desktop desktop = Desktop.getDesktop(); + if (!desktop.isSupported(Desktop.Action.OPEN)) { + System.out.println("Action.OPEN is not supported on this platform."); + return; + } File file = File.createTempFile("Read Me File", ".txt"); try { // Test opening of the file with Windows local file path.