toolkit/system/gnome/nsGIOService.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "nsGIOService.h"
     7 #include "nsStringAPI.h"
     8 #include "nsIURI.h"
     9 #include "nsTArray.h"
    10 #include "nsIStringEnumerator.h"
    11 #include "nsAutoPtr.h"
    13 #include <gio/gio.h>
    14 #include <gtk/gtk.h>
    15 #ifdef MOZ_ENABLE_DBUS
    16 #include <dbus/dbus-glib.h>
    17 #include <dbus/dbus-glib-lowlevel.h>
    18 #endif
    21 char *
    22 get_content_type_from_mime_type(const char *mimeType)
    23 {
    24   GList* contentTypes = g_content_types_get_registered();
    25   GList* ct_ptr = contentTypes;
    26   char* foundContentType = nullptr;
    28   while (ct_ptr) {
    29     char *mimeTypeFromContentType =  g_content_type_get_mime_type((char*)ct_ptr->data);
    30     if (strcmp(mimeTypeFromContentType, mimeType) == 0) {
    31       foundContentType = g_strdup((char*)ct_ptr->data);
    32       g_free(mimeTypeFromContentType);
    33       break;
    34     }
    35     g_free(mimeTypeFromContentType);
    36     ct_ptr = ct_ptr->next;
    37   }
    38   g_list_foreach(contentTypes, (GFunc) g_free, nullptr);
    39   g_list_free(contentTypes);
    40   return foundContentType;
    41 }
    43 class nsGIOMimeApp MOZ_FINAL : public nsIGIOMimeApp
    44 {
    45 public:
    46   NS_DECL_ISUPPORTS
    47   NS_DECL_NSIGIOMIMEAPP
    49   nsGIOMimeApp(GAppInfo* aApp) : mApp(aApp) {}
    50   ~nsGIOMimeApp() { g_object_unref(mApp); }
    52 private:
    53   GAppInfo *mApp;
    54 };
    56 NS_IMPL_ISUPPORTS(nsGIOMimeApp, nsIGIOMimeApp)
    58 NS_IMETHODIMP
    59 nsGIOMimeApp::GetId(nsACString& aId)
    60 {
    61   aId.Assign(g_app_info_get_id(mApp));
    62   return NS_OK;
    63 }
    65 NS_IMETHODIMP
    66 nsGIOMimeApp::GetName(nsACString& aName)
    67 {
    68   aName.Assign(g_app_info_get_name(mApp));
    69   return NS_OK;
    70 }
    72 NS_IMETHODIMP
    73 nsGIOMimeApp::GetCommand(nsACString& aCommand)
    74 {
    75   const char *cmd = g_app_info_get_commandline(mApp);
    76   if (!cmd)
    77     return NS_ERROR_FAILURE;
    78   aCommand.Assign(cmd);
    79   return NS_OK;
    80 }
    82 NS_IMETHODIMP
    83 nsGIOMimeApp::GetExpectsURIs(int32_t* aExpects)
    84 {
    85   *aExpects = g_app_info_supports_uris(mApp);
    86   return NS_OK;
    87 }
    89 NS_IMETHODIMP
    90 nsGIOMimeApp::Launch(const nsACString& aUri)
    91 {
    92   GList uris = { 0 };
    93   PromiseFlatCString flatUri(aUri);
    94   uris.data = const_cast<char*>(flatUri.get());
    96   GError *error = nullptr;
    97   gboolean result = g_app_info_launch_uris(mApp, &uris, nullptr, &error);
    99   if (!result) {
   100     g_warning("Cannot launch application: %s", error->message);
   101     g_error_free(error);
   102     return NS_ERROR_FAILURE;
   103   }
   105   return NS_OK;
   106 }
   108 class GIOUTF8StringEnumerator MOZ_FINAL : public nsIUTF8StringEnumerator
   109 {
   110 public:
   111   GIOUTF8StringEnumerator() : mIndex(0) { }
   112   ~GIOUTF8StringEnumerator() { }
   114   NS_DECL_ISUPPORTS
   115   NS_DECL_NSIUTF8STRINGENUMERATOR
   117   nsTArray<nsCString> mStrings;
   118   uint32_t            mIndex;
   119 };
   121 NS_IMPL_ISUPPORTS(GIOUTF8StringEnumerator, nsIUTF8StringEnumerator)
   123 NS_IMETHODIMP
   124 GIOUTF8StringEnumerator::HasMore(bool* aResult)
   125 {
   126   *aResult = mIndex < mStrings.Length();
   127   return NS_OK;
   128 }
   130 NS_IMETHODIMP
   131 GIOUTF8StringEnumerator::GetNext(nsACString& aResult)
   132 {
   133   if (mIndex >= mStrings.Length())
   134     return NS_ERROR_UNEXPECTED;
   136   aResult.Assign(mStrings[mIndex]);
   137   ++mIndex;
   138   return NS_OK;
   139 }
   141 NS_IMETHODIMP
   142 nsGIOMimeApp::GetSupportedURISchemes(nsIUTF8StringEnumerator** aSchemes)
   143 {
   144   *aSchemes = nullptr;
   146   nsRefPtr<GIOUTF8StringEnumerator> array = new GIOUTF8StringEnumerator();
   147   NS_ENSURE_TRUE(array, NS_ERROR_OUT_OF_MEMORY);
   149   GVfs *gvfs = g_vfs_get_default();
   151   if (!gvfs) {
   152     g_warning("Cannot get GVfs object.");
   153     return NS_ERROR_OUT_OF_MEMORY;
   154   }
   156   const gchar* const * uri_schemes = g_vfs_get_supported_uri_schemes(gvfs);
   158   while (*uri_schemes != nullptr) {
   159     if (!array->mStrings.AppendElement(*uri_schemes)) {
   160       return NS_ERROR_OUT_OF_MEMORY;
   161     }
   162     uri_schemes++;
   163   }
   165   NS_ADDREF(*aSchemes = array);
   166   return NS_OK;
   167 }
   169 NS_IMETHODIMP
   170 nsGIOMimeApp::SetAsDefaultForMimeType(nsACString const& aMimeType)
   171 {
   172   char *content_type =
   173     get_content_type_from_mime_type(PromiseFlatCString(aMimeType).get());
   174   if (!content_type)
   175     return NS_ERROR_FAILURE;
   176   GError *error = nullptr;
   177   g_app_info_set_as_default_for_type(mApp,
   178                                      content_type,
   179                                      &error);
   180   if (error) {
   181     g_warning("Cannot set application as default for MIME type (%s): %s",
   182               PromiseFlatCString(aMimeType).get(),
   183               error->message);
   184     g_error_free(error);
   185     g_free(content_type);
   186     return NS_ERROR_FAILURE;
   187   }
   189   g_free(content_type);
   190   return NS_OK;
   191 }
   192 /**
   193  * Set default application for files with given extensions
   194  * @param fileExts string of space separated extensions
   195  * @return NS_OK when application was set as default for given extensions,
   196  * NS_ERROR_FAILURE otherwise
   197  */
   198 NS_IMETHODIMP
   199 nsGIOMimeApp::SetAsDefaultForFileExtensions(nsACString const& fileExts)
   200 {
   201   GError *error = nullptr;
   202   char *extensions = g_strdup(PromiseFlatCString(fileExts).get());
   203   char *ext_pos = extensions;
   204   char *space_pos;
   206   while ( (space_pos = strchr(ext_pos, ' ')) || (*ext_pos != '\0') ) {
   207     if (space_pos) {
   208       *space_pos = '\0';
   209     }
   210     g_app_info_set_as_default_for_extension(mApp, ext_pos, &error);
   211     if (error) {
   212       g_warning("Cannot set application as default for extension (%s): %s",
   213                 ext_pos,
   214                 error->message);
   215       g_error_free(error);
   216       g_free(extensions);
   217       return NS_ERROR_FAILURE;
   218     }
   219     if (space_pos) {
   220       ext_pos = space_pos + 1;
   221     } else {
   222       *ext_pos = '\0';
   223     }
   224   }
   225   g_free(extensions);
   226   return NS_OK;
   227 }
   229 /**
   230  * Set default application for URI's of a particular scheme
   231  * @param aURIScheme string containing the URI scheme
   232  * @return NS_OK when application was set as default for URI scheme,
   233  * NS_ERROR_FAILURE otherwise
   234  */
   235 NS_IMETHODIMP
   236 nsGIOMimeApp::SetAsDefaultForURIScheme(nsACString const& aURIScheme)
   237 {
   238   GError *error = nullptr;
   239   nsAutoCString contentType("x-scheme-handler/");
   240   contentType.Append(aURIScheme);
   242   g_app_info_set_as_default_for_type(mApp,
   243                                      contentType.get(),
   244                                      &error);
   245   if (error) {
   246     g_warning("Cannot set application as default for URI scheme (%s): %s",
   247               PromiseFlatCString(aURIScheme).get(),
   248               error->message);
   249     g_error_free(error);
   250     return NS_ERROR_FAILURE;
   251   }
   253   return NS_OK;
   254 }
   256 NS_IMPL_ISUPPORTS(nsGIOService, nsIGIOService)
   258 NS_IMETHODIMP
   259 nsGIOService::GetMimeTypeFromExtension(const nsACString& aExtension,
   260                                              nsACString& aMimeType)
   261 {
   262   nsAutoCString fileExtToUse("file.");
   263   fileExtToUse.Append(aExtension);
   265   gboolean result_uncertain;
   266   char *content_type = g_content_type_guess(fileExtToUse.get(),
   267                                             nullptr,
   268                                             0,
   269                                             &result_uncertain);
   270   if (!content_type)
   271     return NS_ERROR_FAILURE;
   273   char *mime_type = g_content_type_get_mime_type(content_type);
   274   if (!mime_type) {
   275     g_free(content_type);
   276     return NS_ERROR_FAILURE;
   277   }
   279   aMimeType.Assign(mime_type);
   281   g_free(mime_type);
   282   g_free(content_type);
   284   return NS_OK;
   285 }
   286 // used in nsGNOMERegistry
   287 // -----------------------------------------------------------------------------
   288 NS_IMETHODIMP
   289 nsGIOService::GetAppForURIScheme(const nsACString& aURIScheme,
   290                                  nsIGIOMimeApp** aApp)
   291 {
   292   *aApp = nullptr;
   294   GAppInfo *app_info = g_app_info_get_default_for_uri_scheme(
   295                           PromiseFlatCString(aURIScheme).get());
   296   if (app_info) {
   297     nsGIOMimeApp *mozApp = new nsGIOMimeApp(app_info);
   298     NS_ADDREF(*aApp = mozApp);
   299   } else {
   300     return NS_ERROR_FAILURE;
   301   }
   302   return NS_OK;
   303 }
   305 NS_IMETHODIMP
   306 nsGIOService::GetAppForMimeType(const nsACString& aMimeType,
   307                                 nsIGIOMimeApp**   aApp)
   308 {
   309   *aApp = nullptr;
   310   char *content_type =
   311     get_content_type_from_mime_type(PromiseFlatCString(aMimeType).get());
   312   if (!content_type)
   313     return NS_ERROR_FAILURE;
   315   GAppInfo *app_info = g_app_info_get_default_for_type(content_type, false);
   316   if (app_info) {
   317     nsGIOMimeApp *mozApp = new nsGIOMimeApp(app_info);
   318     NS_ENSURE_TRUE(mozApp, NS_ERROR_OUT_OF_MEMORY);
   319     NS_ADDREF(*aApp = mozApp);
   320   } else {
   321     g_free(content_type);
   322     return NS_ERROR_FAILURE;
   323   }
   324   g_free(content_type);
   325   return NS_OK;
   326 }
   328 NS_IMETHODIMP
   329 nsGIOService::GetDescriptionForMimeType(const nsACString& aMimeType,
   330                                               nsACString& aDescription)
   331 {
   332   char *content_type =
   333     get_content_type_from_mime_type(PromiseFlatCString(aMimeType).get());
   334   if (!content_type)
   335     return NS_ERROR_FAILURE;
   337   char *desc = g_content_type_get_description(content_type);
   338   if (!desc) {
   339     g_free(content_type);
   340     return NS_ERROR_FAILURE;
   341   }
   343   aDescription.Assign(desc);
   344   g_free(content_type);
   345   g_free(desc);
   346   return NS_OK;
   347 }
   349 NS_IMETHODIMP
   350 nsGIOService::ShowURI(nsIURI* aURI)
   351 {
   352   nsAutoCString spec;
   353   aURI->GetSpec(spec);
   354   GError *error = nullptr;
   355   if (!g_app_info_launch_default_for_uri(spec.get(), nullptr, &error)) {
   356     g_warning("Could not launch default application for URI: %s", error->message);
   357     g_error_free(error);
   358     return NS_ERROR_FAILURE;
   359   }
   360   return NS_OK;
   361 }
   363 NS_IMETHODIMP
   364 nsGIOService::ShowURIForInput(const nsACString& aUri)
   365 {
   366   GFile *file = g_file_new_for_commandline_arg(PromiseFlatCString(aUri).get());
   367   char* spec = g_file_get_uri(file);
   368   nsresult rv = NS_ERROR_FAILURE;
   369   GError *error = nullptr;
   371   g_app_info_launch_default_for_uri(spec, nullptr, &error);
   372   if (error) {
   373     g_warning("Cannot launch default application: %s", error->message);
   374     g_error_free(error);
   375   } else {
   376     rv = NS_OK;
   377   }
   378   g_object_unref(file);
   379   g_free(spec);
   381   return rv;
   382 }
   384 NS_IMETHODIMP
   385 nsGIOService::OrgFreedesktopFileManager1ShowItems(const nsACString& aPath)
   386 {
   387 #ifndef MOZ_ENABLE_DBUS
   388   return NS_ERROR_FAILURE;
   389 #else
   390   GError* error = nullptr;
   391   static bool org_freedesktop_FileManager1_exists = true;
   393   if (!org_freedesktop_FileManager1_exists) {
   394     return NS_ERROR_NOT_AVAILABLE;
   395   }
   397   DBusGConnection* dbusGConnection = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
   399   if (!dbusGConnection) {
   400     if (error) {
   401       g_printerr("Failed to open connection to session bus: %s\n", error->message);
   402       g_error_free(error);
   403     }
   404     return NS_ERROR_FAILURE;
   405   }
   407   char *uri = g_filename_to_uri(PromiseFlatCString(aPath).get(), nullptr, nullptr);
   408   if (uri == nullptr) {
   409     return NS_ERROR_FAILURE;
   410   }
   412   DBusConnection* dbusConnection = dbus_g_connection_get_connection(dbusGConnection);
   413   // Make sure we do not exit the entire program if DBus connection get lost.
   414   dbus_connection_set_exit_on_disconnect(dbusConnection, false);
   416   DBusGProxy* dbusGProxy = dbus_g_proxy_new_for_name(dbusGConnection,
   417                                                      "org.freedesktop.FileManager1",
   418                                                      "/org/freedesktop/FileManager1",
   419                                                      "org.freedesktop.FileManager1");
   421   const char *uris[2] = { uri, nullptr };
   422   gboolean rv_dbus_call = dbus_g_proxy_call (dbusGProxy, "ShowItems", nullptr, G_TYPE_STRV, uris,
   423                                              G_TYPE_STRING, "", G_TYPE_INVALID, G_TYPE_INVALID);
   425   g_object_unref(dbusGProxy);
   426   dbus_g_connection_unref(dbusGConnection);
   427   g_free(uri);
   429   if (!rv_dbus_call) {
   430     org_freedesktop_FileManager1_exists = false;
   431     return NS_ERROR_NOT_AVAILABLE;
   432   }
   434   return NS_OK;
   435 #endif
   436 }
   438 /**
   439  * Create or find already existing application info for specified command
   440  * and application name.
   441  * @param cmd command to execute
   442  * @param appName application name
   443  * @param appInfo location where created GAppInfo is stored
   444  * @return NS_OK when object is created, NS_ERROR_FAILURE otherwise.
   445  */
   446 NS_IMETHODIMP
   447 nsGIOService::CreateAppFromCommand(nsACString const& cmd,
   448                                    nsACString const& appName,
   449                                    nsIGIOMimeApp**   appInfo)
   450 {
   451   GError *error = nullptr;
   452   *appInfo = nullptr;
   454   GAppInfo *app_info = nullptr, *app_info_from_list = nullptr;
   455   GList *apps = g_app_info_get_all();
   456   GList *apps_p = apps;
   458   // Try to find relevant and existing GAppInfo in all installed application
   459   // We do this by comparing each GAppInfo's executable with out own
   460   while (apps_p) {
   461     app_info_from_list = (GAppInfo*) apps_p->data;
   462     if (!app_info) {
   463       // If the executable is not absolute, get it's full path
   464       char *executable = g_find_program_in_path(g_app_info_get_executable(app_info_from_list));
   466       if (executable && strcmp(executable, PromiseFlatCString(cmd).get()) == 0) {
   467         g_object_ref (app_info_from_list);
   468         app_info = app_info_from_list;
   469       }
   470       g_free(executable);
   471     }
   473     g_object_unref(app_info_from_list);
   474     apps_p = apps_p->next;
   475   }
   476   g_list_free(apps);
   478   if (!app_info) {
   479     app_info = g_app_info_create_from_commandline(PromiseFlatCString(cmd).get(),
   480                                                   PromiseFlatCString(appName).get(),
   481                                                   G_APP_INFO_CREATE_SUPPORTS_URIS,
   482                                                   &error);
   483   }
   485   if (!app_info) {
   486     g_warning("Cannot create application info from command: %s", error->message);
   487     g_error_free(error);
   488     return NS_ERROR_FAILURE;
   489   }
   490   nsGIOMimeApp *mozApp = new nsGIOMimeApp(app_info);
   491   NS_ENSURE_TRUE(mozApp, NS_ERROR_OUT_OF_MEMORY);
   492   NS_ADDREF(*appInfo = mozApp);
   493   return NS_OK;
   494 }

mercurial