Bug 624341 - Update check for default mailer to work the new way (glib >= 2.27.1); Note this currently needs --enable-gio for the new check to work. r=Standard8
authorChris Coulson <chrisccoulson@ubuntu.com>
Thu, 19 May 2011 08:46:13 +0100
changeset 7790 dfd0157bf4cf43a1227a6696e96a0fd5b9e5e397
parent 7789 4d710242ad6ec02f7d9c9a75281a86aa430c3505
child 7791 f40b3d53a3858e7b4c1fd1f91b0cf93c6190e745
push id1
push userbugzilla@standard8.plus.com
push dateFri, 20 May 2011 16:03:29 +0000
treeherdercomm-beta@9f2029d7b5ff [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersStandard8
bugs624341
Bug 624341 - Update check for default mailer to work the new way (glib >= 2.27.1); Note this currently needs --enable-gio for the new check to work. r=Standard8
mail/components/shell/nsMailGNOMEIntegration.cpp
mail/components/shell/nsMailGNOMEIntegration.h
--- a/mail/components/shell/nsMailGNOMEIntegration.cpp
+++ b/mail/components/shell/nsMailGNOMEIntegration.cpp
@@ -33,28 +33,30 @@
  * 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 "nsMailGNOMEIntegration.h"
 #include "nsIGConfService.h"
+#include "nsIGIOService.h"
 #include "nsCOMPtr.h"
 #include "nsIServiceManager.h"
 #include "prenv.h"
 #include "nsIFile.h"
 #include "nsIStringBundle.h"
 #include "nsIPromptService.h"
 #include "nsIPrefService.h"
 #include "nsIPrefBranch.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsDirectoryServiceUtils.h"
 #include "nsEmbedCID.h"
 #include "nsMemory.h"
+#include "nsIStringBundle.h"
 
 #include <glib.h>
 #include <limits.h>
 #include <stdlib.h>
 
 static const char* const sMailProtocols[] = {
   "mailto"
 };
@@ -77,18 +79,19 @@ nsMailGNOMEIntegration::nsMailGNOMEInteg
 nsresult
 nsMailGNOMEIntegration::Init()
 {
   nsresult rv;
 
   // GConf _must_ be available, or we do not allow CreateInstance to succeed.
 
   nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID);
+  nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID);
 
-  if (!gconf)
+  if (!gconf && !giovfs)
     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;
 
   if (GetAppPathFromLauncher())
       return NS_OK;
@@ -117,18 +120,18 @@ nsMailGNOMEIntegration::GetAppPathFromLa
     return PR_FALSE;
 
   if (g_path_is_absolute(launcher)) {
     mAppPath = launcher;
     tmp = g_path_get_basename(launcher);
     gchar *fullpath = g_find_program_in_path(tmp);
     if (fullpath && mAppPath.Equals(fullpath)) {
       mAppIsInPath = PR_TRUE;
-      g_free(fullpath);
     }
+    g_free(fullpath);
   } else {
     tmp = g_find_program_in_path(launcher);
     if (!tmp)
       return PR_FALSE;
     mAppPath = tmp;
     mAppIsInPath = PR_TRUE;
   }
 
@@ -210,66 +213,117 @@ nsMailGNOMEIntegration::KeyMatchesAppNam
     return PR_FALSE;
 
   PRBool matches = mAppPath.Equals(commandPath);
   g_free(commandPath);
   return matches;
 }
 
 PRBool
+nsMailGNOMEIntegration::CheckHandlerMatchesAppName(const nsACString &handler) const
+{
+  gint argc;
+  gchar **argv;
+  nsCAutoString command(handler);
+
+  if (g_shell_parse_argv(command.get(), &argc, &argv, NULL)) {
+    command.Assign(argv[0]);
+    g_strfreev(argv);
+  } else {
+    return PR_FALSE;
+  }
+
+  return KeyMatchesAppName(command.get());
+}
+
+PRBool
 nsMailGNOMEIntegration::checkDefault(const char* const *aProtocols, unsigned int aLength)
 {
   nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID);
+  nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID);
 
   PRBool enabled;
   nsCAutoString handler;
+  nsresult rv;
 
   for (unsigned int i = 0; i < aLength; ++i) {
-    handler.Truncate();
-    nsresult rv = gconf->GetAppForProtocol(nsDependentCString(aProtocols[i]),
-                                           &enabled, handler);
-    if (NS_SUCCEEDED(rv))
-    {
-      // The string will be something of the form: [/path/to/]app "%s"
-      // We want to remove all of the parameters and get just the binary name.
+    if (gconf) {
+      handler.Truncate();
+      rv = gconf->GetAppForProtocol(nsDependentCString(aProtocols[i]),
+                                    &enabled, handler);
+      if (NS_SUCCEEDED(rv) && (!CheckHandlerMatchesAppName(handler) || !enabled)) {
+        return PR_FALSE;
+      }
+    }
 
-      gint argc;
-      gchar **argv;
-
-      if (g_shell_parse_argv(handler.get(), &argc, &argv, NULL) && argc > 0) {
-        handler.Assign(argv[0]);
-        g_strfreev(argv);
-      } else 
+    if (giovfs) {
+      handler.Truncate();
+      nsCOMPtr<nsIGIOMimeApp> app;
+      rv = giovfs->GetAppForURIScheme(nsDependentCString(aProtocols[i]),
+                                      getter_AddRefs(app));
+      if (NS_FAILED(rv) || !app) {
         return PR_FALSE;
-
-      if (!KeyMatchesAppName(handler.get()) || !enabled)
-        return PR_FALSE; // the handler is disabled or set to another app
+      }
+      rv = app->GetCommand(handler);
+      if (NS_SUCCEEDED(rv) && !CheckHandlerMatchesAppName(handler)) {
+        return PR_FALSE;
+      }
     }
   }
 
   return PR_TRUE;
 }
 
 nsresult
 nsMailGNOMEIntegration::MakeDefault(const char* const *aProtocols,
                                     unsigned int aLength)
 {
   nsCAutoString appKeyValue;
   nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID);
+  nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID);
   if(mAppIsInPath) {
     // mAppPath is in the users path, so use only the basename as the launcher
     gchar *tmp = g_path_get_basename(mAppPath.get());
     appKeyValue = tmp;
     g_free(tmp);
   } else {
     appKeyValue = mAppPath;
   }
 
   appKeyValue.AppendLiteral(" %s");
 
-  for (unsigned int i = 0; i < aLength; ++i) {
-    nsresult rv = gconf->SetAppForProtocol(nsDependentCString(aProtocols[i]),
-                                           appKeyValue);
+  nsresult rv;
+  if (gconf) {
+    for (unsigned int i = 0; i < aLength; ++i) {
+      rv = gconf->SetAppForProtocol(nsDependentCString(aProtocols[i]),
+                                    appKeyValue);
+      NS_ENSURE_SUCCESS(rv, rv);
+    }
+  }
+
+  if (giovfs) {
+    nsCOMPtr<nsIStringBundleService> bundleService =
+      do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    nsCOMPtr<nsIStringBundle> brandBundle;
+    rv = bundleService->CreateBundle(BRAND_PROPERTIES, getter_AddRefs(brandBundle));
     NS_ENSURE_SUCCESS(rv, rv);
+
+    nsString brandShortName;
+    brandBundle->GetStringFromName(NS_LITERAL_STRING("brandShortName").get(),
+                                   getter_Copies(brandShortName));
+
+    // use brandShortName as the application id.
+    NS_ConvertUTF16toUTF8 id(brandShortName);
+
+    nsCOMPtr<nsIGIOMimeApp> app;
+    rv = giovfs->CreateAppFromCommand(mAppPath, id, getter_AddRefs(app));
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    for (unsigned int i = 0; i < aLength; ++i) {
+      rv = app->SetAsDefaultForURIScheme(nsDependentCString(aProtocols[i]));
+      NS_ENSURE_SUCCESS(rv, rv);
+    }
   }
 
   return NS_OK;
 }
--- a/mail/components/shell/nsMailGNOMEIntegration.h
+++ b/mail/components/shell/nsMailGNOMEIntegration.h
@@ -37,16 +37,18 @@
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsMailGNOMEIntegration_h_
 #define nsMailGNOMEIntegration_h_
 
 #include "nsIShellService.h"
 #include "nsStringGlue.h"
 
+#define BRAND_PROPERTIES "chrome://branding/locale/brand.properties"
+
 #define NS_MAILGNOMEINTEGRATION_CID \
 {0xbddef0f4, 0x5e2d, 0x4846, {0xbd, 0xec, 0x86, 0xd0, 0x78, 0x1d, 0x8d, 0xed}}
 
 class nsMailGNOMEIntegration : public nsIShellService
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSISHELLSERVICE
@@ -57,15 +59,16 @@ public:
 protected:
   virtual ~nsMailGNOMEIntegration() {};
 
   PRBool KeyMatchesAppName(const char *aKeyValue) const;
   PRBool checkDefault(const char* const *aProtocols, unsigned int aLength);
   nsresult MakeDefault(const char* const *aProtocols, unsigned int aLength);
 private:
   PRBool GetAppPathFromLauncher();
+  PRBool CheckHandlerMatchesAppName(const nsACString& handler) const;
   PRPackedBool mUseLocaleFilenames;
   PRPackedBool mCheckedThisSession;
   nsCString mAppPath;
   PRPackedBool mAppIsInPath;
 };
 
 #endif