Bug 1072535 - Pt 1 - Have DownloadDone notify device storage when a new download is available. r=paolo
authorDave Hylands <dhylands@mozilla.com>
Tue, 14 Oct 2014 13:50:57 -0700
changeset 210382 9d0bba1b36dd24bb2441ff05aa846268b66850e9
parent 210381 902dfed4c12076349367d7c05c62f0150e91b819
child 210383 6bc1d826fc4f500d691d01de45f153aeea3e24bf
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewerspaolo
bugs1072535
milestone36.0a1
Bug 1072535 - Pt 1 - Have DownloadDone notify device storage when a new download is available. r=paolo
toolkit/components/jsdownloads/src/DownloadPlatform.cpp
toolkit/components/jsdownloads/test/unit/common_test_Download.js
--- 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);
   }
 });