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