[epiphany] Handle a bit more gracefully the self-launch detection



commit 6ede0c3ebcbc129ea1112ee9f43427231ab50e07
Author: Xan Lopez <xan igalia com>
Date:   Tue Dec 11 17:29:19 2012 +0100

    Handle a bit more gracefully the self-launch detection
    
    Check whether the app that will launch a given download is actually
    the browser itself, and do nothing *before* going ahead. Seems better
    than actually launching and then aborting on startup through UUID
    hacks.

 embed/ephy-download.c               |    3 +-
 embed/ephy-embed-shell.c            |   44 +++++++++++++++++
 embed/ephy-embed-shell.h            |    4 ++
 lib/ephy-file-helpers.c             |   52 ++++++++++++--------
 lib/ephy-file-helpers.h             |   82 ++++++++++++++++---------------
 tests/Makefile.am                   |   12 ++++-
 tests/applications/defaults.list    |    5 ++
 tests/applications/epiphany.desktop |    8 +++
 tests/data/test.html                |    1 +
 tests/ephy-embed-shell-test.c       |   91 +++++++++++++++++++++++++++++++++++
 10 files changed, 240 insertions(+), 62 deletions(-)
---
diff --git a/embed/ephy-download.c b/embed/ephy-download.c
index 792f5c1..2713b75 100644
--- a/embed/ephy-download.c
+++ b/embed/ephy-download.c
@@ -670,7 +670,8 @@ ephy_download_do_download_action (EphyDownload *download,
         break;
       case EPHY_DOWNLOAD_ACTION_OPEN:
         LOG ("ephy_download_do_download_action: open");
-        ret = ephy_file_launch_handler (NULL, destination, priv->start_time);
+        ret = ephy_embed_shell_launch_handler (ephy_embed_shell_get_default (), 
+                                               destination, NULL, priv->start_time);
         break;
       case EPHY_DOWNLOAD_ACTION_NONE:
         LOG ("ephy_download_do_download_action: none");
diff --git a/embed/ephy-embed-shell.c b/embed/ephy-embed-shell.c
index c050d97..9821d4f 100644
--- a/embed/ephy-embed-shell.c
+++ b/embed/ephy-embed-shell.c
@@ -608,3 +608,47 @@ ephy_embed_shell_get_mode (EphyEmbedShell *shell)
   
   return shell->priv->mode;
 }
+
+/**
+ * ephy_embed_shell_launch_application:
+ * @shell: an #EphyEmbedShell
+ * @file: a #GFile to open
+ * @mime_type: the mime type of @file or %NULL
+ * @user_time: user time to prevent focus stealing
+ * 
+ * Tries to open @file with the right application, making sure we will
+ * not call ourselves in the process. This is needed to avoid
+ * potential infinite loops when opening unknown file types.
+ * 
+ * Returns: %TRUE on success
+ **/
+gboolean
+ephy_embed_shell_launch_handler (EphyEmbedShell *shell,
+                                 GFile *file,
+                                 const char *mime_type,
+                                 guint32 user_time)
+{
+  GAppInfo *app;
+  GList *list = NULL;
+  gboolean ret = FALSE;
+
+  g_return_val_if_fail (EPHY_IS_EMBED_SHELL (shell), FALSE);
+  g_return_val_if_fail (file || mime_type, FALSE);
+
+  app = ephy_file_launcher_get_app_info_for_file (file, mime_type);
+
+  /* Do not allow recursive calls into the browser, they can lead to
+   * infinite loops and they should never happen anyway. */
+
+  /* FIXME: eventually there should be a nice and safe way of getting
+   * the app ID from the GApplication itself, but for now let's
+   * hardcode the .desktop file name and use it here. */
+  if (!app || g_strcmp0 (g_app_info_get_id (app), "epiphany.desktop") == 0)
+    return ret;
+
+  list = g_list_append (list, file);
+  ret = ephy_file_launch_application (app, list, user_time, NULL);
+  g_list_free (list);
+
+  return ret;
+}
diff --git a/embed/ephy-embed-shell.h b/embed/ephy-embed-shell.h
index 7432e11..08558f7 100644
--- a/embed/ephy-embed-shell.h
+++ b/embed/ephy-embed-shell.h
@@ -91,6 +91,10 @@ void               ephy_embed_shell_add_download               (EphyEmbedShell
 void               ephy_embed_shell_remove_download            (EphyEmbedShell   *shell,
                                                                 EphyDownload     *download);
 EphyEmbedShellMode ephy_embed_shell_get_mode                   (EphyEmbedShell   *shell);
+gboolean           ephy_embed_shell_launch_handler             (EphyEmbedShell   *shell,
+                                                                GFile            *file,
+                                                                const char       *mime_type,
+                                                                guint32           user_time);
 
 G_END_DECLS
 
diff --git a/lib/ephy-file-helpers.c b/lib/ephy-file-helpers.c
index 680f2b5..8b61085 100644
--- a/lib/ephy-file-helpers.c
+++ b/lib/ephy-file-helpers.c
@@ -825,26 +825,13 @@ ephy_file_launch_desktop_file (const char *filename,
 	return ret;
 }
 
-/**
- * ephy_file_launch_handler:
- * @mime_type: the mime type of @file or %NULL
- * @file: a #GFile to pass as argument
- * @user_time: user time to prevent focus stealing
- *
- * Launches @file with its default handler application, if @mime_type is %NULL
- * then @file will be queried for its type.
- *
- * Returns: %TRUE on success
- **/
-gboolean
-ephy_file_launch_handler (const char *mime_type,
-			  GFile *file,
-			  guint32 user_time)
+GAppInfo *
+ephy_file_launcher_get_app_info_for_file (GFile *file,
+					  const char *mime_type)
 {
 	GAppInfo *app = NULL;
-	gboolean ret = FALSE;
 
-	g_return_val_if_fail (file != NULL, FALSE);
+	g_return_val_if_fail (file || mime_type, FALSE);
 
 	if (mime_type != NULL)
 	{
@@ -860,7 +847,8 @@ ephy_file_launch_handler (const char *mime_type,
 		file_info = g_file_query_info (file,
 					       G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
 					       0, NULL, NULL);
-		if (file_info == NULL) {
+		if (file_info == NULL)
+		{
 			return FALSE;
 		}
 		type = g_strdup (g_file_info_get_content_type (file_info));
@@ -876,6 +864,32 @@ ephy_file_launch_handler (const char *mime_type,
 		g_free (type);
 	}
 
+	return app;
+}
+
+/**
+ * ephy_file_launch_handler:
+ * @mime_type: the mime type of @file or %NULL
+ * @file: a #GFile to pass as argument
+ * @user_time: user time to prevent focus stealing
+ *
+ * Launches @file with its default handler application, if @mime_type is %NULL
+ * then @file will be queried for its type.
+ *
+ * Returns: %TRUE on success
+ **/
+gboolean
+ephy_file_launch_handler (const char *mime_type,
+			  GFile *file,
+			  guint32 user_time)
+{
+	GAppInfo *app = NULL;
+	gboolean ret = FALSE;
+
+	g_return_val_if_fail (file != NULL, FALSE);
+
+	app = ephy_file_launcher_get_app_info_for_file (file, mime_type);
+
 	if (app != NULL)
 	{
 		GList *list = NULL;
@@ -884,8 +898,6 @@ ephy_file_launch_handler (const char *mime_type,
 		ret = ephy_file_launch_application (app, list, user_time, NULL);
 		g_list_free (list);
 	}
-	else
-		ret = FALSE;
 
 	return ret;
 }
diff --git a/lib/ephy-file-helpers.h b/lib/ephy-file-helpers.h
index fc50c63..a80f450 100644
--- a/lib/ephy-file-helpers.h
+++ b/lib/ephy-file-helpers.h
@@ -52,46 +52,48 @@ typedef enum
 
 #define EPHY_UUID_ENVVAR	"EPHY_UNIQUE"
 
-gboolean           ephy_file_helpers_init        (const char  *profile_dir,
-                                                  EphyFileHelpersFlags flags,
-                                                  GError     **error);
-const char *       ephy_file                     (const char  *filename);
-const char *       ephy_dot_dir                  (void);
-gboolean           ephy_dot_dir_is_default       (void);
-void               ephy_file_helpers_shutdown    (void);
-char	   *       ephy_file_get_downloads_dir   (void);
-char       *       ephy_file_desktop_dir         (void);
-const char *       ephy_file_tmp_dir             (void);
-char       *       ephy_file_tmp_filename        (const char  *base,
-                                                  const char  *extension);
-gboolean           ephy_ensure_dir_exists        (const char  *dir,
-                                                  GError **);
-GSList     *       ephy_file_find                (const char  *path,
-                                                  const char  *fname,
-                                                  gint         maxdepth);
-gboolean           ephy_file_switch_temp_file    (GFile       *file_dest,
-                                                  GFile       *file_temp);
-void               ephy_file_delete_on_exit      (GFile       *file);
-EphyMimePermission ephy_file_check_mime          (const char  *mime_type);
-gboolean           ephy_file_launch_desktop_file (const char  *filename,
-                                                  const char  *parameter,
-                                                  guint32      user_time,
-                                                  GtkWidget   *widget);
-gboolean           ephy_file_launch_application  (GAppInfo    *app,
-                                                  GList       *files,
-                                                  guint32      user_time,
-                                                  GtkWidget   *widget);
-gboolean           ephy_file_launch_handler      (const char  *mime_type,
-                                                  GFile       *file,
-                                                  guint32      user_time);
-gboolean           ephy_file_browse_to           (GFile       *file,
-                                                  guint32      user_time);
-gboolean           ephy_file_delete_dir_recursively (GFile *file,
-                                                     GError      **error);
-void               ephy_file_delete_uri          (const char  *uri);
-char       *       ephy_file_create_data_uri_for_filename (const char *filename,
-                                                           const char *mime_type);
-char       *       ephy_sanitize_filename        (char *filename);
+gboolean           ephy_file_helpers_init                   (const char            *profile_dir,
+                                                             EphyFileHelpersFlags   flags,
+                                                             GError               **error);
+const char *       ephy_file                                (const char            *filename);
+const char *       ephy_dot_dir                             (void);
+gboolean           ephy_dot_dir_is_default                  (void);
+void               ephy_file_helpers_shutdown               (void);
+char	   *          ephy_file_get_downloads_dir              (void);
+char       *       ephy_file_desktop_dir                    (void);
+const char *       ephy_file_tmp_dir                        (void);
+char       *       ephy_file_tmp_filename                   (const char            *base,
+                                                             const char            *extension);
+gboolean           ephy_ensure_dir_exists                   (const char            *dir,
+                                                             GError **);
+GSList     *       ephy_file_find                           (const char            *path,
+                                                             const char            *fname,
+                                                             gint                   maxdepth);
+gboolean           ephy_file_switch_temp_file               (GFile                 *file_dest,
+                                                             GFile                 *file_temp);
+void               ephy_file_delete_on_exit                 (GFile                 *file);
+EphyMimePermission ephy_file_check_mime                     (const char            *mime_type);
+gboolean           ephy_file_launch_desktop_file            (const char            *filename,
+                                                             const char            *parameter,
+                                                             guint32                user_time,
+                                                             GtkWidget             *widget);
+gboolean           ephy_file_launch_application             (GAppInfo              *app,
+                                                             GList                 *files,
+                                                             guint32                user_time,
+                                                             GtkWidget             *widget);
+gboolean           ephy_file_launch_handler                 (const char            *mime_type,
+                                                             GFile                 *file,
+                                                             guint32                user_time);
+gboolean           ephy_file_browse_to                      (GFile                 *file,
+                                                             guint32                user_time);
+gboolean           ephy_file_delete_dir_recursively         (GFile                 *file,
+                                                             GError               **error);
+void               ephy_file_delete_uri                     (const char            *uri);
+char       *       ephy_file_create_data_uri_for_filename   (const char            *filename,
+                                                             const char            *mime_type);
+char       *       ephy_sanitize_filename                   (char                  *filename);
+GAppInfo   *       ephy_file_launcher_get_app_info_for_file (GFile                 *file,
+                                                             const char            *mime_type);
 
 G_END_DECLS
 
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 992547e..aaaf6c1 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -4,6 +4,7 @@ noinst_PROGRAMS = \
 	test-ephy-bookmarks \
 	test-ephy-completion-model \
 	test-ephy-download \
+	test-ephy-embed-shell \
 	test-ephy-embed-single \
 	test-ephy-embed-utils \
 	test-ephy-encodings \
@@ -100,7 +101,8 @@ INCLUDES = \
 	-I$(top_srcdir)/src/bookmarks
 
 CFLAGS = \
-	$(DEPENDENCIES_CFLAGS) \
+	-DTEST_DIR=\"$(srcdir)\"\
+	$(DEPENDENCIES_CFLAGS)  \
 	$(CODE_COVERAGE_CFLAGS) \
 	$(AM_CFLAGS)
 
@@ -125,6 +127,9 @@ test_ephy_completion_model_SOURCES = \
 test_ephy_download_SOURCES = \
 	ephy-download-test.c
 
+test_ephy_embed_shell_SOURCES = \
+	ephy-embed-shell-test.c
+
 test_ephy_embed_single_SOURCES = \
 	ephy-embed-single-test.c
 
@@ -173,3 +178,8 @@ test_ephy_web_app_utils_SOURCES = \
 
 test_ephy_web_view_SOURCES = \
 	ephy-web-view-test.c
+
+EXTRA_DIST = \
+	data/test.html \
+	applications/epiphany.desktop \
+	applications/defaults.list
diff --git a/tests/applications/defaults.list b/tests/applications/defaults.list
new file mode 100644
index 0000000..8947025
--- /dev/null
+++ b/tests/applications/defaults.list
@@ -0,0 +1,5 @@
+
+[Default Applications]
+text/html=epiphany.desktop
+
+
diff --git a/tests/applications/epiphany.desktop b/tests/applications/epiphany.desktop
new file mode 100644
index 0000000..8e5390c
--- /dev/null
+++ b/tests/applications/epiphany.desktop
@@ -0,0 +1,8 @@
+[Desktop Entry]
+Exec=epiphany %U
+StartupNotify=true
+Terminal=false
+Type=Application
+Icon=web-browser
+Categories=Network;GNOME;GTK;WebBrowser;
+MimeType=text/html;text/xml;application/xhtml+xml;x-scheme-handler/http;x-scheme-handler/https;
diff --git a/tests/data/test.html b/tests/data/test.html
new file mode 100644
index 0000000..f806b92
--- /dev/null
+++ b/tests/data/test.html
@@ -0,0 +1 @@
+<html>THIS IS A TEST!</html>
diff --git a/tests/ephy-embed-shell-test.c b/tests/ephy-embed-shell-test.c
new file mode 100644
index 0000000..27c1b9c
--- /dev/null
+++ b/tests/ephy-embed-shell-test.c
@@ -0,0 +1,91 @@
+/* vim: set sw=2 ts=2 sts=2 et: */
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * ephy-embed-shell-test.c
+ * This file is part of Epiphany
+ *
+ * Copyright  2012 - Igalia S.L.
+ *
+ * Epiphany is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Epiphany is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Epiphany; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA  02110-1301  USA
+ */
+
+#include "config.h"
+#include "ephy-debug.h"
+#include "ephy-embed.h"
+#include "ephy-embed-prefs.h"
+#include "ephy-embed-private.h"
+#include "ephy-embed-shell.h"
+#include "ephy-embed-utils.h"
+#include "ephy-file-helpers.h"
+#include "ephy-private.h"
+
+#include <glib.h>
+#include <gtk/gtk.h>
+
+static void
+test_ephy_embed_shell_launch_handler (void)
+{
+    EphyEmbedShell *embed_shell;
+    gboolean ret;
+    GFile *file;
+
+    embed_shell = ephy_embed_shell_get_default ();
+
+    ret = ephy_embed_shell_launch_handler (embed_shell, NULL, "text/html", 0);
+    g_assert (ret == FALSE);
+
+    file = g_file_new_for_path (TEST_DIR"/data/test.html");
+    g_assert (file);
+
+    ret = ephy_embed_shell_launch_handler (embed_shell, file, NULL, 0);
+    g_assert (ret == FALSE);
+
+    ret = ephy_embed_shell_launch_handler (embed_shell, file, "text/html", 0);
+    g_assert (ret == FALSE);
+
+    g_object_unref (file);
+}
+
+int
+main (int argc, char *argv[])
+{
+  int ret;
+
+  g_setenv ("XDG_DATA_DIRS", TEST_DIR, TRUE);
+  g_setenv ("XDG_DATA_HOME", TEST_DIR, TRUE);
+
+  gtk_test_init (&argc, &argv);
+
+  ephy_debug_init ();
+
+  if (!ephy_file_helpers_init (NULL, EPHY_FILE_HELPERS_PRIVATE_PROFILE | EPHY_FILE_HELPERS_ENSURE_EXISTS, NULL)) {
+    g_debug ("Something wrong happened with ephy_file_helpers_init()");
+    return -1;
+  }
+
+  _ephy_shell_create_instance (EPHY_EMBED_SHELL_MODE_TEST);
+  g_application_register (G_APPLICATION (ephy_embed_shell_get_default ()), NULL, NULL);
+
+  g_test_add_func ("/embed/ephy-embed-shell/launch_handler",
+                   test_ephy_embed_shell_launch_handler);
+
+  ret = g_test_run ();
+
+  g_object_unref (ephy_embed_shell_get_default ());
+  ephy_file_helpers_shutdown ();
+
+  return ret;
+}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]