LCOV - code coverage report
Current view: top level - toolkit/components/jsdownloads/src - DownloadPlatform.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 65 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 8 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* This Source Code Form is subject to the terms of the Mozilla Public
       2             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       3             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       4             : 
       5             : #include "DownloadPlatform.h"
       6             : #include "nsAutoPtr.h"
       7             : #include "nsNetUtil.h"
       8             : #include "nsString.h"
       9             : #include "nsINestedURI.h"
      10             : #include "nsIProtocolHandler.h"
      11             : #include "nsIURI.h"
      12             : #include "nsIFile.h"
      13             : #include "nsIObserverService.h"
      14             : #include "nsISupportsPrimitives.h"
      15             : #include "nsDirectoryServiceDefs.h"
      16             : 
      17             : #include "mozilla/Preferences.h"
      18             : #include "mozilla/Services.h"
      19             : 
      20             : #define PREF_BDM_ADDTORECENTDOCS "browser.download.manager.addToRecentDocs"
      21             : 
      22             : #ifdef XP_WIN
      23             : #include <shlobj.h>
      24             : #include <urlmon.h>
      25             : #include "nsILocalFileWin.h"
      26             : #endif
      27             : 
      28             : #ifdef XP_MACOSX
      29             : #include <CoreFoundation/CoreFoundation.h>
      30             : #include "../../../../xpcom/io/CocoaFileUtils.h"
      31             : #endif
      32             : 
      33             : #ifdef MOZ_WIDGET_ANDROID
      34             : #include "FennecJNIWrappers.h"
      35             : #endif
      36             : 
      37             : #ifdef MOZ_WIDGET_GTK
      38             : #include <gtk/gtk.h>
      39             : #endif
      40             : 
      41             : using namespace mozilla;
      42             : 
      43             : DownloadPlatform *DownloadPlatform::gDownloadPlatformService = nullptr;
      44             : 
      45           0 : NS_IMPL_ISUPPORTS(DownloadPlatform, mozIDownloadPlatform);
      46             : 
      47           0 : DownloadPlatform* DownloadPlatform::GetDownloadPlatform()
      48             : {
      49           0 :   if (!gDownloadPlatformService) {
      50           0 :     gDownloadPlatformService = new DownloadPlatform();
      51             :   }
      52             : 
      53           0 :   NS_ADDREF(gDownloadPlatformService);
      54             : 
      55             : #if defined(MOZ_WIDGET_GTK)
      56           0 :   g_type_init();
      57             : #endif
      58             : 
      59           0 :   return gDownloadPlatformService;
      60             : }
      61             : 
      62             : #ifdef MOZ_WIDGET_GTK
      63           0 : static void gio_set_metadata_done(GObject *source_obj, GAsyncResult *res, gpointer user_data)
      64             : {
      65           0 :   GError *err = nullptr;
      66           0 :   g_file_set_attributes_finish(G_FILE(source_obj), res, nullptr, &err);
      67           0 :   if (err) {
      68             : #ifdef DEBUG
      69           0 :     NS_DebugBreak(NS_DEBUG_WARNING, "Set file metadata failed: ", err->message, __FILE__, __LINE__);
      70             : #endif
      71           0 :     g_error_free(err);
      72             :   }
      73           0 : }
      74             : #endif
      75             : 
      76             : #ifdef XP_MACOSX
      77             : // Caller is responsible for freeing any result (CF Create Rule)
      78             : CFURLRef CreateCFURLFromNSIURI(nsIURI *aURI) {
      79             :   nsAutoCString spec;
      80             :   if (aURI) {
      81             :     aURI->GetSpec(spec);
      82             :   }
      83             : 
      84             :   CFStringRef urlStr = ::CFStringCreateWithCString(kCFAllocatorDefault,
      85             :                                                    spec.get(),
      86             :                                                    kCFStringEncodingUTF8);
      87             :   if (!urlStr) {
      88             :     return NULL;
      89             :   }
      90             : 
      91             :   CFURLRef url = ::CFURLCreateWithString(kCFAllocatorDefault,
      92             :                                          urlStr,
      93             :                                          NULL);
      94             : 
      95             :   ::CFRelease(urlStr);
      96             : 
      97             :   return url;
      98             : }
      99             : #endif
     100             : 
     101           0 : nsresult DownloadPlatform::DownloadDone(nsIURI* aSource, nsIURI* aReferrer, nsIFile* aTarget,
     102             :                                         const nsACString& aContentType, bool aIsPrivate)
     103             : {
     104             : #if defined(XP_WIN) || defined(XP_MACOSX) || defined(MOZ_WIDGET_ANDROID) \
     105             :  || defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_GONK)
     106             : 
     107           0 :   nsAutoString path;
     108           0 :   if (aTarget && NS_SUCCEEDED(aTarget->GetPath(path))) {
     109             : #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_ANDROID)
     110             :     // On Windows and Gtk, add the download to the system's "recent documents"
     111             :     // list, with a pref to disable.
     112             :     {
     113           0 :       bool addToRecentDocs = Preferences::GetBool(PREF_BDM_ADDTORECENTDOCS);
     114             : #ifdef MOZ_WIDGET_ANDROID
     115             :       if (jni::IsFennec() && addToRecentDocs) {
     116             :         java::DownloadsIntegration::ScanMedia(path, aContentType);
     117             :       }
     118             : #else
     119           0 :       if (addToRecentDocs && !aIsPrivate) {
     120             : #ifdef XP_WIN
     121             :         ::SHAddToRecentDocs(SHARD_PATHW, path.get());
     122             : #elif defined(MOZ_WIDGET_GTK)
     123           0 :         GtkRecentManager* manager = gtk_recent_manager_get_default();
     124             : 
     125           0 :         gchar* uri = g_filename_to_uri(NS_ConvertUTF16toUTF8(path).get(),
     126           0 :                                        nullptr, nullptr);
     127           0 :         if (uri) {
     128           0 :           gtk_recent_manager_add_item(manager, uri);
     129           0 :           g_free(uri);
     130             :         }
     131             : #endif
     132             :       }
     133             : #endif
     134             : #ifdef MOZ_WIDGET_GTK
     135             :       // Use GIO to store the source URI for later display in the file manager.
     136           0 :       GFile* gio_file = g_file_new_for_path(NS_ConvertUTF16toUTF8(path).get());
     137           0 :       nsCString source_uri;
     138           0 :       nsresult rv = aSource->GetSpec(source_uri);
     139           0 :       NS_ENSURE_SUCCESS(rv, rv);
     140           0 :       GFileInfo *file_info = g_file_info_new();
     141           0 :       g_file_info_set_attribute_string(file_info, "metadata::download-uri", source_uri.get());
     142             :       g_file_set_attributes_async(gio_file,
     143             :                                   file_info,
     144             :                                   G_FILE_QUERY_INFO_NONE,
     145             :                                   G_PRIORITY_DEFAULT,
     146           0 :                                   nullptr, gio_set_metadata_done, nullptr);
     147           0 :       g_object_unref(file_info);
     148           0 :       g_object_unref(gio_file);
     149             : #endif
     150             :     }
     151             : #endif
     152             : 
     153             : #ifdef XP_MACOSX
     154             :     // On OS X, make the downloads stack bounce.
     155             :     CFStringRef observedObject = ::CFStringCreateWithCString(kCFAllocatorDefault,
     156             :                                              NS_ConvertUTF16toUTF8(path).get(),
     157             :                                              kCFStringEncodingUTF8);
     158             :     CFNotificationCenterRef center = ::CFNotificationCenterGetDistributedCenter();
     159             :     ::CFNotificationCenterPostNotification(center, CFSTR("com.apple.DownloadFileFinished"),
     160             :                                            observedObject, nullptr, TRUE);
     161             :     ::CFRelease(observedObject);
     162             : 
     163             :     // Add OS X origin and referrer file metadata
     164             :     CFStringRef pathCFStr = NULL;
     165             :     if (!path.IsEmpty()) {
     166             :       pathCFStr = ::CFStringCreateWithCharacters(kCFAllocatorDefault,
     167             :                                                  (const UniChar*)path.get(),
     168             :                                                  path.Length());
     169             :     }
     170             :     if (pathCFStr) {
     171             :       bool isFromWeb = IsURLPossiblyFromWeb(aSource);
     172             : 
     173             :       CFURLRef sourceCFURL = CreateCFURLFromNSIURI(aSource);
     174             :       CFURLRef referrerCFURL = CreateCFURLFromNSIURI(aReferrer);
     175             : 
     176             :       CocoaFileUtils::AddOriginMetadataToFile(pathCFStr,
     177             :                                               sourceCFURL,
     178             :                                               referrerCFURL);
     179             :       CocoaFileUtils::AddQuarantineMetadataToFile(pathCFStr,
     180             :                                                   sourceCFURL,
     181             :                                                   referrerCFURL,
     182             :                                                   isFromWeb);
     183             : 
     184             :       ::CFRelease(pathCFStr);
     185             :       if (sourceCFURL) {
     186             :         ::CFRelease(sourceCFURL);
     187             :       }
     188             :       if (referrerCFURL) {
     189             :         ::CFRelease(referrerCFURL);
     190             :       }
     191             :     }
     192             : #endif
     193             :   }
     194             : 
     195             : #endif
     196             : 
     197           0 :   return NS_OK;
     198             : }
     199             : 
     200           0 : nsresult DownloadPlatform::MapUrlToZone(const nsAString& aURL,
     201             :                                         uint32_t* aZone)
     202             : {
     203             : #ifdef XP_WIN
     204             :   RefPtr<IInternetSecurityManager> inetSecMgr;
     205             :   if (FAILED(CoCreateInstance(CLSID_InternetSecurityManager, NULL,
     206             :                               CLSCTX_ALL, IID_IInternetSecurityManager,
     207             :                               getter_AddRefs(inetSecMgr)))) {
     208             :     return NS_ERROR_UNEXPECTED;
     209             :   }
     210             : 
     211             :   DWORD zone;
     212             :   if (inetSecMgr->MapUrlToZone(PromiseFlatString(aURL).get(),
     213             :                                &zone, 0) != S_OK) {
     214             :     return NS_ERROR_UNEXPECTED;
     215             :   } else {
     216             :     *aZone = zone;
     217             :   }
     218             : 
     219             :   return NS_OK;
     220             : #else
     221           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     222             : #endif
     223             : }
     224             : 
     225             : // Check if a URI is likely to be web-based, by checking its URI flags.
     226             : // If in doubt (e.g. if anything fails during the check) claims things
     227             : // are from the web.
     228           0 : bool DownloadPlatform::IsURLPossiblyFromWeb(nsIURI* aURI)
     229             : {
     230           0 :   nsCOMPtr<nsIIOService> ios = do_GetIOService();
     231           0 :   nsCOMPtr<nsIURI> uri = aURI;
     232           0 :   if (!ios) {
     233           0 :     return true;
     234             :   }
     235             : 
     236           0 :   while (uri) {
     237             :     // We're not using nsIIOService::ProtocolHasFlags because it doesn't
     238             :     // take per-URI flags into account. We're also not using
     239             :     // NS_URIChainHasFlags because we're checking for *any* of 3 flags
     240             :     // to be present on *all* of the nested URIs, which it can't do.
     241           0 :     nsAutoCString scheme;
     242           0 :     nsresult rv = uri->GetScheme(scheme);
     243           0 :     if (NS_FAILED(rv)) {
     244           0 :       return true;
     245             :     }
     246           0 :     nsCOMPtr<nsIProtocolHandler> ph;
     247           0 :     rv = ios->GetProtocolHandler(scheme.get(), getter_AddRefs(ph));
     248           0 :     if (NS_FAILED(rv)) {
     249           0 :       return true;
     250             :     }
     251             :     uint32_t flags;
     252           0 :     rv = ph->DoGetProtocolFlags(uri, &flags);
     253           0 :     if (NS_FAILED(rv)) {
     254           0 :       return true;
     255             :     }
     256             :     // If not dangerous to load, not a UI resource and not a local file,
     257             :     // assume this is from the web:
     258           0 :     if (!(flags & nsIProtocolHandler::URI_DANGEROUS_TO_LOAD) &&
     259           0 :         !(flags & nsIProtocolHandler::URI_IS_UI_RESOURCE) &&
     260           0 :         !(flags & nsIProtocolHandler::URI_IS_LOCAL_FILE)) {
     261           0 :       return true;
     262             :     }
     263             :     // Otherwise, check if the URI is nested, and if so go through
     264             :     // the loop again:
     265           0 :     nsCOMPtr<nsINestedURI> nestedURI = do_QueryInterface(uri);
     266           0 :     uri = nullptr;
     267           0 :     if (nestedURI) {
     268           0 :       rv = nestedURI->GetInnerURI(getter_AddRefs(uri));
     269           0 :       if (NS_FAILED(rv)) {
     270           0 :         return true;
     271             :       }
     272             :     }
     273             :   }
     274           0 :   return false;
     275             : }

Generated by: LCOV version 1.13