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
--- a/jdk/src/solaris/classes/sun/awt/X11/XDesktopPeer.java Wed Dec 18 10:41:11 2013 +0000
+++ b/jdk/src/solaris/classes/sun/awt/X11/XDesktopPeer.java Wed Dec 18 11:01:33 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/jdk/src/solaris/native/sun/awt/gtk2_interface.c Wed Dec 18 10:41:11 2013 +0000
+++ b/jdk/src/solaris/native/sun/awt/gtk2_interface.c Wed Dec 18 11:01:33 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/jdk/src/solaris/native/sun/awt/gtk2_interface.h Wed Dec 18 10:41:11 2013 +0000
+++ b/jdk/src/solaris/native/sun/awt/gtk2_interface.h Wed Dec 18 11:01:33 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/jdk/src/solaris/native/sun/xawt/awt_Desktop.c Wed Dec 18 10:41:11 2013 +0000
+++ b/jdk/src/solaris/native/sun/xawt/awt_Desktop.c Wed Dec 18 11:01:33 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/jdk/test/java/awt/Desktop/OpenByUNCPathNameTest/OpenByUNCPathNameTest.java Wed Dec 18 10:41:11 2013 +0000
+++ b/jdk/test/java/awt/Desktop/OpenByUNCPathNameTest/OpenByUNCPathNameTest.java Wed Dec 18 11:01:33 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.