firefox-shellservice.patch
changeset 289 3c0dff7ca9c4
parent 288 d51f3999a1c2
child 290 8e4307c73cbd
equal deleted inserted replaced
288:d51f3999a1c2 289:3c0dff7ca9c4
     1 # HG changeset patch
       
     2 # Parent 948830682920db68e4b039f5babc34dea0040415
       
     3 Bug 611953 - GNOME 3.0 readiness (based on patch 3)
       
     4 
       
     5 diff --git a/browser/components/shell/src/nsGNOMEShellService.cpp b/browser/components/shell/src/nsGNOMEShellService.cpp
       
     6 --- a/browser/components/shell/src/nsGNOMEShellService.cpp
       
     7 +++ b/browser/components/shell/src/nsGNOMEShellService.cpp
       
     8 @@ -101,30 +101,33 @@ static const char kDesktopOptionsKey[] =
       
     9  static const char kDesktopDrawBGKey[] = DG_BACKGROUND "/draw_background";
       
    10  static const char kDesktopColorKey[] = DG_BACKGROUND "/primary_color";
       
    11  
       
    12  nsresult
       
    13  nsGNOMEShellService::Init()
       
    14  {
       
    15    nsresult rv;
       
    16  
       
    17 -  // GConf _must_ be available, or we do not allow
       
    18 +  // GConf or GIO _must_ be available, or we do not allow
       
    19    // CreateInstance to succeed.
       
    20  
       
    21    nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID);
       
    22    nsCOMPtr<nsIGIOService> giovfs =
       
    23      do_GetService(NS_GIOSERVICE_CONTRACTID);
       
    24  
       
    25 -  if (!gconf)
       
    26 +  if (!gconf && !giovfs)
       
    27      return NS_ERROR_NOT_AVAILABLE;
       
    28  
       
    29    // Check G_BROKEN_FILENAMES.  If it's set, then filenames in glib use
       
    30    // the locale encoding.  If it's not set, they use UTF-8.
       
    31    mUseLocaleFilenames = PR_GetEnv("G_BROKEN_FILENAMES") != nsnull;
       
    32  
       
    33 +  if (GetAppPathFromLauncher())
       
    34 +    return NS_OK;
       
    35 +
       
    36    nsCOMPtr<nsIProperties> dirSvc
       
    37      (do_GetService("@mozilla.org/file/directory_service;1"));
       
    38    NS_ENSURE_TRUE(dirSvc, NS_ERROR_NOT_AVAILABLE);
       
    39  
       
    40    nsCOMPtr<nsILocalFile> appPath;
       
    41    rv = dirSvc->Get(NS_XPCOM_CURRENT_PROCESS_DIR, NS_GET_IID(nsILocalFile),
       
    42                     getter_AddRefs(appPath));
       
    43    NS_ENSURE_SUCCESS(rv, rv);
       
    44 @@ -133,16 +136,44 @@ nsGNOMEShellService::Init()
       
    45    NS_ENSURE_SUCCESS(rv, rv);
       
    46  
       
    47    return appPath->GetNativePath(mAppPath);
       
    48  }
       
    49  
       
    50  NS_IMPL_ISUPPORTS1(nsGNOMEShellService, nsIShellService)
       
    51  
       
    52  PRBool
       
    53 +nsGNOMEShellService::GetAppPathFromLauncher()
       
    54 +{
       
    55 +  gchar *tmp;
       
    56 +
       
    57 +  const char *launcher = PR_GetEnv("MOZ_APP_LAUNCHER");
       
    58 +  if (!launcher)
       
    59 +    return PR_FALSE;
       
    60 +
       
    61 +  if (g_path_is_absolute(launcher)) {
       
    62 +    mAppPath = launcher;
       
    63 +    tmp = g_path_get_basename(launcher);
       
    64 +    gchar *fullpath = g_find_program_in_path(tmp);
       
    65 +    if (fullpath && mAppPath.Equals(fullpath))
       
    66 +      mAppIsInPath = PR_TRUE;
       
    67 +    g_free(fullpath);
       
    68 +  } else {
       
    69 +    tmp = g_find_program_in_path(launcher);
       
    70 +    if (!tmp)
       
    71 +      return PR_FALSE;
       
    72 +    mAppPath = tmp;
       
    73 +    mAppIsInPath = PR_TRUE;
       
    74 +  }
       
    75 +
       
    76 +  g_free(tmp);
       
    77 +  return PR_TRUE;
       
    78 +}
       
    79 +
       
    80 +PRBool
       
    81  nsGNOMEShellService::KeyMatchesAppName(const char *aKeyValue) const
       
    82  {
       
    83  
       
    84    gchar *commandPath;
       
    85    if (mUseLocaleFilenames) {
       
    86      gchar *nativePath = g_filename_from_utf8(aKeyValue, -1, NULL, NULL, NULL);
       
    87      if (!nativePath) {
       
    88        NS_ERROR("Error converting path to filesystem encoding");
       
    89 @@ -158,84 +189,119 @@ nsGNOMEShellService::KeyMatchesAppName(c
       
    90    if (!commandPath)
       
    91      return PR_FALSE;
       
    92  
       
    93    PRBool matches = mAppPath.Equals(commandPath);
       
    94    g_free(commandPath);
       
    95    return matches;
       
    96  }
       
    97  
       
    98 +PRBool
       
    99 +nsGNOMEShellService::CheckHandlerMatchesAppName(const nsACString &handler) const
       
   100 +{
       
   101 +  gint argc;
       
   102 +  gchar **argv;
       
   103 +  nsCAutoString command(handler);
       
   104 +
       
   105 +  // The string will be something of the form: [/path/to/]browser "%s"
       
   106 +  // We want to remove all of the parameters and get just the binary name.
       
   107 +  if (g_shell_parse_argv(command.get(), &argc, &argv, NULL) && argc > 0) {
       
   108 +    command.Assign(argv[0]);
       
   109 +    g_strfreev(argv);
       
   110 +  }
       
   111 +
       
   112 +  if (!KeyMatchesAppName(command.get()))
       
   113 +    return PR_FALSE; // the handler is disabled or set to another app
       
   114 +
       
   115 +  return PR_TRUE;
       
   116 +}
       
   117 +
       
   118  NS_IMETHODIMP
       
   119  nsGNOMEShellService::IsDefaultBrowser(PRBool aStartupCheck,
       
   120                                        PRBool* aIsDefaultBrowser)
       
   121  {
       
   122    *aIsDefaultBrowser = PR_FALSE;
       
   123    if (aStartupCheck)
       
   124      mCheckedThisSession = PR_TRUE;
       
   125  
       
   126    nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID);
       
   127 +  nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID);
       
   128  
       
   129    PRBool enabled;
       
   130    nsCAutoString handler;
       
   131 +  nsCOMPtr<nsIGIOMimeApp> gioApp;
       
   132  
       
   133    for (unsigned int i = 0; i < NS_ARRAY_LENGTH(appProtocols); ++i) {
       
   134      if (!appProtocols[i].essential)
       
   135        continue;
       
   136  
       
   137 -    handler.Truncate();
       
   138 -    gconf->GetAppForProtocol(nsDependentCString(appProtocols[i].name),
       
   139 -                             &enabled, handler);
       
   140 +    if (gconf) {
       
   141 +      handler.Truncate();
       
   142 +      gconf->GetAppForProtocol(nsDependentCString(appProtocols[i].name),
       
   143 +                               &enabled, handler);
       
   144  
       
   145 -    // The string will be something of the form: [/path/to/]browser "%s"
       
   146 -    // We want to remove all of the parameters and get just the binary name.
       
   147 -
       
   148 -    gint argc;
       
   149 -    gchar **argv;
       
   150 -
       
   151 -    if (g_shell_parse_argv(handler.get(), &argc, &argv, NULL) && argc > 0) {
       
   152 -      handler.Assign(argv[0]);
       
   153 -      g_strfreev(argv);
       
   154 +      if (!CheckHandlerMatchesAppName(handler) || !enabled)
       
   155 +        return NS_OK; // the handler is disabled or set to another app
       
   156      }
       
   157  
       
   158 -    if (!KeyMatchesAppName(handler.get()) || !enabled)
       
   159 -      return NS_OK; // the handler is disabled or set to another app
       
   160 +    if (giovfs) {
       
   161 +      handler.Truncate();
       
   162 +      giovfs->GetAppForURIScheme(nsDependentCString(appProtocols[i].name),
       
   163 +                                 getter_AddRefs(gioApp));
       
   164 +      if (!gioApp)
       
   165 +        return NS_OK;
       
   166 +
       
   167 +      gioApp->GetCommand(handler);
       
   168 +
       
   169 +      if (!CheckHandlerMatchesAppName(handler))
       
   170 +        return NS_OK; // the handler is set to another app
       
   171 +    }
       
   172    }
       
   173  
       
   174    *aIsDefaultBrowser = PR_TRUE;
       
   175  
       
   176    return NS_OK;
       
   177  }
       
   178  
       
   179  NS_IMETHODIMP
       
   180  nsGNOMEShellService::SetDefaultBrowser(PRBool aClaimAllTypes,
       
   181                                         PRBool aForAllUsers)
       
   182  {
       
   183  #ifdef DEBUG
       
   184    if (aForAllUsers)
       
   185      NS_WARNING("Setting the default browser for all users is not yet supported");
       
   186  #endif
       
   187  
       
   188 +  nsCAutoString appKeyValue;
       
   189    nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID);
       
   190 +  nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID);
       
   191 +
       
   192 +  if (mAppIsInPath) {
       
   193 +    // mAppPath is in the users path, so use only the basename as the
       
   194 +    // launcher
       
   195 +    gchar *tmp = g_path_get_basename(mAppPath.get());
       
   196 +    appKeyValue = tmp;
       
   197 +    g_free(tmp);
       
   198 +  } else {
       
   199 +    appKeyValue = mAppPath;
       
   200 +  }
       
   201 +  appKeyValue.AppendLiteral(" %s");
       
   202 +
       
   203    if (gconf) {
       
   204 -    nsCAutoString appKeyValue(mAppPath);
       
   205 -    appKeyValue.Append(" \"%s\"");
       
   206      for (unsigned int i = 0; i < NS_ARRAY_LENGTH(appProtocols); ++i) {
       
   207        if (appProtocols[i].essential || aClaimAllTypes) {
       
   208          gconf->SetAppForProtocol(nsDependentCString(appProtocols[i].name),
       
   209                                   appKeyValue);
       
   210        }
       
   211      }
       
   212    }
       
   213  
       
   214 -  // set handler for .html and xhtml files and MIME types:
       
   215 -  if (aClaimAllTypes) {
       
   216 +  if (giovfs) {
       
   217      nsresult rv;
       
   218 -    nsCOMPtr<nsIGIOService> giovfs =
       
   219 -      do_GetService(NS_GIOSERVICE_CONTRACTID, &rv);
       
   220 -    NS_ENSURE_SUCCESS(rv, NS_OK);
       
   221 +    unsigned int i;
       
   222  
       
   223      nsCOMPtr<nsIStringBundleService> bundleService =
       
   224        do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
       
   225      NS_ENSURE_SUCCESS(rv, rv);
       
   226  
       
   227      nsCOMPtr<nsIStringBundle> brandBundle;
       
   228      rv = bundleService->CreateBundle(BRAND_PROPERTIES, getter_AddRefs(brandBundle));
       
   229      NS_ENSURE_SUCCESS(rv, rv);
       
   230 @@ -249,20 +315,30 @@ nsGNOMEShellService::SetDefaultBrowser(P
       
   231      // use brandShortName as the application id.
       
   232      NS_ConvertUTF16toUTF8 id(brandShortName);
       
   233      nsCOMPtr<nsIGIOMimeApp> appInfo;
       
   234      rv = giovfs->CreateAppFromCommand(mAppPath,
       
   235                                        id,
       
   236                                        getter_AddRefs(appInfo));
       
   237      NS_ENSURE_SUCCESS(rv, rv);
       
   238  
       
   239 -    // Add mime types for html, xhtml extension and set app to just created appinfo.
       
   240 -    for (unsigned int i = 0; i < NS_ARRAY_LENGTH(appTypes); ++i) {
       
   241 -      appInfo->SetAsDefaultForMimeType(nsDependentCString(appTypes[i].mimeType));
       
   242 -      appInfo->SetAsDefaultForFileExtensions(nsDependentCString(appTypes[i].extensions));
       
   243 +    // set handler for the protocols
       
   244 +    for (i = 0; i < NS_ARRAY_LENGTH(appProtocols); ++i) {
       
   245 +      if (appProtocols[i].essential || aClaimAllTypes) {
       
   246 +        appInfo->SetAsDefaultForURIScheme(nsDependentCString(appProtocols[i].name));
       
   247 +      }
       
   248 +    }
       
   249 +
       
   250 +    // set handler for .html and xhtml files and MIME types:
       
   251 +    if (aClaimAllTypes) {
       
   252 +      // Add mime types for html, xhtml extension and set app to just created appinfo.
       
   253 +      for (i = 0; i < NS_ARRAY_LENGTH(appTypes); ++i) {
       
   254 +        appInfo->SetAsDefaultForMimeType(nsDependentCString(appTypes[i].mimeType));
       
   255 +        appInfo->SetAsDefaultForFileExtensions(nsDependentCString(appTypes[i].extensions));
       
   256 +      }
       
   257      }
       
   258    }
       
   259  
       
   260    return NS_OK;
       
   261  }
       
   262  
       
   263  NS_IMETHODIMP
       
   264  nsGNOMEShellService::GetShouldCheckDefaultBrowser(PRBool* aResult)
       
   265 @@ -451,17 +527,27 @@ nsGNOMEShellService::OpenApplication(PRI
       
   266    nsCAutoString scheme;
       
   267    if (aApplication == APPLICATION_MAIL)
       
   268      scheme.Assign("mailto");
       
   269    else if (aApplication == APPLICATION_NEWS)
       
   270      scheme.Assign("news");
       
   271    else
       
   272      return NS_ERROR_NOT_AVAILABLE;
       
   273  
       
   274 +  nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID);
       
   275 +  if (giovfs) {
       
   276 +    nsCOMPtr<nsIGIOMimeApp> gioApp;
       
   277 +    giovfs->GetAppForURIScheme(scheme, getter_AddRefs(gioApp));
       
   278 +    if (gioApp)
       
   279 +      return gioApp->Launch(EmptyCString());
       
   280 +  }
       
   281 +
       
   282    nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID);
       
   283 +  if (!gconf)
       
   284 +    return NS_ERROR_FAILURE;
       
   285  
       
   286    PRBool enabled;
       
   287    nsCAutoString appCommand;
       
   288    gconf->GetAppForProtocol(scheme, &enabled, appCommand);
       
   289  
       
   290    if (!enabled)
       
   291      return NS_ERROR_FAILURE;
       
   292  
       
   293 diff --git a/browser/components/shell/src/nsGNOMEShellService.h b/browser/components/shell/src/nsGNOMEShellService.h
       
   294 --- a/browser/components/shell/src/nsGNOMEShellService.h
       
   295 +++ b/browser/components/shell/src/nsGNOMEShellService.h
       
   296 @@ -38,26 +38,29 @@
       
   297  #define nsgnomeshellservice_h____
       
   298  
       
   299  #include "nsIShellService.h"
       
   300  #include "nsStringAPI.h"
       
   301  
       
   302  class nsGNOMEShellService : public nsIShellService
       
   303  {
       
   304  public:
       
   305 -  nsGNOMEShellService() : mCheckedThisSession(PR_FALSE) { }
       
   306 +  nsGNOMEShellService() : mCheckedThisSession(PR_FALSE), mAppIsInPath(PR_FALSE) { }
       
   307  
       
   308    NS_DECL_ISUPPORTS
       
   309    NS_DECL_NSISHELLSERVICE
       
   310  
       
   311    nsresult Init() NS_HIDDEN;
       
   312  
       
   313  private:
       
   314    ~nsGNOMEShellService() {}
       
   315  
       
   316    NS_HIDDEN_(PRBool) KeyMatchesAppName(const char *aKeyValue) const;
       
   317 +  NS_HIDDEN_(PRBool) CheckHandlerMatchesAppName(const nsACString& handler) const;
       
   318  
       
   319 +  NS_HIDDEN_(PRBool) GetAppPathFromLauncher();
       
   320    PRPackedBool mCheckedThisSession;
       
   321    PRPackedBool mUseLocaleFilenames;
       
   322    nsCString    mAppPath;
       
   323 +  PRPackedBool mAppIsInPath;
       
   324  };
       
   325  
       
   326  #endif // nsgnomeshellservice_h____