Bug 1072535 - Pt 1 - Have DownloadDone notify device storage when a new download is available. r=paolo
--- a/toolkit/components/jsdownloads/src/DownloadPlatform.cpp
+++ b/toolkit/components/jsdownloads/src/DownloadPlatform.cpp
@@ -2,19 +2,22 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "DownloadPlatform.h"
#include "nsAutoPtr.h"
#include "nsString.h"
#include "nsIURI.h"
#include "nsIFile.h"
+#include "nsIObserverService.h"
+#include "nsISupportsPrimitives.h"
#include "nsDirectoryServiceDefs.h"
#include "mozilla/Preferences.h"
+#include "mozilla/Services.h"
#define PREF_BDM_ADDTORECENTDOCS "browser.download.manager.addToRecentDocs"
#ifdef XP_WIN
#include <shlobj.h>
#include <urlmon.h>
#include "nsILocalFileWin.h"
#endif
@@ -64,17 +67,19 @@ static void gio_set_metadata_done(GObjec
g_error_free(err);
}
}
#endif
nsresult DownloadPlatform::DownloadDone(nsIURI* aSource, nsIFile* aTarget,
const nsACString& aContentType, bool aIsPrivate)
{
-#if defined(XP_WIN) || defined(XP_MACOSX) || defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GTK)
+#if defined(XP_WIN) || defined(XP_MACOSX) || defined(MOZ_WIDGET_ANDROID) \
+ || defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_GONK)
+
nsAutoString path;
if (aTarget && NS_SUCCEEDED(aTarget->GetPath(path))) {
#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_ANDROID)
// On Windows and Gtk, add the download to the system's "recent documents"
// list, with a pref to disable.
{
bool addToRecentDocs = Preferences::GetBool(PREF_BDM_ADDTORECENTDOCS);
if (addToRecentDocs && !aIsPrivate) {
@@ -115,16 +120,28 @@ nsresult DownloadPlatform::DownloadDone(
CFStringRef observedObject = ::CFStringCreateWithCString(kCFAllocatorDefault,
NS_ConvertUTF16toUTF8(path).get(),
kCFStringEncodingUTF8);
CFNotificationCenterRef center = ::CFNotificationCenterGetDistributedCenter();
::CFNotificationCenterPostNotification(center, CFSTR("com.apple.DownloadFileFinished"),
observedObject, nullptr, TRUE);
::CFRelease(observedObject);
#endif
+ if (mozilla::Preferences::GetBool("device.storage.enabled", true)) {
+ // Tell DeviceStorage that a new file may have been added.
+ nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
+ nsCOMPtr<nsISupportsString> pathString
+ = do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID);
+ if (obs && pathString) {
+ if (NS_SUCCEEDED(pathString->SetData(path))) {
+ (void)obs->NotifyObservers(pathString, "download-watcher-notify",
+ MOZ_UTF16("modified"));
+ }
+ }
+ }
}
#ifdef XP_WIN
// Adjust file attributes so that by default, new files are indexed by
// desktop search services. Skip off those that land in the temp folder.
nsCOMPtr<nsIFile> tempDir, fileDir;
nsresult rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(tempDir));
NS_ENSURE_SUCCESS(rv, rv);
--- a/toolkit/components/jsdownloads/test/unit/common_test_Download.js
+++ b/toolkit/components/jsdownloads/test/unit/common_test_Download.js
@@ -1728,20 +1728,38 @@ add_task(function test_toSerializable_st
/**
* This test will call the platform specific operations within
* DownloadPlatform::DownloadDone. While there is no test to verify the
* specific behaviours, this at least ensures that there is no error or crash.
*/
add_task(function test_platform_integration()
{
let downloadFiles = [];
+ let oldDeviceStorageEnabled = false;
+ try {
+ oldDeviceStorageEnabled = Services.prefs.getBoolPref("device.storage.enabled");
+ } catch (e) {
+ // This happens if the pref doesn't exist.
+ }
+ let downloadWatcherNotified = false;
+ let observer = {
+ observe: function(subject, topic, data) {
+ do_check_eq(topic, "download-watcher-notify");
+ do_check_eq(data, "modified");
+ downloadWatcherNotified = true;
+ }
+ }
+ Services.obs.addObserver(observer, "download-watcher-notify", false);
+ Services.prefs.setBoolPref("device.storage.enabled", true);
function cleanup() {
for (let file of downloadFiles) {
file.remove(true);
}
+ Services.obs.removeObserver(observer, "download-watcher-notify");
+ Services.prefs.setBoolPref("device.storage.enabled", oldDeviceStorageEnabled);
}
do_register_cleanup(cleanup);
for (let isPrivate of [false, true]) {
DownloadIntegration.downloadDoneCalled = false;
// Some platform specific operations only operate on files outside the
// temporary directory or in the Downloads directory (such as setting
@@ -1765,16 +1783,17 @@ add_task(function test_platform_integrat
});
download.start();
}
// Wait for the whenSucceeded promise to be resolved first.
// downloadDone should be called before the whenSucceeded promise is resolved.
yield download.whenSucceeded().then(function () {
do_check_true(DownloadIntegration.downloadDoneCalled);
+ do_check_true(downloadWatcherNotified);
});
// Then, wait for the promise returned by "start" to be resolved.
yield promiseDownloadStopped(download);
yield promiseVerifyContents(download.target.path, TEST_DATA_SHORT);
}
});