1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/components/jsdownloads/src/DownloadPlatform.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,175 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +#include "DownloadPlatform.h" 1.9 +#include "nsAutoPtr.h" 1.10 +#include "nsString.h" 1.11 +#include "nsIURI.h" 1.12 +#include "nsIFile.h" 1.13 +#include "nsDirectoryServiceDefs.h" 1.14 + 1.15 +#include "mozilla/Preferences.h" 1.16 + 1.17 +#define PREF_BDM_ADDTORECENTDOCS "browser.download.manager.addToRecentDocs" 1.18 + 1.19 +#ifdef XP_WIN 1.20 +#include <shlobj.h> 1.21 +#include <urlmon.h> 1.22 +#include "nsILocalFileWin.h" 1.23 +#endif 1.24 + 1.25 +#ifdef XP_MACOSX 1.26 +#include <CoreFoundation/CoreFoundation.h> 1.27 +#endif 1.28 + 1.29 +#ifdef MOZ_WIDGET_ANDROID 1.30 +#include "AndroidBridge.h" 1.31 +#endif 1.32 + 1.33 +#ifdef MOZ_WIDGET_GTK 1.34 +#include <gtk/gtk.h> 1.35 +#endif 1.36 + 1.37 +using namespace mozilla; 1.38 + 1.39 +DownloadPlatform *DownloadPlatform::gDownloadPlatformService = nullptr; 1.40 + 1.41 +NS_IMPL_ISUPPORTS(DownloadPlatform, mozIDownloadPlatform); 1.42 + 1.43 +DownloadPlatform* DownloadPlatform::GetDownloadPlatform() 1.44 +{ 1.45 + if (!gDownloadPlatformService) { 1.46 + gDownloadPlatformService = new DownloadPlatform(); 1.47 + } 1.48 + 1.49 + NS_ADDREF(gDownloadPlatformService); 1.50 + 1.51 +#if defined(MOZ_WIDGET_GTK) 1.52 + g_type_init(); 1.53 +#endif 1.54 + 1.55 + return gDownloadPlatformService; 1.56 +} 1.57 + 1.58 +#ifdef MOZ_ENABLE_GIO 1.59 +static void gio_set_metadata_done(GObject *source_obj, GAsyncResult *res, gpointer user_data) 1.60 +{ 1.61 + GError *err = nullptr; 1.62 + g_file_set_attributes_finish(G_FILE(source_obj), res, nullptr, &err); 1.63 + if (err) { 1.64 +#ifdef DEBUG 1.65 + NS_DebugBreak(NS_DEBUG_WARNING, "Set file metadata failed: ", err->message, __FILE__, __LINE__); 1.66 +#endif 1.67 + g_error_free(err); 1.68 + } 1.69 +} 1.70 +#endif 1.71 + 1.72 +nsresult DownloadPlatform::DownloadDone(nsIURI* aSource, nsIFile* aTarget, 1.73 + const nsACString& aContentType, bool aIsPrivate) 1.74 +{ 1.75 +#if defined(XP_WIN) || defined(XP_MACOSX) || defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GTK) 1.76 + nsAutoString path; 1.77 + if (aTarget && NS_SUCCEEDED(aTarget->GetPath(path))) { 1.78 +#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK) 1.79 + // On Windows and Gtk, add the download to the system's "recent documents" 1.80 + // list, with a pref to disable. 1.81 + { 1.82 + bool addToRecentDocs = Preferences::GetBool(PREF_BDM_ADDTORECENTDOCS); 1.83 + if (addToRecentDocs && !aIsPrivate) { 1.84 +#ifdef XP_WIN 1.85 + ::SHAddToRecentDocs(SHARD_PATHW, path.get()); 1.86 +#elif defined(MOZ_WIDGET_GTK) 1.87 + GtkRecentManager* manager = gtk_recent_manager_get_default(); 1.88 + 1.89 + gchar* uri = g_filename_to_uri(NS_ConvertUTF16toUTF8(path).get(), 1.90 + nullptr, nullptr); 1.91 + if (uri) { 1.92 + gtk_recent_manager_add_item(manager, uri); 1.93 + g_free(uri); 1.94 + } 1.95 +#endif 1.96 + } 1.97 +#ifdef MOZ_ENABLE_GIO 1.98 + // Use GIO to store the source URI for later display in the file manager. 1.99 + GFile* gio_file = g_file_new_for_path(NS_ConvertUTF16toUTF8(path).get()); 1.100 + nsCString source_uri; 1.101 + aSource->GetSpec(source_uri); 1.102 + GFileInfo *file_info = g_file_info_new(); 1.103 + g_file_info_set_attribute_string(file_info, "metadata::download-uri", source_uri.get()); 1.104 + g_file_set_attributes_async(gio_file, 1.105 + file_info, 1.106 + G_FILE_QUERY_INFO_NONE, 1.107 + G_PRIORITY_DEFAULT, 1.108 + nullptr, gio_set_metadata_done, nullptr); 1.109 + g_object_unref(file_info); 1.110 + g_object_unref(gio_file); 1.111 +#endif 1.112 + } 1.113 +#endif 1.114 +#ifdef XP_MACOSX 1.115 + // On OS X, make the downloads stack bounce. 1.116 + CFStringRef observedObject = ::CFStringCreateWithCString(kCFAllocatorDefault, 1.117 + NS_ConvertUTF16toUTF8(path).get(), 1.118 + kCFStringEncodingUTF8); 1.119 + CFNotificationCenterRef center = ::CFNotificationCenterGetDistributedCenter(); 1.120 + ::CFNotificationCenterPostNotification(center, CFSTR("com.apple.DownloadFileFinished"), 1.121 + observedObject, nullptr, TRUE); 1.122 + ::CFRelease(observedObject); 1.123 +#endif 1.124 +#ifdef MOZ_WIDGET_ANDROID 1.125 + if (!aContentType.IsEmpty()) { 1.126 + mozilla::widget::android::GeckoAppShell::ScanMedia(path, NS_ConvertUTF8toUTF16(aContentType)); 1.127 + } 1.128 +#endif 1.129 + } 1.130 + 1.131 +#ifdef XP_WIN 1.132 + // Adjust file attributes so that by default, new files are indexed by 1.133 + // desktop search services. Skip off those that land in the temp folder. 1.134 + nsCOMPtr<nsIFile> tempDir, fileDir; 1.135 + nsresult rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(tempDir)); 1.136 + NS_ENSURE_SUCCESS(rv, rv); 1.137 + aTarget->GetParent(getter_AddRefs(fileDir)); 1.138 + 1.139 + bool isTemp = false; 1.140 + if (fileDir) { 1.141 + fileDir->Equals(tempDir, &isTemp); 1.142 + } 1.143 + 1.144 + nsCOMPtr<nsILocalFileWin> localFileWin(do_QueryInterface(aTarget)); 1.145 + if (!isTemp && localFileWin) { 1.146 + localFileWin->SetFileAttributesWin(nsILocalFileWin::WFA_SEARCH_INDEXED); 1.147 + } 1.148 +#endif 1.149 + 1.150 +#endif 1.151 + 1.152 + return NS_OK; 1.153 +} 1.154 + 1.155 +nsresult DownloadPlatform::MapUrlToZone(const nsAString& aURL, 1.156 + uint32_t* aZone) 1.157 +{ 1.158 +#ifdef XP_WIN 1.159 + nsRefPtr<IInternetSecurityManager> inetSecMgr; 1.160 + if (FAILED(CoCreateInstance(CLSID_InternetSecurityManager, NULL, 1.161 + CLSCTX_ALL, IID_IInternetSecurityManager, 1.162 + getter_AddRefs(inetSecMgr)))) { 1.163 + return NS_ERROR_UNEXPECTED; 1.164 + } 1.165 + 1.166 + DWORD zone; 1.167 + if (inetSecMgr->MapUrlToZone(PromiseFlatString(aURL).get(), 1.168 + &zone, 0) != S_OK) { 1.169 + return NS_ERROR_UNEXPECTED; 1.170 + } else { 1.171 + *aZone = zone; 1.172 + } 1.173 + 1.174 + return NS_OK; 1.175 +#else 1.176 + return NS_ERROR_NOT_IMPLEMENTED; 1.177 +#endif 1.178 +}