Bug 402892. Support gio as well as gnome-vfs. r=roc
authorjhorak@redhat.com
Tue, 25 Aug 2009 11:58:11 -0700
changeset 31951 2572312e17df
parent 31950 6db996debbd1
child 31952 01bbe887b004
push idunknown
push userunknown
push dateunknown
reviewersroc
bugs402892
milestone1.9.3a1pre
Bug 402892. Support gio as well as gnome-vfs. r=roc
browser/components/shell/src/nsGNOMEShellService.cpp
config/autoconf.mk.in
config/system_wrappers/gio/gio.h
configure.in
toolkit/system/gnome/Makefile.in
toolkit/system/gnome/nsGIOService.cpp
toolkit/system/gnome/nsGIOService.h
toolkit/system/gnome/nsGnomeModule.cpp
uriloader/exthandler/Makefile.in
uriloader/exthandler/unix/nsGNOMERegistry.cpp
uriloader/exthandler/unix/nsMIMEInfoUnix.cpp
xpcom/io/nsLocalFileUnix.cpp
xpcom/system/Makefile.in
xpcom/system/nsIGIOService.idl
--- a/browser/components/shell/src/nsGNOMEShellService.cpp
+++ b/browser/components/shell/src/nsGNOMEShellService.cpp
@@ -40,16 +40,17 @@
 #include "nsIServiceManager.h"
 #include "nsILocalFile.h"
 #include "nsIProperties.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsIPrefService.h"
 #include "prenv.h"
 #include "nsStringAPI.h"
 #include "nsIGConfService.h"
+#include "nsIGIOService.h"
 #include "nsIGnomeVFSService.h"
 #include "nsIStringBundle.h"
 #include "nsIOutputStream.h"
 #include "nsIProcess.h"
 #include "nsNetUtil.h"
 #include "nsIDOMHTMLImageElement.h"
 #include "nsIImageLoadingContent.h"
 #include "imgIRequest.h"
@@ -105,20 +106,22 @@ nsresult
 nsGNOMEShellService::Init()
 {
   nsresult rv;
 
   // GConf and GnomeVFS _must_ be available, or we do not allow
   // CreateInstance to succeed.
 
   nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID);
-  nsCOMPtr<nsIGnomeVFSService> vfs =
+  nsCOMPtr<nsIGIOService> giovfs =
+    do_GetService(NS_GIOSERVICE_CONTRACTID);
+  nsCOMPtr<nsIGnomeVFSService> gnomevfs =
     do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID);
 
-  if (!gconf || !vfs)
+  if (!gconf || (!giovfs && !gnomevfs))
     return NS_ERROR_NOT_AVAILABLE;
 
   // Check G_BROKEN_FILENAMES.  If it's set, then filenames in glib use
   // the locale encoding.  If it's not set, they use UTF-8.
   mUseLocaleFilenames = PR_GetEnv("G_BROKEN_FILENAMES") != nsnull;
 
   nsCOMPtr<nsIProperties> dirSvc
     (do_GetService("@mozilla.org/file/directory_service;1"));
@@ -210,33 +213,37 @@ nsGNOMEShellService::SetDefaultBrowser(P
 {
 #ifdef DEBUG
   if (aForAllUsers)
     NS_WARNING("Setting the default browser for all users is not yet supported");
 #endif
 
   nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID);
 
-  nsCAutoString schemeList;
+  nsCAutoString schemeList; /* For GnomeVFS fallback */
   nsCAutoString appKeyValue(mAppPath);
   appKeyValue.Append(" \"%s\"");
   unsigned int i;
 
   for (i = 0; i < NS_ARRAY_LENGTH(appProtocols); ++i) {
+    /* For GnomeVFS fallback */
     schemeList.Append(nsDependentCString(appProtocols[i].name));
     schemeList.Append(',');
 
     if (appProtocols[i].essential || aClaimAllTypes) {
       gconf->SetAppForProtocol(nsDependentCString(appProtocols[i].name),
                                appKeyValue);
     }
   }
 
+  // set handler for .html and xhtml files and MIME types:
   if (aClaimAllTypes) {
-    nsCOMPtr<nsIGnomeVFSService> vfs =
+    nsCOMPtr<nsIGIOService> giovfs =
+      do_GetService(NS_GIOSERVICE_CONTRACTID);
+    nsCOMPtr<nsIGnomeVFSService> gnomevfs =
       do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID);
 
     nsCOMPtr<nsIStringBundleService> bundleService =
       do_GetService(NS_STRINGBUNDLE_CONTRACTID);
     NS_ENSURE_TRUE(bundleService, NS_ERROR_OUT_OF_MEMORY);
 
     nsCOMPtr<nsIStringBundle> brandBundle;
     bundleService->CreateBundle(BRAND_PROPERTIES, getter_AddRefs(brandBundle));
@@ -245,72 +252,86 @@ nsGNOMEShellService::SetDefaultBrowser(P
     nsString brandShortName, brandFullName;
     brandBundle->GetStringFromName(NS_LITERAL_STRING("brandShortName").get(),
                                    getter_Copies(brandShortName));
     brandBundle->GetStringFromName(NS_LITERAL_STRING("brandFullName").get(),
                                    getter_Copies(brandFullName));
 
     // use brandShortName as the application id.
     NS_ConvertUTF16toUTF8 id(brandShortName);
+    if (giovfs) {
+      nsCOMPtr<nsIGIOMimeApp> appInfo;
+      giovfs->CreateAppFromCommand(mAppPath,
+                                id,
+                                getter_AddRefs(appInfo));
 
-    vfs->SetAppStringKey(id, nsIGnomeVFSService::APP_KEY_COMMAND, mAppPath);
-    vfs->SetAppStringKey(id, nsIGnomeVFSService::APP_KEY_NAME,
-                         NS_ConvertUTF16toUTF8(brandFullName));
+      // Add mime types for html, xhtml extension and set app to just created appinfo.
+      for (i = 0; i < NS_ARRAY_LENGTH(appTypes); ++i) {
+        appInfo->SetAsDefaultForMimeType(nsDependentCString(appTypes[i].mimeType));
+        appInfo->SetAsDefaultForFileExtensions(nsDependentCString(appTypes[i].extensions));
+      }
+    } else {
+       /* Fallback GnomeVFS */
+       gnomevfs->SetAppStringKey(id, nsIGnomeVFSService::APP_KEY_COMMAND, mAppPath);
+       gnomevfs->SetAppStringKey(id, nsIGnomeVFSService::APP_KEY_NAME,
+                            NS_ConvertUTF16toUTF8(brandFullName));
 
     // We don't want to be the default handler for "file:", but we do
     // want Nautilus to know that we support file: if the MIME type is
     // one that we can handle.
 
     schemeList.Append("file");
 
-    vfs->SetAppStringKey(id, nsIGnomeVFSService::APP_KEY_SUPPORTED_URI_SCHEMES,
-                         schemeList);
+       gnomevfs->SetAppStringKey(id, nsIGnomeVFSService::APP_KEY_SUPPORTED_URI_SCHEMES,
+                            schemeList);
 
-    vfs->SetAppStringKey(id, nsIGnomeVFSService::APP_KEY_EXPECTS_URIS,
-                         NS_LITERAL_CSTRING("true"));
+       gnomevfs->SetAppStringKey(id, nsIGnomeVFSService::APP_KEY_EXPECTS_URIS,
+                            NS_LITERAL_CSTRING("true"));
 
-    vfs->SetAppBoolKey(id, nsIGnomeVFSService::APP_KEY_CAN_OPEN_MULTIPLE,
-                       PR_FALSE);
+       gnomevfs->SetAppBoolKey(id, nsIGnomeVFSService::APP_KEY_CAN_OPEN_MULTIPLE,
+                          PR_FALSE);
 
-    vfs->SetAppBoolKey(id, nsIGnomeVFSService::APP_KEY_REQUIRES_TERMINAL,
-                       PR_FALSE);
+       gnomevfs->SetAppBoolKey(id, nsIGnomeVFSService::APP_KEY_REQUIRES_TERMINAL,
+                          PR_FALSE);
 
     // Copy icons/document.png to ~/.icons/firefox-document.png
     nsCAutoString iconFilePath(mAppPath);
     PRInt32 lastSlash = iconFilePath.RFindChar(PRUnichar('/'));
     if (lastSlash == -1) {
       NS_ERROR("no slash in executable path?");
     } else {
       iconFilePath.SetLength(lastSlash);
       nsCOMPtr<nsILocalFile> iconFile;
       NS_NewNativeLocalFile(iconFilePath, PR_FALSE, getter_AddRefs(iconFile));
       if (iconFile) {
         iconFile->AppendRelativeNativePath(NS_LITERAL_CSTRING("icons/document.png"));
 
-        nsCOMPtr<nsILocalFile> userIconPath;
-        NS_NewNativeLocalFile(nsDependentCString(PR_GetEnv("HOME")), PR_FALSE,
-                              getter_AddRefs(userIconPath));
-        if (userIconPath) {
-          userIconPath->AppendNative(NS_LITERAL_CSTRING(".icons"));
-          iconFile->CopyToNative(userIconPath,
-                                 nsDependentCString(kDocumentIconPath));
-        }
-      }
+           nsCOMPtr<nsILocalFile> userIconPath;
+           NS_NewNativeLocalFile(nsDependentCString(PR_GetEnv("HOME")), PR_FALSE,
+                                 getter_AddRefs(userIconPath));
+           if (userIconPath) {
+             userIconPath->AppendNative(NS_LITERAL_CSTRING(".icons"));
+             iconFile->CopyToNative(userIconPath,
+                                    nsDependentCString(kDocumentIconPath));
+           }
+         }
+       }
+
+       for (i = 0; i < NS_ARRAY_LENGTH(appTypes); ++i) {
+         gnomevfs->AddMimeType(id, nsDependentCString(appTypes[i].mimeType));
+         gnomevfs->SetMimeExtensions(nsDependentCString(appTypes[i].mimeType),
+                                nsDependentCString(appTypes[i].extensions));
+         gnomevfs->SetAppForMimeType(nsDependentCString(appTypes[i].mimeType), id);
+         gnomevfs->SetIconForMimeType(nsDependentCString(appTypes[i].mimeType),
+                                 NS_LITERAL_CSTRING(kDocumentIconPath));
+       }
+
+       gnomevfs->SyncAppRegistry();
+
     }
-
-    for (i = 0; i < NS_ARRAY_LENGTH(appTypes); ++i) {
-      vfs->AddMimeType(id, nsDependentCString(appTypes[i].mimeType));
-      vfs->SetMimeExtensions(nsDependentCString(appTypes[i].mimeType),
-                             nsDependentCString(appTypes[i].extensions));
-      vfs->SetAppForMimeType(nsDependentCString(appTypes[i].mimeType), id);
-      vfs->SetIconForMimeType(nsDependentCString(appTypes[i].mimeType),
-                              NS_LITERAL_CSTRING(kDocumentIconPath));
-    }
-
-    vfs->SyncAppRegistry();
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsGNOMEShellService::GetShouldCheckDefaultBrowser(PRBool* aResult)
 {
--- a/config/autoconf.mk.in
+++ b/config/autoconf.mk.in
@@ -261,16 +261,20 @@ MOZ_GNOMEVFS_CFLAGS = @MOZ_GNOMEVFS_CFLA
 MOZ_GNOMEVFS_LIBS = @MOZ_GNOMEVFS_LIBS@
 
 MOZ_ENABLE_GCONF = @MOZ_ENABLE_GCONF@
 MOZ_GCONF_CFLAGS = @MOZ_GCONF_CFLAGS@
 MOZ_GCONF_LIBS = @MOZ_GCONF_LIBS@
 
 MOZ_ENABLE_GNOME_COMPONENT = @MOZ_ENABLE_GNOME_COMPONENT@
 
+MOZ_ENABLE_GIO = @MOZ_ENABLE_GIO@
+MOZ_GIO_CFLAGS = @MOZ_GIO_CFLAGS@
+MOZ_GIO_LIBS = @MOZ_GIO_LIBS@
+
 MOZ_INSURE = @MOZ_INSURE@
 MOZ_INSURIFYING = @MOZ_INSURIFYING@
 MOZ_INSURE_DIRS = @MOZ_INSURE_DIRS@
 MOZ_INSURE_EXCLUDE_DIRS = @MOZ_INSURE_EXCLUDE_DIRS@
 
 MOZ_NATIVE_NSPR = @MOZ_NATIVE_NSPR@
 MOZ_NATIVE_NSS = @MOZ_NATIVE_NSS@
 
new file mode 100644
--- /dev/null
+++ b/config/system_wrappers/gio/gio.h
@@ -0,0 +1,4 @@
+#pragma GCC system_header 
+#pragma GCC visibility push(default) 
+#include_next <gio/gio.h> 
+#pragma GCC visibility pop
--- a/configure.in
+++ b/configure.in
@@ -123,16 +123,17 @@ CAIRO_VERSION=1.6.0
 PANGO_VERSION=1.14.0
 GTK2_VERSION=2.10.0
 WINDRES_VERSION=2.14.90
 W32API_VERSION=3.8
 GNOMEVFS_VERSION=2.0
 GNOMEUI_VERSION=2.2.0
 GCONF_VERSION=1.2.1
 LIBGNOME_VERSION=2.0
+GIO_VERSION=2.0
 STARTUP_NOTIFICATION_VERSION=0.8
 DBUS_VERSION=0.60
 SQLITE_VERSION=3.6.16
 LIBNOTIFY_VERSION=0.4
 
 MSMANIFEST_TOOL=
 
 dnl Set various checks
@@ -5149,16 +5150,17 @@ then
         MOZ_ENABLE_GNOMEVFS=,
         MOZ_ENABLE_GNOMEVFS=force)
 
     if test "$MOZ_ENABLE_GNOMEVFS"
     then
         PKG_CHECK_MODULES(MOZ_GNOMEVFS, gnome-vfs-2.0 >= $GNOMEVFS_VERSION gnome-vfs-module-2.0 >= $GNOMEVFS_VERSION,[
             MOZ_GNOMEVFS_LIBS=`echo $MOZ_GNOMEVFS_LIBS | sed 's/-llinc\>//'`
             MOZ_ENABLE_GNOMEVFS=1
+            AC_DEFINE(MOZ_ENABLE_GNOMEVFS)
         ],[
             if test "$MOZ_ENABLE_GNOMEVFS" = "force"
             then
                 AC_MSG_ERROR([* * * Could not find gnome-vfs-module-2.0 >= $GNOMEVFS_VERSION])
             fi
             MOZ_ENABLE_GNOMEVFS=
         ])
     fi
@@ -5180,27 +5182,42 @@ then
     if test "$MOZ_ENABLE_GCONF"; then
         AC_DEFINE(MOZ_ENABLE_GCONF)
     fi
 
     AC_SUBST(MOZ_ENABLE_GCONF)
     AC_SUBST(MOZ_GCONF_CFLAGS)
     AC_SUBST(MOZ_GCONF_LIBS)
 
-    # The GNOME component is built if gtk2, gconf and gnome-vfs
-    # are all available.
-
-    if test "$MOZ_ENABLE_GTK2" -a "$MOZ_ENABLE_GCONF" -a \
-            "$MOZ_ENABLE_GNOMEVFS"; then
-      MOZ_ENABLE_GNOME_COMPONENT=1
-    else
-      MOZ_ENABLE_GNOME_COMPONENT=
-    fi
-
-    AC_SUBST(MOZ_ENABLE_GNOME_COMPONENT)
+    dnl ========================================================
+    dnl = GIO support module
+    dnl ========================================================
+    MOZ_ARG_ENABLE_BOOL(gio,
+    [  --enable-gio            Enable GIO support (default: disabled)],
+        MOZ_ENABLE_GIO=force,
+        MOZ_ENABLE_GIO=)
+
+    if test "$MOZ_ENABLE_GIO" -a "$MOZ_ENABLE_GTK2"
+    then
+        PKG_CHECK_MODULES(MOZ_GIO, gio-2.0 >= $GIO_VERSION,[
+            MOZ_GIO_LIBS=`echo $MOZ_GIO_LIBS | sed 's/-llinc\>//'`
+            MOZ_ENABLE_GIO=1
+            AC_DEFINE(MOZ_ENABLE_GIO)
+        ],[
+            if test "$MOZ_ENABLE_GIO" = "force"
+            then
+                AC_MSG_ERROR([* * * Could not find gio-2.0 >= $GIO_VERSION])
+            fi
+            MOZ_ENABLE_GIO=
+        ])
+    fi
+
+    AC_SUBST(MOZ_ENABLE_GIO)
+    AC_SUBST(MOZ_GIO_CFLAGS)
+    AC_SUBST(MOZ_GIO_LIBS)
 fi
 
 dnl ========================================================
 dnl = libgnomeui support module
 dnl ========================================================
 
 if test "$MOZ_ENABLE_GTK2"
 then
@@ -5224,16 +5241,28 @@ then
             fi
             MOZ_ENABLE_GNOMEUI=
         ])
     fi
 
     if test "$MOZ_ENABLE_GNOMEUI"; then
         AC_DEFINE(MOZ_ENABLE_GNOMEUI)
     fi
+
+    # The GNOME component is built if gtk2, gconf and gnome-vfs
+    # are all available.
+
+    if test "$MOZ_ENABLE_GTK2" -a "$MOZ_ENABLE_GCONF" && \
+            (test "$MOZ_ENABLE_GNOMEVFS" || test "$MOZ_ENABLE_GIO"); then
+      MOZ_ENABLE_GNOME_COMPONENT=1
+    else
+      MOZ_ENABLE_GNOME_COMPONENT=
+    fi
+
+    AC_SUBST(MOZ_ENABLE_GNOME_COMPONENT)
 fi
 AC_SUBST(MOZ_ENABLE_GNOMEUI)
 AC_SUBST(MOZ_GNOMEUI_CFLAGS)
 AC_SUBST(MOZ_GNOMEUI_LIBS)
 
 dnl ========================================================
 dnl = dbus support
 dnl ========================================================
@@ -5744,16 +5773,24 @@ done],
 if test -z "$MOZ_ENABLE_GNOMEVFS" && test `echo "$MOZ_EXTENSIONS" | grep -c gnomevfs` -ne 0; then
     # Suppress warning on non-X11 platforms
     if test -n "$MOZ_X11"; then
         AC_MSG_WARN([Cannot build gnomevfs without required libraries. Removing gnomevfs from MOZ_EXTENSIONS.])
     fi
     MOZ_EXTENSIONS=`echo $MOZ_EXTENSIONS | sed -e 's|gnomevfs||'`
 fi
 
+if test -z "$MOZ_ENABLE_GIO" && test `echo "$MOZ_EXTENSIONS" | grep -c gio` -ne 0; then
+    # Suppress warning on non-X11 platforms
+    if test -n "$MOZ_X11"; then
+        AC_MSG_WARN([Cannot build gio without required libraries. Removing gio from MOZ_EXTENSIONS.])
+    fi
+    MOZ_EXTENSIONS=`echo $MOZ_EXTENSIONS | sed -e 's|gio||'`
+fi
+
 if test -z "$MOZ_JSDEBUGGER" && test `echo "$MOZ_EXTENSIONS" | grep -c venkman` -ne 0; then
     AC_MSG_WARN([Cannot build venkman without JavaScript debug library. Removing venkman from MOZ_EXTENSIONS.])
     MOZ_EXTENSIONS=`echo $MOZ_EXTENSIONS | sed -e 's|venkman||'`
 fi
 
 dnl This might be temporary: build tridentprofile only on Windows
 if test `echo "$MOZ_EXTENSIONS" | grep -c tridentprofile` -ne 0 && test "$OS_ARCH" != "WINNT"; then
     AC_MSG_WARN([tridentprofile extension works only on Windows at this time. Removing tridentprofile from MOZ_EXTENSIONS.])
--- a/toolkit/system/gnome/Makefile.in
+++ b/toolkit/system/gnome/Makefile.in
@@ -45,19 +45,31 @@ include $(DEPTH)/config/autoconf.mk
 MODULE		= mozgnome
 LIBRARY_NAME	= mozgnome
 FORCE_SHARED_LIB = 1
 IS_COMPONENT	= 1
 
 
 CPPSRCS = \
 	nsGConfService.cpp \
-	nsGnomeVFSService.cpp \
 	nsGnomeModule.cpp \
 	$(NULL)
+	
+
+ifdef MOZ_ENABLE_GNOMEVFS
+CPPSRCS += \
+	nsGnomeVFSService.cpp \
+	$(NULL)
+endif
+
+ifdef MOZ_ENABLE_GIO
+CPPSRCS += \
+	nsGIOService.cpp \
+	$(NULL)
+endif
 
 ifdef MOZ_ENABLE_LIBNOTIFY
 REQUIRES += thebes
 CPPSRCS += \
 	nsAlertsService.cpp \
 	nsAlertsIconListener.cpp \
 	$(NULL)
 endif
@@ -65,20 +77,22 @@ endif
 EXTRA_DSO_LDOPTS += \
 		$(XPCOM_GLUE_LDOPTS) \
 		$(XPCOM_FROZEN_LDOPTS) \
 		$(NSPR_LIBS) \
 		$(MOZ_GCONF_LIBS) \
 		$(MOZ_GNOMEVFS_LIBS) \
 		$(GLIB_LIBS) \
 		$(MOZ_LIBNOTIFY_LIBS) \
+		$(MOZ_GIO_LIBS) \
 		$(NULL)
 
 LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/components/build/
 
 include $(topsrcdir)/config/rules.mk
 
 CXXFLAGS += \
 	$(MOZ_GCONF_CFLAGS) \
 	$(MOZ_GNOMEVFS_CFLAGS) \
 	$(GLIB_CFLAGS) \
 	$(MOZ_LIBNOTIFY_CFLAGS) \
+	$(MOZ_GTK2_CFLAGS) \
 	$(NULL)
new file mode 100644
--- /dev/null
+++ b/toolkit/system/gnome/nsGIOService.cpp
@@ -0,0 +1,488 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Mozilla GNOME integration code.
+ *
+ * The Initial Developer of the Original Code is
+ * Red Hat, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Jan Horak <jhorak@redhat.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsGIOService.h"
+#include "nsStringAPI.h"
+#include "nsIURI.h"
+#include "nsTArray.h"
+#include "nsIStringEnumerator.h"
+#include "nsAutoPtr.h"
+#include <dlfcn.h>
+
+#include <gio/gio.h>
+#include <gtk/gtk.h>
+
+
+typedef const char* (*get_commandline_t)(GAppInfo*);
+
+char *
+get_content_type_from_mime_type(const char *mimeType)
+{
+  GList* contentTypes = g_content_types_get_registered();
+  GList* ct_ptr = contentTypes;
+  char* foundContentType = NULL;
+
+  while (ct_ptr) {
+    char *mimeTypeFromContentType =  g_content_type_get_mime_type((char*)ct_ptr->data);
+    if (strcmp(mimeTypeFromContentType, mimeType) == 0) {
+      foundContentType = strdup((char*)ct_ptr->data);
+      g_free(mimeTypeFromContentType);
+      break;
+    }
+    g_free(mimeTypeFromContentType);
+    ct_ptr = ct_ptr->next;
+  }
+  g_list_foreach(contentTypes, (GFunc) g_free, NULL);
+  g_list_free(contentTypes);
+  return foundContentType;
+}
+
+class nsGIOMimeApp : public nsIGIOMimeApp
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIGIOMIMEAPP
+
+  nsGIOMimeApp(GAppInfo* aApp) : mApp(aApp) {}
+  ~nsGIOMimeApp() { g_object_unref(mApp); }
+
+private:
+  GAppInfo *mApp;
+};
+
+NS_IMPL_ISUPPORTS1(nsGIOMimeApp, nsIGIOMimeApp)
+
+NS_IMETHODIMP
+nsGIOMimeApp::GetId(nsACString& aId)
+{
+  aId.Assign(g_app_info_get_id(mApp));
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsGIOMimeApp::GetName(nsACString& aName)
+{
+  aName.Assign(g_app_info_get_name(mApp));
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsGIOMimeApp::GetCommand(nsACString& aCommand)
+{
+  get_commandline_t g_app_info_get_commandline_ptr;
+
+  void *libHandle = dlopen("libgio-2.0.so", RTLD_LAZY);
+  if (!libHandle) {
+    return NS_ERROR_FAILURE;
+  }
+  dlerror(); /* clear any existing error */
+  g_app_info_get_commandline_ptr =
+    (get_commandline_t) dlsym(libHandle, "g_app_info_get_commandline");
+  if (dlerror() != NULL) {
+    const char cmd = *g_app_info_get_commandline_ptr(mApp);
+    if (!cmd) {
+      dlclose(libHandle);
+      return NS_ERROR_FAILURE;
+    }
+    aCommand.Assign(cmd);
+  }
+  dlclose(libHandle);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsGIOMimeApp::GetExpectsURIs(PRInt32* aExpects)
+{
+  *aExpects = g_app_info_supports_uris(mApp);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsGIOMimeApp::Launch(const nsACString& aUri)
+{
+  char *uri = strdup(PromiseFlatCString(aUri).get());
+
+  if (!uri)
+    return NS_ERROR_OUT_OF_MEMORY;
+
+  GList *uris = g_list_append(NULL, uri);
+
+  if (!uris) {
+    g_free(uri);
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
+  GError *error = NULL;
+  gboolean result = g_app_info_launch_uris(mApp, uris, NULL, &error);
+
+  g_free(uri);
+  g_list_free(uris);
+
+  if (!result) {
+    g_warning("Cannot launch application: %s", error->message);
+    g_error_free(error);
+    return NS_ERROR_FAILURE;
+  }
+
+  return NS_OK;
+}
+
+class GIOUTF8StringEnumerator : public nsIUTF8StringEnumerator
+{
+public:
+  GIOUTF8StringEnumerator() : mIndex(0) { }
+  ~GIOUTF8StringEnumerator() { }
+
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIUTF8STRINGENUMERATOR
+
+  nsTArray<nsCString> mStrings;
+  PRUint32            mIndex;
+};
+
+NS_IMPL_ISUPPORTS1(GIOUTF8StringEnumerator, nsIUTF8StringEnumerator)
+
+NS_IMETHODIMP
+GIOUTF8StringEnumerator::HasMore(PRBool* aResult)
+{
+  *aResult = mIndex < mStrings.Length();
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+GIOUTF8StringEnumerator::GetNext(nsACString& aResult)
+{
+  if (mIndex >= mStrings.Length())
+    return NS_ERROR_UNEXPECTED;
+
+  aResult.Assign(mStrings[mIndex]);
+  ++mIndex;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsGIOMimeApp::GetSupportedURISchemes(nsIUTF8StringEnumerator** aSchemes)
+{
+  *aSchemes = nsnull;
+
+  nsRefPtr<GIOUTF8StringEnumerator> array = new GIOUTF8StringEnumerator();
+  NS_ENSURE_TRUE(array, NS_ERROR_OUT_OF_MEMORY);
+
+  GVfs *gvfs = g_vfs_get_default();
+
+  if (!gvfs) {
+    g_warning("Cannot get GVfs object.");
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
+
+  const gchar* const * uri_schemes = g_vfs_get_supported_uri_schemes(gvfs);
+
+  while (*uri_schemes != NULL) {
+    if (!array->mStrings.AppendElement(*uri_schemes)) {
+      return NS_ERROR_OUT_OF_MEMORY;
+    }
+    uri_schemes++;
+  }
+
+  NS_ADDREF(*aSchemes = array);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsGIOMimeApp::SetAsDefaultForMimeType(nsACString const& aMimeType)
+{
+  char *content_type =
+    get_content_type_from_mime_type(PromiseFlatCString(aMimeType).get());
+  if (!content_type)
+    return NS_ERROR_FAILURE;
+  GError *error = NULL;
+  g_app_info_set_as_default_for_type(mApp,
+                                     content_type,
+                                     &error);
+  if (error) {
+    g_warning("Cannot set application as default for MIME type (%s): %s",
+              PromiseFlatCString(aMimeType).get(),
+              error->message);
+    g_error_free(error);
+    g_free(content_type);
+    return NS_ERROR_FAILURE;
+  }
+
+  g_free(content_type);
+  return NS_OK;
+}
+/**
+ * Set default application for files with given extensions
+ * @param fileExts string of space separated extensions
+ * @return NS_OK when application was set as default for given extensions,
+ * NS_ERROR_FAILURE otherwise
+ */
+NS_IMETHODIMP
+nsGIOMimeApp::SetAsDefaultForFileExtensions(nsACString const& fileExts)
+{
+  GError *error = NULL;
+  char *extensions = strdup(PromiseFlatCString(fileExts).get());
+  char *ext_pos = extensions;
+  char *space_pos;
+
+  while ( (space_pos = strchr(ext_pos, ' ')) || (*ext_pos != '\0') ) {
+    if (space_pos) {
+      *space_pos = '\0';
+    }
+    g_app_info_set_as_default_for_extension(mApp, ext_pos, &error);
+    if (error) {
+      g_warning("Cannot set application as default for extension (%s): %s",
+                ext_pos,
+                error->message);
+      g_error_free(error);
+      g_free(extensions);
+      return NS_ERROR_FAILURE;
+    }
+    if (space_pos) {
+      ext_pos = space_pos + 1;
+    } else {
+      *ext_pos = '\0';
+    }
+  }
+  g_free(extensions);
+  return NS_OK;
+}
+
+nsresult
+nsGIOService::Init()
+{
+  // do nothing, gvfs/gio does not init.
+  return NS_OK;
+}
+
+NS_IMPL_ISUPPORTS1(nsGIOService, nsIGIOService)
+
+NS_IMETHODIMP
+nsGIOService::GetMimeTypeFromExtension(const nsACString& aExtension,
+                                             nsACString& aMimeType)
+{
+  nsCAutoString fileExtToUse("file.");
+  fileExtToUse.Append(aExtension);
+
+  gboolean result_uncertain;
+  char *content_type = g_content_type_guess(fileExtToUse.get(),
+                                            NULL,
+                                            0,
+                                            &result_uncertain);
+  if (!content_type)
+    return NS_ERROR_FAILURE;
+
+  char *mime_type = g_content_type_get_mime_type(content_type);
+  if (!mime_type) {
+    g_free(content_type);
+    return NS_ERROR_FAILURE;
+  }
+
+  aMimeType.Assign(mime_type);
+
+  g_free(mime_type);
+  g_free(content_type);
+
+  return NS_OK;
+}
+// used in nsGNOMERegistry
+// -----------------------------------------------------------------------------
+NS_IMETHODIMP
+nsGIOService::GetAppForMimeType(const nsACString& aMimeType,
+                                nsIGIOMimeApp**   aApp)
+{
+  *aApp = nsnull;
+  char *content_type =
+    get_content_type_from_mime_type(PromiseFlatCString(aMimeType).get());
+  if (!content_type)
+    return NS_ERROR_FAILURE;
+
+  GAppInfo *app_info = g_app_info_get_default_for_type(content_type, false);
+  if (app_info) {
+    nsGIOMimeApp *mozApp = new nsGIOMimeApp(app_info);
+    NS_ENSURE_TRUE(mozApp, NS_ERROR_OUT_OF_MEMORY);
+    NS_ADDREF(*aApp = mozApp);
+  } else {
+    g_free(content_type);
+    return NS_ERROR_FAILURE;
+  }
+  g_free(content_type);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsGIOService::GetDescriptionForMimeType(const nsACString& aMimeType,
+                                              nsACString& aDescription)
+{
+  char *content_type =
+    get_content_type_from_mime_type(PromiseFlatCString(aMimeType).get());
+  if (!content_type)
+    return NS_ERROR_FAILURE;
+
+  char *desc = g_content_type_get_description(content_type);
+  if (!desc) {
+    g_free(content_type);
+    return NS_ERROR_FAILURE;
+  }
+
+  aDescription.Assign(desc);
+  g_free(content_type);
+  g_free(desc);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsGIOService::ShowURI(nsIURI* aURI)
+{
+  nsCAutoString spec;
+  aURI->GetSpec(spec);
+  GError *error = NULL;
+  if (!g_app_info_launch_default_for_uri(spec.get(), NULL, &error)) {
+    g_warning("Could not launch default application for URI: %s" ,error->message);
+    g_error_free(error);
+    return NS_ERROR_FAILURE;
+  }
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsGIOService::ShowURIForInput(const nsACString& aUri)
+{
+  GFile *file = g_file_new_for_commandline_arg(PromiseFlatCString(aUri).get());
+  char* spec = g_file_get_uri(file);
+  nsresult rv = NS_ERROR_FAILURE;
+  GError *error = NULL;
+
+  g_app_info_launch_default_for_uri(spec, NULL, &error);
+  if (error) {
+    g_warning("Cannot launch default application: %s", error->message);
+    g_error_free(error);
+  } else {
+    rv = NS_OK;
+  }
+  g_object_unref(file);
+  g_free(spec);
+
+  return rv;
+}
+
+/**
+ * Create or find already existing application info for specified command
+ * and application name.
+ * @param cmd command to execute
+ * @param appName application name
+ * @param appInfo location where created GAppInfo is stored
+ * @return NS_OK when object is created, NS_ERROR_FAILURE otherwise.
+ */
+NS_IMETHODIMP
+nsGIOService::CreateAppFromCommand(nsACString const& cmd,
+                                   nsACString const& appName,
+                                   nsIGIOMimeApp**   appInfo)
+{
+  GError *error = NULL;
+  *appInfo = nsnull;
+
+  GAppInfo *app_info = NULL, *app_info_from_list = NULL;
+  GList *apps = g_app_info_get_all();
+  GList *apps_p = apps;
+  get_commandline_t g_app_info_get_commandline_ptr;
+
+  void *libHandle = dlopen("libgio-2.0.so", RTLD_LAZY);
+  if (!libHandle) {
+    return NS_ERROR_FAILURE;
+  }
+  dlerror(); /* clear any existing error */
+  g_app_info_get_commandline_ptr =
+    (get_commandline_t) dlsym(libHandle, "g_app_info_get_commandline");
+  if (dlerror() != NULL) {
+    g_app_info_get_commandline_ptr = NULL;
+  }
+
+  // Try to find relevant and existing GAppInfo in all installed application
+  while (apps_p) {
+    app_info_from_list = (GAppInfo*) apps_p->data;
+    /* This is  a silly test. It just compares app names but not
+     * commands. This is due to old version of Glib/Gio. The required
+     * function which allows to do a regular check of existence of desktop file
+     * is possible by using function g_app_info_get_commandline. This function
+     * has been introduced in Glib 2.20. */
+    if (app_info_from_list && strcmp(g_app_info_get_name(app_info_from_list),
+                                     PromiseFlatCString(appName).get()) == 0 )
+    {
+      if (g_app_info_get_commandline_ptr)
+      {
+        /* Following test is only possible with Glib >= 2.20.
+         * Compare path only by using strncmp */
+        if (strncmp(g_app_info_get_commandline_ptr(app_info_from_list),
+                    PromiseFlatCString(cmd).get(),
+                    strlen(PromiseFlatCString(cmd).get())) == 0)
+        {
+          app_info = app_info_from_list;
+          break;
+        } else {
+          g_object_unref(app_info_from_list);
+        }
+      } else {
+        app_info = app_info_from_list;
+        break;
+      }
+    } else {
+      g_object_unref(app_info_from_list);
+    }
+    apps_p = apps_p->next;
+  }
+  g_list_free(apps);
+
+  if (!app_info) {
+    app_info = g_app_info_create_from_commandline(PromiseFlatCString(cmd).get(),
+                                                  PromiseFlatCString(appName).get(),
+                                                  G_APP_INFO_CREATE_SUPPORTS_URIS,
+                                                  &error);
+  }
+
+  if (!app_info) {
+    g_warning("Cannot create application info from command: %s", error->message);
+    g_error_free(error);
+    dlclose(libHandle);
+    return NS_ERROR_FAILURE;
+  }
+  nsGIOMimeApp *mozApp = new nsGIOMimeApp(app_info);
+  NS_ENSURE_TRUE(mozApp, NS_ERROR_OUT_OF_MEMORY);
+  NS_ADDREF(*appInfo = mozApp);
+  dlclose(libHandle);
+  return NS_OK;
+}
new file mode 100644
--- /dev/null
+++ b/toolkit/system/gnome/nsGIOService.h
@@ -0,0 +1,57 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Mozilla GNOME integration code.
+ *
+ * The Initial Developer of the Original Code is
+ * Red Hat, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Jan Horak <jhorak@redhat.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsGIOService_h_
+#define nsGIOService_h_
+
+#include "nsIGIOService.h"
+
+#define NS_GIOSERVICE_CID \
+{0xe3a1f3c9, 0x3ae1, 0x4b40, {0xa5, 0xe0, 0x7b, 0x45, 0x7f, 0xc9, 0xa9, 0xad}}
+
+class nsGIOService : public nsIGIOService
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIGIOSERVICE
+
+  NS_HIDDEN_(nsresult) Init();
+};
+
+#endif
+
--- a/toolkit/system/gnome/nsGnomeModule.cpp
+++ b/toolkit/system/gnome/nsGnomeModule.cpp
@@ -33,39 +33,52 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsGConfService.h"
 #include "nsGnomeVFSService.h"
+#include "nsGIOService.h"
 #include "nsToolkitCompsCID.h"
 #include "nsIGenericFactory.h"
 
 #ifdef MOZ_ENABLE_LIBNOTIFY
 #include "nsAlertsService.h"
 #endif
 
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsGConfService, Init)
+#ifdef MOZ_ENABLE_GNOMEVFS
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsGnomeVFSService, Init)
-
+#endif
+#ifdef MOZ_ENABLE_GIO
+NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsGIOService, Init)
+#endif
 #ifdef MOZ_ENABLE_LIBNOTIFY
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsAlertsService, Init)
 #endif
 
 static const nsModuleComponentInfo components[] = {
   { "GConf Service",
     NS_GCONFSERVICE_CID,
     NS_GCONFSERVICE_CONTRACTID,
     nsGConfServiceConstructor },
+#ifdef MOZ_ENABLE_GNOMEVFS
   { "GnomeVFS Service",
     NS_GNOMEVFSSERVICE_CID,
     NS_GNOMEVFSSERVICE_CONTRACTID,
     nsGnomeVFSServiceConstructor },
+#endif
+#ifdef MOZ_ENABLE_GIO
+  { "GIO Service",
+    NS_GIOSERVICE_CID,
+    NS_GIOSERVICE_CONTRACTID,
+    nsGIOServiceConstructor },
+#endif
 #ifdef MOZ_ENABLE_LIBNOTIFY
   { "Gnome Alerts Service",
     NS_SYSTEMALERTSSERVICE_CID,
     NS_SYSTEMALERTSERVICE_CONTRACTID,
     nsAlertsServiceConstructor },
 #endif
 };
 
--- a/uriloader/exthandler/Makefile.in
+++ b/uriloader/exthandler/Makefile.in
@@ -141,16 +141,20 @@ LOCAL_INCLUDES   += $(TK_CFLAGS) $(MOZ_D
 EXTRA_DSO_LDOPTS += $(MOZ_DBUS_GLIB_LIBS)
 endif
 
 ifdef MOZ_PLATFORM_HILDON
 ifdef MOZ_ENABLE_GNOMEVFS
 LOCAL_INCLUDES   += $(MOZ_GNOMEVFS_CFLAGS)
 EXTRA_DSO_LDOPTS += $(MOZ_GNOMEVFS_LIBS)
 endif
+ifdef MOZ_ENABLE_GIO
+LOCAL_INCLUDES   += $(MOZ_GIO_CFLAGS)
+EXTRA_DSO_LDOPTS += $(MOZ_GIO_LIBS)
+endif
 endif
 
 ifeq ($(OS_ARCH),WINNT WINCE)
 OS_LIBS		+= shell32.lib
 GARBAGE		+= nsOSHelperAppService.cpp $(srcdir)/nsOSHelperAppService.cpp \
              nsMIMEInfoWin.cpp $(srcdir)/nsMIMEInfoWin.cpp
 endif
 
--- a/uriloader/exthandler/unix/nsGNOMERegistry.cpp
+++ b/uriloader/exthandler/unix/nsGNOMERegistry.cpp
@@ -41,16 +41,17 @@
 #include "prmem.h"
 #include "nsString.h"
 #include "nsIComponentManager.h"
 #include "nsILocalFile.h"
 #include "nsMIMEInfoUnix.h"
 #include "nsAutoPtr.h"
 #include "nsIGConfService.h"
 #include "nsIGnomeVFSService.h"
+#include "nsIGIOService.h"
 
 #ifdef MOZ_WIDGET_GTK2
 #include <glib.h>
 #include <glib-object.h>
 
 #ifdef MOZ_PLATFORM_HILDON
 #include <libintl.h>
 #endif
@@ -77,21 +78,25 @@ nsGNOMERegistry::HandlerExists(const cha
 // falls back to using gnomevfs modules.  See bug 389632.  We don't want
 // this fallback to happen as we are not sure of the safety of all gnomevfs
 // modules and MIME-default applications.  (gnomevfs should be handled in
 // nsGnomeVFSProtocolHandler.)
 
 /* static */ nsresult
 nsGNOMERegistry::LoadURL(nsIURI *aURL)
 {
-  nsCOMPtr<nsIGnomeVFSService> vfs = do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID);
-  if (!vfs)
-    return NS_ERROR_FAILURE;
-
-  return vfs->ShowURI(aURL);
+  nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID);
+  nsCOMPtr<nsIGnomeVFSService> gnomevfs = do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID);
+  if (giovfs) {
+    return giovfs->ShowURI(aURL);
+  } else if (gnomevfs) {
+    /* Fallback to GnomeVFS */
+    return gnomevfs->ShowURI(aURL);
+  }
+  return NS_ERROR_FAILURE;
 }
 
 /* static */ void
 nsGNOMERegistry::GetAppDescForScheme(const nsACString& aScheme,
                                      nsAString& aDesc)
 {
   nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID);
   if (!gconf)
@@ -117,51 +122,81 @@ nsGNOMERegistry::GetAppDescForScheme(con
   }
 }
 
 
 /* static */ already_AddRefed<nsMIMEInfoBase>
 nsGNOMERegistry::GetFromExtension(const nsACString& aFileExt)
 {
   NS_ASSERTION(aFileExt[0] != '.', "aFileExt shouldn't start with a dot");
-  nsCOMPtr<nsIGnomeVFSService> vfs = do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID);
-  if (!vfs)
+  nsCAutoString mimeType;
+  nsCOMPtr<nsIGnomeVFSService> gnomevfs = do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID);
+  nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID);
+
+  if (!gnomevfs && !giovfs)
     return nsnull;
 
-  // Get the MIME type from the extension, then call GetFromType to
-  // fill in the MIMEInfo.
-  nsCAutoString mimeType;
-  if (NS_FAILED(vfs->GetMimeTypeFromExtension(aFileExt, mimeType)) ||
-      mimeType.EqualsLiteral("application/octet-stream"))
-    return nsnull;
+  if (giovfs) {
+    // Get the MIME type from the extension, then call GetFromType to
+    // fill in the MIMEInfo.
+    if (NS_FAILED(giovfs->GetMimeTypeFromExtension(aFileExt, mimeType)) ||
+        mimeType.EqualsLiteral("application/octet-stream"))
+      return nsnull;
+  } else if (gnomevfs) {
+    /* Fallback to GnomeVFS */
+    if (NS_FAILED(gnomevfs->GetMimeTypeFromExtension(aFileExt, mimeType)) ||
+        mimeType.EqualsLiteral("application/octet-stream"))
+      return nsnull;
+    
+  }
+
 
   return GetFromType(mimeType);
 }
 
 /* static */ already_AddRefed<nsMIMEInfoBase>
 nsGNOMERegistry::GetFromType(const nsACString& aMIMEType)
 {
-  nsCOMPtr<nsIGnomeVFSService> vfs = do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID);
-  if (!vfs)
+  nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID);
+  nsCOMPtr<nsIGnomeVFSService> gnomevfs = do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID);
+  nsCOMPtr<nsIGIOMimeApp> gioHandlerApp;
+  nsCOMPtr<nsIGnomeVFSMimeApp> gnomeHandlerApp;
+  
+  if (!giovfs && !gnomevfs)
     return nsnull;
 
-  nsCOMPtr<nsIGnomeVFSMimeApp> handlerApp;
-  if (NS_FAILED(vfs->GetAppForMimeType(aMIMEType, getter_AddRefs(handlerApp))) ||
-      !handlerApp)
-    return nsnull;
+  if (giovfs) {
+    if (NS_FAILED(giovfs->GetAppForMimeType(aMIMEType, getter_AddRefs(gioHandlerApp))) ||
+        !gioHandlerApp)
+      return nsnull;
 
+  } else {
+    /* Fallback to GnomeVFS*/
+    if (NS_FAILED(gnomevfs->GetAppForMimeType(aMIMEType, getter_AddRefs(gnomeHandlerApp))) ||
+        !gnomeHandlerApp)
+      return nsnull;
+    
+  }
   nsRefPtr<nsMIMEInfoUnix> mimeInfo = new nsMIMEInfoUnix(aMIMEType);
   NS_ENSURE_TRUE(mimeInfo, nsnull);
 
   nsCAutoString description;
-  vfs->GetDescriptionForMimeType(aMIMEType, description);
+  if (giovfs)
+    giovfs->GetDescriptionForMimeType(aMIMEType, description);
+  else
+    gnomevfs->GetDescriptionForMimeType(aMIMEType, description);
+
   mimeInfo->SetDescription(NS_ConvertUTF8toUTF16(description));
 
   nsCAutoString name;
-  handlerApp->GetName(name);
+  if (giovfs)
+    gioHandlerApp->GetName(name);
+  else 
+    gnomeHandlerApp->GetName(name);
+
 #ifdef MOZ_PLATFORM_HILDON
   // On Maemo/Hildon, GetName ends up calling gnome_vfs_mime_application_get_name,
   // which happens to return a non-localized message-id for the application. To
   // get the localized name for the application, we have to call dgettext with 
   // the default maemo domain-name to try and translate the string into the operating 
   // system's native language.
   const char kDefaultTextDomain [] = "maemo-af-desktop";
   nsCAutoString realName (dgettext(kDefaultTextDomain, PromiseFlatCString(name).get()));
--- a/uriloader/exthandler/unix/nsMIMEInfoUnix.cpp
+++ b/uriloader/exthandler/unix/nsMIMEInfoUnix.cpp
@@ -41,16 +41,17 @@
 #include <glib.h>
 #include <hildon-uri.h>
 #include <hildon-mime.h>
 #include <libosso.h>
 #endif
 
 #include "nsMIMEInfoUnix.h"
 #include "nsGNOMERegistry.h"
+#include "nsIGIOService.h"
 #include "nsIGnomeVFSService.h"
 #ifdef MOZ_ENABLE_DBUS
 #include "nsDBusHandlerApp.h"
 #endif
 
 nsresult
 nsMIMEInfoUnix::LoadUriInternal(nsIURI * aURI)
 {
@@ -69,20 +70,26 @@ nsMIMEInfoUnix::LoadUriInternal(nsIURI *
 #endif
   return rv;
 }
 
 NS_IMETHODIMP
 nsMIMEInfoUnix::GetHasDefaultHandler(PRBool *_retval)
 {
   *_retval = PR_FALSE;
-  nsCOMPtr<nsIGnomeVFSService> vfs = do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID);
-  if (vfs) {
+  nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID);
+  nsCOMPtr<nsIGnomeVFSService> gnomevfs = do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID);
+  if (giovfs) {
+    nsCOMPtr<nsIGIOMimeApp> app;
+    if (NS_SUCCEEDED(giovfs->GetAppForMimeType(mType, getter_AddRefs(app))) && app)
+      *_retval = PR_TRUE;
+  } else if (gnomevfs) {
+     /* Fallback to GnomeVFS*/
     nsCOMPtr<nsIGnomeVFSMimeApp> app;
-    if (NS_SUCCEEDED(vfs->GetAppForMimeType(mType, getter_AddRefs(app))) && app)
+    if (NS_SUCCEEDED(gnomevfs->GetAppForMimeType(mType, getter_AddRefs(app))) && app)
       *_retval = PR_TRUE;
   }
 
   if (*_retval)
     return NS_OK;
 
 #ifdef MOZ_PLATFORM_HILDON
   HildonURIAction *action = hildon_uri_get_default_action(mType.get(), nsnull);
@@ -103,20 +110,26 @@ nsMIMEInfoUnix::LaunchDefaultWithFile(ns
   nsCAutoString nativePath;
   aFile->GetNativePath(nativePath);
 
 #ifdef MOZ_PLATFORM_HILDON
   if(NS_SUCCEEDED(LaunchDefaultWithDBus(PromiseFlatCString(nativePath).get())))
     return NS_OK;
 #endif
 
-  nsCOMPtr<nsIGnomeVFSService> vfs = do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID);
-  if (vfs) {
+  nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID);
+  nsCOMPtr<nsIGnomeVFSService> gnomevfs = do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID);
+  if (giovfs) {
+    nsCOMPtr<nsIGIOMimeApp> app;
+    if (NS_SUCCEEDED(giovfs->GetAppForMimeType(mType, getter_AddRefs(app))) && app)
+      return app->Launch(nativePath);
+  } else if (gnomevfs) {
+    /* Fallback to GnomeVFS */
     nsCOMPtr<nsIGnomeVFSMimeApp> app;
-    if (NS_SUCCEEDED(vfs->GetAppForMimeType(mType, getter_AddRefs(app))) && app)
+    if (NS_SUCCEEDED(gnomevfs->GetAppForMimeType(mType, getter_AddRefs(app))) && app)
       return app->Launch(nativePath);
   }
 
   if (!mDefaultApplication)
     return NS_ERROR_FILE_NOT_FOUND;
 
   return LaunchWithIProcess(mDefaultApplication, nativePath);
 }
--- a/xpcom/io/nsLocalFileUnix.cpp
+++ b/xpcom/io/nsLocalFileUnix.cpp
@@ -78,16 +78,17 @@
 #include "nsIComponentManager.h"
 #include "nsXPIDLString.h"
 #include "prproces.h"
 #include "nsIDirectoryEnumerator.h"
 #include "nsISimpleEnumerator.h"
 #include "nsITimelineService.h"
 
 #ifdef MOZ_WIDGET_GTK2
+#include "nsIGIOService.h"
 #include "nsIGnomeVFSService.h"
 #endif
 
 #ifdef MOZ_PLATFORM_HILDON
 #include <glib.h>
 #include <hildon-uri.h>
 #include <hildon-mime.h>
 #include <libosso.h>
@@ -1627,35 +1628,43 @@ nsLocalFile::Launch()
 
     return NS_OK;
 }
 #else
 NS_IMETHODIMP
 nsLocalFile::Reveal()
 {
 #ifdef MOZ_WIDGET_GTK2
-    nsCOMPtr<nsIGnomeVFSService> vfs = do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID);
-    if (!vfs)
+    nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID);
+    nsCOMPtr<nsIGnomeVFSService> gnomevfs = do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID);
+    if (!giovfs && !gnomevfs)
         return NS_ERROR_FAILURE;
 
     PRBool isDirectory;
     if (NS_FAILED(IsDirectory(&isDirectory)))
         return NS_ERROR_FAILURE;
 
     if (isDirectory) {
-        return vfs->ShowURIForInput(mPath);
+        if (giovfs)
+            return giovfs->ShowURIForInput(mPath);
+        else 
+            /* Fallback to GnomeVFS */
+            return gnomevfs->ShowURIForInput(mPath);
     } else {
         nsCOMPtr<nsIFile> parentDir;
         nsCAutoString dirPath;
         if (NS_FAILED(GetParent(getter_AddRefs(parentDir))))
             return NS_ERROR_FAILURE;
         if (NS_FAILED(parentDir->GetNativePath(dirPath)))
             return NS_ERROR_FAILURE;
 
-        return vfs->ShowURIForInput(dirPath);
+        if (giovfs)
+            return giovfs->ShowURIForInput(dirPath);
+        else 
+            return gnomevfs->ShowURIForInput(dirPath);        
     }
 #else
     return NS_ERROR_FAILURE;
 #endif
 }
 
 NS_IMETHODIMP
 nsLocalFile::Launch()
@@ -1674,21 +1683,26 @@ nsLocalFile::Launch()
 
     if (nsnull == connection)
       return NS_ERROR_FAILURE;
 
     if (hildon_mime_open_file(connection, mPath.get()) != kHILDON_SUCCESS)
       return NS_ERROR_FAILURE;
     return NS_OK;
 #else
-    nsCOMPtr<nsIGnomeVFSService> vfs = do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID);
-    if (!vfs)
-        return NS_ERROR_FAILURE;
-
-    return vfs->ShowURIForInput(mPath);
+    nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID);
+    nsCOMPtr<nsIGnomeVFSService> gnomevfs = do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID);
+    if (giovfs) {
+      return giovfs->ShowURIForInput(mPath);
+    } else if (gnomevfs) {
+      /* GnomeVFS fallback */
+      return gnomevfs->ShowURIForInput(mPath);
+    }
+    
+    return NS_ERROR_FAILURE;
 #endif
 #else
     return NS_ERROR_FAILURE;
 #endif
 }
 #endif
 
 nsresult
--- a/xpcom/system/Makefile.in
+++ b/xpcom/system/Makefile.in
@@ -46,15 +46,16 @@ MODULE          = xpcom
 XPIDL_MODULE    = xpcom_system
 
 XPIDLSRCS = \
         nsIXULAppInfo.idl \
         nsIXULRuntime.idl \
         nsIGConfService.idl \
         nsIGnomeVFSService.idl \
         nsIBlocklistService.idl \
+        nsIGIOService.idl \
         $(NULL)
 
 ifdef MOZ_CRASHREPORTER
 XPIDLSRCS += nsICrashReporter.idl
 endif
 
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/xpcom/system/nsIGIOService.idl
@@ -0,0 +1,109 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Mozilla GNOME integration code.
+ *
+ * The Initial Developer of the Original Code is
+ * IBM Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2004
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Brian Ryner <bryner@brianryner.com>
+ *  Jan Horak <jhorak@redhat.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsISupports.idl"
+
+interface nsIUTF8StringEnumerator;
+interface nsIURI;
+
+/* nsIGIOMimeApp holds information about an application that is looked up
+   with nsIGIOService::GetAppForMimeType. */
+// 66009894-9877-405b-9321-bf30420e34e6 prev uuid
+
+[scriptable, uuid(e77021b4-4012-407d-b686-7a1f18050109)] 
+interface nsIGIOMimeApp : nsISupports
+{
+  const long EXPECTS_URIS  = 0;
+  const long EXPECTS_PATHS = 1;
+  const long EXPECTS_URIS_FOR_NON_FILES = 2;
+
+  readonly attribute AUTF8String         id;
+  readonly attribute AUTF8String         name;
+  readonly attribute AUTF8String         command;
+  readonly attribute long                expectsURIs;  // see constants above
+  readonly attribute nsIUTF8StringEnumerator supportedURISchemes;
+
+  void launch(in AUTF8String uri);
+  void setAsDefaultForMimeType(in AUTF8String mimeType);
+  void setAsDefaultForFileExtensions(in AUTF8String extensions);
+};
+
+/*
+ * The VFS service makes use of two distinct registries.
+ *
+ * The application registry holds information about applications (uniquely
+ * identified by id), such as which MIME types and URI schemes they are
+ * capable of handling, whether they run in a terminal, etc.
+ *
+ * The MIME registry holds information about MIME types, such as which
+ * extensions map to a given MIME type.  The MIME registry also stores the
+ * id of the application selected to handle each MIME type.
+ */
+
+// prev id dea20bf0-4e4d-48c5-b932-dc3e116dc64b
+[scriptable, uuid(47e372c2-78bb-4899-8114-56aa7d9cdac5)]
+interface nsIGIOService : nsISupports
+{
+
+  /*** MIME registry methods ***/
+
+  /* Obtain the MIME type registered for an extension.  The extension
+     should not include a leading dot. */
+  AUTF8String        getMimeTypeFromExtension(in AUTF8String extension);
+
+  /* Obtain the preferred application for opening a given MIME type */
+  nsIGIOMimeApp      getAppForMimeType(in AUTF8String mimeType);
+
+  /* Obtain the preferred application for opening a given MIME type */
+  nsIGIOMimeApp      createAppFromCommand(in AUTF8String cmd, 
+                                          in AUTF8String appName);
+
+  /* Obtain a description for the given MIME type */
+  AUTF8String        getDescriptionForMimeType(in AUTF8String mimeType);
+
+  /*** Misc. methods ***/
+
+  /* Open the given URI in the default application */
+  void               showURI(in nsIURI uri);
+  [noscript] void    showURIForInput(in ACString uri);
+};
+
+%{C++
+#define NS_GIOSERVICE_CONTRACTID "@mozilla.org/gio-service;1"
+%}