Bug 722995 - DownloadLastDir.jsm uses global Private Browsing state to make decisions, r=ehsan
authorSaurabh Anand <saurabhanandiit@gmail.com>
Sat, 21 Jul 2012 11:25:37 +0530
changeset 100019 8b28f53415fe403823ca428dde1c9c675aceb963
parent 100018 73f73097fb1a93cd0ae6349f42ecfc2edcaa4881
child 100020 e9e2767a427556247a18d841e73ba58d24bc5d95
push id12300
push userkwierso@gmail.com
push dateSat, 21 Jul 2012 06:38:36 +0000
treeherdermozilla-inbound@8b28f53415fe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs722995
milestone17.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 722995 - DownloadLastDir.jsm uses global Private Browsing state to make decisions, r=ehsan
toolkit/content/contentAreaUtils.js
toolkit/mozapps/downloads/DownloadLastDir.jsm
toolkit/mozapps/downloads/nsHelperAppDlg.js
--- a/toolkit/content/contentAreaUtils.js
+++ b/toolkit/content/contentAreaUtils.js
@@ -1,9 +1,9 @@
-# -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- 
+# -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- 
 # This Source Code Form is subject to the terms of the Mozilla Public
 # 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/.
 
 var ContentAreaUtils = {
   get ioService() {
     delete this.ioService;
     return this.ioService =
@@ -426,17 +426,17 @@ function internalPersist(persistArgs)
                     targetFileURL);
   }
 }
 
 /**
  * Structure for holding info about automatically supplied parameters for
  * internalSave(...). This allows parameters to be supplied so the user does not
  * need to be prompted for file info.
- * @param aFileAutoChosen This is an nsILocalFile object that has been
+ * @param aFileAutoChosen This is an nsIFile object that has been
  *        pre-determined as the filename for the target to save to
  * @param aUriAutoChosen  This is the nsIURI object for the target
  */
 function AutoChosen(aFileAutoChosen, aUriAutoChosen) {
   this.file = aFileAutoChosen;
   this.uri  = aUriAutoChosen;
 }
 
@@ -520,23 +520,23 @@ function initFileInfo(aFI, aURL, aURLCha
  *        An nsIURI associated with the download. The last used
  *        directory of the picker is retrieved from/stored in the 
  *        Content Pref Service using this URI.
  * @return true if the user confirmed a filename in the picker or the picker
  *         was not displayed; false if they dismissed the picker.
  */
 function getTargetFile(aFpP, /* optional */ aSkipPrompt, /* optional */ aRelatedURI)
 {
-  if (!getTargetFile.gDownloadLastDir)
-    Components.utils.import("resource://gre/modules/DownloadLastDir.jsm", getTargetFile);
-  var gDownloadLastDir = getTargetFile.gDownloadLastDir;
+  let downloadModule = {};
+  Components.utils.import("resource://gre/modules/DownloadLastDir.jsm", downloadModule);
+  var gDownloadLastDir = new downloadModule.DownloadLastDir(window);
 
   var prefs = getPrefsBrowserDownload("browser.download.");
   var useDownloadDir = prefs.getBoolPref("useDownloadDir");
-  const nsILocalFile = Components.interfaces.nsILocalFile;
+  const nsIFile = Components.interfaces.nsIFile;
 
   if (!aSkipPrompt)
     useDownloadDir = false;
 
   // Default to the user's default downloads directory configured
   // through download prefs.
   var dlMgr = Components.classes["@mozilla.org/download-manager;1"]
                         .getService(Components.interfaces.nsIDownloadManager);
@@ -563,17 +563,17 @@ function getTargetFile(aFpP, /* optional
       dirExists = true;
     }
   } catch(e) {}
 
   if (!dirExists) {
     // Default to desktop.
     var fileLocator = Components.classes["@mozilla.org/file/directory_service;1"]
                                 .getService(Components.interfaces.nsIProperties);
-    dir = fileLocator.get("Desk", nsILocalFile);
+    dir = fileLocator.get("Desk", nsIFile);
   }
 
   var fp = makeFilePicker();
   var titleKey = aFpP.fpTitleKey || "SaveLinkTitle";
   fp.init(window, ContentAreaUtils.stringBundle.GetStringFromName(titleKey),
           Components.interfaces.nsIFilePicker.modeSave);
 
   fp.displayDirectory = dir;
@@ -595,21 +595,21 @@ function getTargetFile(aFpP, /* optional
 
   if (fp.show() == Components.interfaces.nsIFilePicker.returnCancel || !fp.file)
     return false;
 
   if (aFpP.saveMode != SAVEMODE_FILEONLY)
     prefs.setIntPref("save_converter_index", fp.filterIndex);
 
   // Do not store the last save directory as a pref inside the private browsing mode
-  var directory = fp.file.parent.QueryInterface(nsILocalFile);
+  var directory = fp.file.parent.QueryInterface(nsIFile);
   gDownloadLastDir.setFile(aRelatedURI, directory);
 
   fp.file.leafName = validateFileName(fp.file.leafName);
-  
+
   aFpP.saveAsType = fp.filterIndex;
   aFpP.file = fp.file;
   aFpP.fileURL = fp.fileURL;
   return true;
 }
 
 // Since we're automatically downloading, we don't get the file picker's
 // logic to check for existing files, so we need to do that here.
--- a/toolkit/mozapps/downloads/DownloadLastDir.jsm
+++ b/toolkit/mozapps/downloads/DownloadLastDir.jsm
@@ -1,8 +1,9 @@
+/* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * 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/. */
 
 /*
  * The behavior implemented by gDownloadLastDir is documented here.
  *
  * In normal browsing sessions, gDownloadLastDir uses the browser.download.lastDir
@@ -20,114 +21,118 @@
  *
  * If passed a URI, the last used directory is also stored with that URI in the
  * content preferences database. This can be disabled by setting the pref
  * browser.download.lastDir.savePerSite to false.
  */
 
 const LAST_DIR_PREF = "browser.download.lastDir";
 const SAVE_PER_SITE_PREF = LAST_DIR_PREF + ".savePerSite";
-const PBSVC_CID = "@mozilla.org/privatebrowsing;1";
-const nsILocalFile = Components.interfaces.nsILocalFile;
+const nsIFile = Components.interfaces.nsIFile;
 
-var EXPORTED_SYMBOLS = [ "gDownloadLastDir" ];
+var EXPORTED_SYMBOLS = [ "DownloadLastDir" ];
 
 Components.utils.import("resource://gre/modules/Services.jsm");
-
-let pbSvc = null;
-if (PBSVC_CID in Components.classes) {
-  pbSvc = Components.classes[PBSVC_CID]
-                    .getService(Components.interfaces.nsIPrivateBrowsingService);
-}
+Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
 
 let observer = {
   QueryInterface: function (aIID) {
     if (aIID.equals(Components.interfaces.nsIObserver) ||
         aIID.equals(Components.interfaces.nsISupports) ||
         aIID.equals(Components.interfaces.nsISupportsWeakReference))
       return this;
     throw Components.results.NS_NOINTERFACE;
   },
   observe: function (aSubject, aTopic, aData) {
     switch (aTopic) {
-      case "private-browsing":
-        if (aData == "enter")
-          gDownloadLastDirFile = readLastDirPref();
-        else if (aData == "exit") {
-          gDownloadLastDirFile = null;
-        }
+      case "last-pb-context-exited":
+        gDownloadLastDirFile = null;
         break;
       case "browser:purge-session-history":
         gDownloadLastDirFile = null;
         if (Services.prefs.prefHasUserValue(LAST_DIR_PREF))
           Services.prefs.clearUserPref(LAST_DIR_PREF);
         Services.contentPrefs.removePrefsByName(LAST_DIR_PREF);
         break;
     }
   }
 };
 
 let os = Components.classes["@mozilla.org/observer-service;1"]
                    .getService(Components.interfaces.nsIObserverService);
-os.addObserver(observer, "private-browsing", true);
+os.addObserver(observer, "last-pb-context-exited", true);
 os.addObserver(observer, "browser:purge-session-history", true);
 
 function readLastDirPref() {
   try {
-    return Services.prefs.getComplexValue(LAST_DIR_PREF, nsILocalFile);
+    return Services.prefs.getComplexValue(LAST_DIR_PREF, nsIFile);
   }
   catch (e) {
     return null;
   }
 }
 
 function isContentPrefEnabled() {
   try {
     return Services.prefs.getBoolPref(SAVE_PER_SITE_PREF);
-  } 
+  }
   catch (e) {
     return true;
   }
 }
 
 let gDownloadLastDirFile = readLastDirPref();
-let gDownloadLastDir = {
+
+function DownloadLastDir(aWindow) {
+  this.window = aWindow;
+}
+
+DownloadLastDir.prototype = {
+  isPrivate: function DownloadLastDir_isPrivate() {
+    return PrivateBrowsingUtils.isWindowPrivate(this.window);
+  },
   // compat shims
   get file() { return this.getFile(); },
   set file(val) { this.setFile(null, val); },
+  cleanupPrivateFile: function () {
+    gDownloadLastDirFile = null;
+  },
   getFile: function (aURI) {
     if (aURI && isContentPrefEnabled()) {
       let lastDir = Services.contentPrefs.getPref(aURI, LAST_DIR_PREF);
       if (lastDir) {
         var lastDirFile = Components.classes["@mozilla.org/file/local;1"]
-                                    .createInstance(Components.interfaces.nsILocalFile);
+                                    .createInstance(Components.interfaces.nsIFile);
         lastDirFile.initWithPath(lastDir);
         return lastDirFile;
       }
     }
     if (gDownloadLastDirFile && !gDownloadLastDirFile.exists())
       gDownloadLastDirFile = null;
 
-    if (pbSvc && pbSvc.privateBrowsingEnabled)
+    if (this.isPrivate()) {
+      if (!gDownloadLastDirFile)
+        gDownloadLastDirFile = readLastDirPref();
       return gDownloadLastDirFile;
+    }
     else
       return readLastDirPref();
   },
   setFile: function (aURI, aFile) {
     if (aURI && isContentPrefEnabled()) {
       if (aFile instanceof Components.interfaces.nsIFile)
         Services.contentPrefs.setPref(aURI, LAST_DIR_PREF, aFile.path);
       else
         Services.contentPrefs.removePref(aURI, LAST_DIR_PREF);
     }
-    if (pbSvc && pbSvc.privateBrowsingEnabled) {
+    if (this.isPrivate()) {
       if (aFile instanceof Components.interfaces.nsIFile)
         gDownloadLastDirFile = aFile.clone();
       else
         gDownloadLastDirFile = null;
     } else {
       if (aFile instanceof Components.interfaces.nsIFile)
-        Services.prefs.setComplexValue(LAST_DIR_PREF, nsILocalFile, aFile);
+        Services.prefs.setComplexValue(LAST_DIR_PREF, nsIFile, aFile);
       else if (Services.prefs.prefHasUserValue(LAST_DIR_PREF))
         Services.prefs.clearUserPref(LAST_DIR_PREF);
     }
   }
 };
--- a/toolkit/mozapps/downloads/nsHelperAppDlg.js
+++ b/toolkit/mozapps/downloads/nsHelperAppDlg.js
@@ -1,9 +1,9 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: javascript; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /*
 # This Source Code Form is subject to the terms of the Mozilla Public
 # 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/.
 */
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -92,18 +92,19 @@ nsUnknownContentTypeDialogProgressListen
  *
  * In addition, this file implements an nsIModule object that registers the
  * nsUnknownContentTypeDialog component.
  */
 
 const PREF_BD_USEDOWNLOADDIR = "browser.download.useDownloadDir";
 const nsITimer = Components.interfaces.nsITimer;
 
+let downloadModule = {};
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-Components.utils.import("resource://gre/modules/DownloadLastDir.jsm");
+Components.utils.import("resource://gre/modules/DownloadLastDir.jsm", downloadModule);
 Components.utils.import("resource://gre/modules/DownloadPaths.jsm");
 Components.utils.import("resource://gre/modules/DownloadUtils.jsm");
 
 /* ctor
  */
 function nsUnknownContentTypeDialog() {
   // Initialize data properties.
   this.mLauncher = null;
@@ -240,16 +241,18 @@ nsUnknownContentTypeDialog.prototype = {
     // Use file picker to show dialog.
     var nsIFilePicker = Components.interfaces.nsIFilePicker;
     var picker = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
     var windowTitle = bundle.GetStringFromName("saveDialogTitle");
     var parent = aContext.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIDOMWindow);
     picker.init(parent, windowTitle, nsIFilePicker.modeSave);
     picker.defaultString = aDefaultFile;
 
+    let gDownloadLastDir = new downloadModule.DownloadLastDir(parent);
+
     if (aSuggestedFileExtension) {
       // aSuggestedFileExtension includes the period, so strip it
       picker.defaultExtension = aSuggestedFileExtension.substring(1);
     }
     else {
       try {
         picker.defaultExtension = this.mLauncher.MIMEInfo.primaryExtension;
       }