Bug 373397 - "nsGNOMERegistry could use the mozgnome component" [p=mh+mozilla@glandium.org (Mike Hommey) r=chpe sr=biesi a1.9=beltzner]
authorreed@reedloden.com
Tue, 29 Jan 2008 20:36:11 -0800
changeset 11009 c7722e4e80eab4823ebf1167055b5599cb55fe3d
parent 11008 f11c30c9679d8897d419df20a5ce13244edeedbc
child 11010 8b2bbd3c92da2bd470e73b084436fc417a6bddfa
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerschpe, biesi
bugs373397
milestone1.9b3pre
Bug 373397 - "nsGNOMERegistry could use the mozgnome component" [p=mh+mozilla@glandium.org (Mike Hommey) r=chpe sr=biesi a1.9=beltzner]
uriloader/exthandler/unix/nsGNOMERegistry.cpp
uriloader/exthandler/unix/nsGNOMERegistry.h
uriloader/exthandler/unix/nsOSHelperAppService.cpp
--- a/uriloader/exthandler/unix/nsGNOMERegistry.cpp
+++ b/uriloader/exthandler/unix/nsGNOMERegistry.cpp
@@ -39,338 +39,150 @@
 #include "nsGNOMERegistry.h"
 #include "prlink.h"
 #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 <glib.h>
 #include <glib-object.h>
 
-static PRLibrary *gconfLib;
-static PRLibrary *gnomeLib;
-static PRLibrary *vfsLib;
-
-typedef struct _GConfClient GConfClient;
-typedef struct _GnomeProgram GnomeProgram;
-typedef struct _GnomeModuleInfo GnomeModuleInfo;
-
-typedef struct {
-  char *id;
-  char *name;
-  char *command;
-  /* there is more here, but we don't need it */
-} GnomeVFSMimeApplication;
-
-typedef GConfClient * (*_gconf_client_get_default_fn)();
-typedef gchar * (*_gconf_client_get_string_fn)(GConfClient *,
-					       const char *, GError **);
-typedef gboolean (*_gconf_client_get_bool_fn)(GConfClient *,
-                                              const char *, GError **);
-typedef gboolean (*_gnome_url_show_fn)(const char *, GError **);
-typedef const char * (*_gnome_vfs_mime_type_from_name_fn)(const char *);
-typedef GList * (*_gnome_vfs_mime_get_extensions_list_fn)(const char *);
-typedef void (*_gnome_vfs_mime_extensions_list_free_fn)(GList *);
-typedef const char * (*_gnome_vfs_mime_get_description_fn)(const char *);
-typedef GnomeVFSMimeApplication * (*_gnome_vfs_mime_get_default_application_fn)
-                                                                (const char *);
-typedef void (*_gnome_vfs_mime_application_free_fn)(GnomeVFSMimeApplication *);
-typedef GnomeProgram * (*_gnome_program_init_fn)(const char *, const char *,
-						 const GnomeModuleInfo *, int,
-						 char **, const char *, ...);
-typedef const GnomeModuleInfo * (*_libgnome_module_info_get_fn)();
-typedef GnomeProgram * (*_gnome_program_get_fn)();
-
-#define DECL_FUNC_PTR(func) static _##func##_fn _##func
-
-DECL_FUNC_PTR(gconf_client_get_default);
-DECL_FUNC_PTR(gconf_client_get_string);
-DECL_FUNC_PTR(gconf_client_get_bool);
-DECL_FUNC_PTR(gnome_url_show);
-DECL_FUNC_PTR(gnome_vfs_mime_type_from_name);
-DECL_FUNC_PTR(gnome_vfs_mime_get_extensions_list);
-DECL_FUNC_PTR(gnome_vfs_mime_extensions_list_free);
-DECL_FUNC_PTR(gnome_vfs_mime_get_description);
-DECL_FUNC_PTR(gnome_vfs_mime_get_default_application);
-DECL_FUNC_PTR(gnome_vfs_mime_application_free);
-DECL_FUNC_PTR(gnome_program_init);
-DECL_FUNC_PTR(libgnome_module_info_get);
-DECL_FUNC_PTR(gnome_program_get);
-
-static void
-CleanUp()
-{
-  // Unload all libraries
-  if (gnomeLib) {
-    PR_UnloadLibrary(gnomeLib);
-    gnomeLib = nsnull;
-  }
-  if (gconfLib) {
-    PR_UnloadLibrary(gconfLib);
-    gconfLib = nsnull;
-  }
-  if (vfsLib) {
-    PR_UnloadLibrary(vfsLib);
-    vfsLib = nsnull;
-  }
-}
-
-static PRLibrary *
-LoadVersionedLibrary(const char* libName, const char* libVersion)
-{
-  char *platformLibName = PR_GetLibraryName(nsnull, libName);
-  nsCAutoString versionLibName(platformLibName);
-  versionLibName.Append(libVersion);
-  PR_FreeLibraryName(platformLibName);
-  return PR_LoadLibrary(versionLibName.get());
-}
-
-/* static */ void
-nsGNOMERegistry::Startup()
-{
-  #define ENSURE_LIB(lib) \
-    PR_BEGIN_MACRO \
-    if (!lib) { \
-      CleanUp(); \
-      return; \
-    } \
-    PR_END_MACRO
-
-  #define GET_LIB_FUNCTION(lib, func) \
-    PR_BEGIN_MACRO \
-    _##func = (_##func##_fn) PR_FindFunctionSymbol(lib##Lib, #func); \
-    if (!_##func) { \
-      CleanUp(); \
-      return; \
-    } \
-    PR_END_MACRO
-
-  // Attempt to open libgconf
-  gconfLib = LoadVersionedLibrary("gconf-2", ".4");
-  ENSURE_LIB(gconfLib);
-
-  GET_LIB_FUNCTION(gconf, gconf_client_get_default);
-  GET_LIB_FUNCTION(gconf, gconf_client_get_string);
-  GET_LIB_FUNCTION(gconf, gconf_client_get_bool);
-
-  // Attempt to open libgnome
-  gnomeLib = LoadVersionedLibrary("gnome-2", ".0");
-  ENSURE_LIB(gnomeLib);
-
-  GET_LIB_FUNCTION(gnome, gnome_url_show);
-  GET_LIB_FUNCTION(gnome, gnome_program_init);
-  GET_LIB_FUNCTION(gnome, libgnome_module_info_get);
-  GET_LIB_FUNCTION(gnome, gnome_program_get);
-
-  // Attempt to open libgnomevfs
-  vfsLib = LoadVersionedLibrary("gnomevfs-2", ".0");
-  ENSURE_LIB(vfsLib);
-
-  GET_LIB_FUNCTION(vfs, gnome_vfs_mime_type_from_name);
-  GET_LIB_FUNCTION(vfs, gnome_vfs_mime_get_extensions_list);
-  GET_LIB_FUNCTION(vfs, gnome_vfs_mime_extensions_list_free);
-  GET_LIB_FUNCTION(vfs, gnome_vfs_mime_get_description);
-  GET_LIB_FUNCTION(vfs, gnome_vfs_mime_get_default_application);
-  GET_LIB_FUNCTION(vfs, gnome_vfs_mime_application_free);
-
-  // Initialize GNOME, if it's not already initialized.  It's not
-  // necessary to tell GNOME about our actual command line arguments.
-
-  if (!_gnome_program_get()) {
-    char *argv[1] = { "gecko" };
-    _gnome_program_init("Gecko", "1.0", _libgnome_module_info_get(),
-                        1, argv, NULL);
-  }
-
-  // Note: after GNOME has been initialized, do not ever unload these
-  // libraries.  They register atexit handlers, so if they are unloaded, we'll
-  // crash on exit.
-}
-
-/**
- * Finds the application for a given protocol.
- *
- * @param aProtocolScheme
- *        Protocol to look up. For example, "ghelp" or "mailto".
- *
- * @return UTF-8 string identifying the application. Must be freed with
- *         g_free.
- *         NULL on error.
- */
-static gchar* getAppForScheme(const nsACString& aProtocolScheme)
-{
-  if (!gconfLib)
-    return nsnull;
-
-  GError *error = nsnull;
-  GConfClient *client = _gconf_client_get_default();
-  NS_ASSERTION(client, "no gconf client");
-
-  nsCAutoString gconfPath(NS_LITERAL_CSTRING("/desktop/gnome/url-handlers/") +
-                          aProtocolScheme +
-                          NS_LITERAL_CSTRING("/command"));
-
-  gchar *app = _gconf_client_get_string(client, gconfPath.get(), &error);
-  g_object_unref(G_OBJECT(client));
-
-  if (error)
-    g_error_free(error);
-
-  return app;
-}
-
 /* static */ PRBool
 nsGNOMERegistry::HandlerExists(const char *aProtocolScheme)
 {
-  gchar *app = getAppForScheme(nsDependentCString(aProtocolScheme));
-
-  if (app) {
-    g_free(app);
-    GConfClient *client = _gconf_client_get_default();
+  nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID);
+  if (!gconf)
+    return PR_FALSE;
 
-    nsCAutoString enabledPath(NS_LITERAL_CSTRING("/desktop/gnome/url-handlers/") +
-                              nsDependentCString(aProtocolScheme) +
-                              NS_LITERAL_CSTRING("/enabled"));
-    gboolean isEnabled = _gconf_client_get_bool(client, enabledPath.get(), NULL);
+  PRBool isEnabled;
+  nsCAutoString handler;
+  if (NS_FAILED(gconf->GetAppForProtocol(nsDependentCString(aProtocolScheme), &isEnabled, handler)))
+    return PR_FALSE;
 
-    g_object_unref(G_OBJECT(client));
-
-    return isEnabled ? PR_TRUE : PR_FALSE;
-  }
-
-  return PR_FALSE;
+  return isEnabled;
 }
 
 // XXX Check HandlerExists() before calling LoadURL.
 //
 // If there is not a registered handler for the protocol, gnome_url_show()
 // 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)
 {
-  if (!gconfLib)
+  nsCOMPtr<nsIGnomeVFSService> vfs = do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID);
+  if (!vfs)
     return NS_ERROR_FAILURE;
 
-  nsCAutoString spec;
-  aURL->GetAsciiSpec(spec);
-
-  // XXX what if gnome_url_show() uses the default handler and that's us?
-
-  if (_gnome_url_show(spec.get(), NULL))
-    return NS_OK;
-
-  return NS_ERROR_FAILURE;
+  return vfs->ShowURI(aURL);
 }
 
 /* static */ void
 nsGNOMERegistry::GetAppDescForScheme(const nsACString& aScheme,
                                      nsAString& aDesc)
 {
-  char *app = getAppForScheme(aScheme);
+  nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID);
+  if (!gconf)
+    return;
 
-  if (app) {
+  PRBool isEnabled;
+  nsCAutoString app;
+  if (NS_FAILED(gconf->GetAppForProtocol(aScheme, &isEnabled, app)))
+    return;
+
+  if (!app.IsEmpty()) {
     // Try to only provide the executable name, as it is much simpler than with the path and arguments
-    char *firstSpace = strchr(app, ' ');
-    if (firstSpace) {
-      *firstSpace = '\0';
-      char *lastSlash = strrchr(app, '/');
-      if (lastSlash) {
-        CopyUTF8toUTF16(lastSlash + 1, aDesc);
-        g_free(app);
-        return;
+    PRInt32 firstSpace = app.FindChar(' ');
+    if (firstSpace != kNotFound) {
+      app.Truncate(firstSpace);
+      PRInt32 lastSlash = app.RFindChar('/');
+      if (lastSlash != kNotFound) {
+        app.Cut(0, lastSlash + 1);
       }
     }
 
     CopyUTF8toUTF16(app, aDesc);
-    g_free(app);
   }
 }
 
 
 /* static */ already_AddRefed<nsMIMEInfoBase>
-nsGNOMERegistry::GetFromExtension(const char *aFileExt)
+nsGNOMERegistry::GetFromExtension(const nsACString& aFileExt)
 {
-  if (!gconfLib)
+  NS_ASSERTION(aFileExt[0] != '.', "aFileExt shouldn't start with a dot");
+  nsCOMPtr<nsIGnomeVFSService> vfs = do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID);
+  if (!vfs)
     return nsnull;
 
   // Get the MIME type from the extension, then call GetFromType to
   // fill in the MIMEInfo.
-
-  nsCAutoString fileExtToUse;
-  if (aFileExt && aFileExt[0] != '.')
-    fileExtToUse = '.';
-
-  fileExtToUse.Append(aFileExt);
-
-  const char *mimeType = _gnome_vfs_mime_type_from_name(fileExtToUse.get());
-  if (!strcmp(mimeType, "application/octet-stream"))
+  nsCAutoString mimeType;
+  if (NS_FAILED(vfs->GetMimeTypeFromExtension(aFileExt, mimeType)) ||
+      mimeType.EqualsLiteral("application/octet-stream"))
     return nsnull;
 
   return GetFromType(mimeType);
 }
 
 /* static */ already_AddRefed<nsMIMEInfoBase>
-nsGNOMERegistry::GetFromType(const char *aMIMEType)
+nsGNOMERegistry::GetFromType(const nsACString& aMIMEType)
 {
-  if (!gconfLib)
+  nsCOMPtr<nsIGnomeVFSService> vfs = do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID);
+  if (!vfs)
     return nsnull;
 
-  GnomeVFSMimeApplication *handlerApp = _gnome_vfs_mime_get_default_application(aMIMEType);
-  if (!handlerApp)
+  nsCOMPtr<nsIGnomeVFSMimeApp> handlerApp;
+  if (NS_FAILED(vfs->GetAppForMimeType(aMIMEType, getter_AddRefs(handlerApp))) ||
+      !handlerApp)
     return nsnull;
 
   nsRefPtr<nsMIMEInfoUnix> mimeInfo = new nsMIMEInfoUnix(aMIMEType);
   NS_ENSURE_TRUE(mimeInfo, nsnull);
 
-  // Get the list of extensions and append then to the mimeInfo.
-  GList *extensions = _gnome_vfs_mime_get_extensions_list(aMIMEType);
-  for (GList *extension = extensions; extension; extension = extension->next)
-    mimeInfo->AppendExtension(nsDependentCString((const char *) extension->data));
-
-  _gnome_vfs_mime_extensions_list_free(extensions);
-
-  const char *description = _gnome_vfs_mime_get_description(aMIMEType);
+  nsCAutoString description;
+  vfs->GetDescriptionForMimeType(aMIMEType, description);
   mimeInfo->SetDescription(NS_ConvertUTF8toUTF16(description));
 
   // Convert UTF-8 registry value to filesystem encoding, which
   // g_find_program_in_path() uses.
 
-  gchar *nativeCommand = g_filename_from_utf8(handlerApp->command,
+  nsCAutoString command;
+  handlerApp->GetCommand(command);
+  gchar *nativeCommand = g_filename_from_utf8(command.get(),
                                               -1, NULL, NULL, NULL);
   if (!nativeCommand) {
     NS_ERROR("Could not convert helper app command to filesystem encoding");
-    _gnome_vfs_mime_application_free(handlerApp);
     return nsnull;
   }
 
   gchar *commandPath = g_find_program_in_path(nativeCommand);
 
   g_free(nativeCommand);
 
   if (!commandPath) {
-    _gnome_vfs_mime_application_free(handlerApp);
     return nsnull;
   }
 
   nsCOMPtr<nsILocalFile> appFile;
   NS_NewNativeLocalFile(nsDependentCString(commandPath), PR_TRUE,
                         getter_AddRefs(appFile));
   if (appFile) {
     mimeInfo->SetDefaultApplication(appFile);
-    mimeInfo->SetDefaultDescription(NS_ConvertUTF8toUTF16(handlerApp->name));
+    nsCAutoString name;
+    handlerApp->GetName(name);
+    mimeInfo->SetDefaultDescription(NS_ConvertUTF8toUTF16(name));
     mimeInfo->SetPreferredAction(nsIMIMEInfo::useSystemDefault);
   }
 
   g_free(commandPath);
 
-  _gnome_vfs_mime_application_free(handlerApp);
-
   nsMIMEInfoBase* retval;
   NS_ADDREF((retval = mimeInfo));
   return retval;
 }
--- a/uriloader/exthandler/unix/nsGNOMERegistry.h
+++ b/uriloader/exthandler/unix/nsGNOMERegistry.h
@@ -38,21 +38,19 @@
 #include "nsIURI.h"
 #include "nsCOMPtr.h"
 
 class nsMIMEInfoBase;
 
 class nsGNOMERegistry
 {
  public:
-  static void Startup();
-
   static PRBool HandlerExists(const char *aProtocolScheme);
 
   static nsresult LoadURL(nsIURI *aURL);
 
   static void GetAppDescForScheme(const nsACString& aScheme,
                                   nsAString& aDesc);
 
-  static already_AddRefed<nsMIMEInfoBase> GetFromExtension(const char *aFileExt);
+  static already_AddRefed<nsMIMEInfoBase> GetFromExtension(const nsACString& aFileExt);
 
-  static already_AddRefed<nsMIMEInfoBase> GetFromType(const char *aMIMEType);
+  static already_AddRefed<nsMIMEInfoBase> GetFromType(const nsACString& aMIMEType);
 };
--- a/uriloader/exthandler/unix/nsOSHelperAppService.cpp
+++ b/uriloader/exthandler/unix/nsOSHelperAppService.cpp
@@ -83,20 +83,16 @@ ParseMIMEType(const nsAString::const_ite
               nsAString::const_iterator& aMinorTypeEnd,
               const nsAString::const_iterator& aEnd_iter);
 
 inline PRBool
 IsNetscapeFormat(const nsACString& aBuffer);
 
 nsOSHelperAppService::nsOSHelperAppService() : nsExternalHelperAppService()
 {
-#ifdef MOZ_WIDGET_GTK2
-  nsGNOMERegistry::Startup();
-#endif
-
   mode_t mask = umask(0777);
   umask(mask);
   mPermissions = 0666 & ~mask;
 }
 
 nsOSHelperAppService::~nsOSHelperAppService()
 {}
 
@@ -1359,17 +1355,17 @@ nsOSHelperAppService::GetFromExtension(c
                                          minorType,
                                          mime_types_description,
                                          PR_TRUE);
 
   if (NS_FAILED(rv) || majorType.IsEmpty()) {
     
 #ifdef MOZ_WIDGET_GTK2
     LOG(("Looking in GNOME registry\n"));
-    nsMIMEInfoBase *gnomeInfo = nsGNOMERegistry::GetFromExtension(aFileExt.get()).get();
+    nsMIMEInfoBase *gnomeInfo = nsGNOMERegistry::GetFromExtension(aFileExt).get();
     if (gnomeInfo) {
       LOG(("Got MIMEInfo from GNOME registry\n"));
       return gnomeInfo;
     }
 #endif
 
     rv = LookUpTypeAndDescription(NS_ConvertUTF8toUTF16(aFileExt),
                                   majorType,
@@ -1485,17 +1481,17 @@ nsOSHelperAppService::GetFromType(const 
 #ifdef MOZ_WIDGET_GTK2
   nsMIMEInfoBase *gnomeInfo = nsnull;
   if (handler.IsEmpty()) {
     // No useful data yet.  Check the GNOME registry.  Unfortunately, newer
     // GNOME versions no longer have type-to-extension mappings, so we might
     // get back a MIMEInfo without any extensions set.  In that case we'll have
     // to look in our mime.types files for the extensions.    
     LOG(("Looking in GNOME registry\n"));
-    gnomeInfo = nsGNOMERegistry::GetFromType(aMIMEType.get()).get();
+    gnomeInfo = nsGNOMERegistry::GetFromType(aMIMEType).get();
     if (gnomeInfo && gnomeInfo->HasExtensions()) {
       LOG(("Got MIMEInfo from GNOME registry, and it has extensions set\n"));
       return gnomeInfo;
     }
   }
 #endif
 
   // Now look up our extensions