Bug 722983 - Fix the back-end handling of permanent private browsing mode through the per-window private browsing APIs; r=jdm
authorEhsan Akhgari <ehsan@mozilla.com>
Tue, 16 Oct 2012 18:06:38 -0400
changeset 110607 2dc84b223c276efec569468ac59e87fc20f9c109
parent 110606 21c42ad33eca5969585560dbc7b28fdc5cb4b10c
child 110608 3dc836fcff4316cdb9bc697feb1a384c12e060f1
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
reviewersjdm
bugs722983
milestone19.0a1
Bug 722983 - Fix the back-end handling of permanent private browsing mode through the per-window private browsing APIs; r=jdm
browser/components/preferences/jar.mn
browser/components/preferences/privacy.js
embedding/components/windowwatcher/src/nsWindowWatcher.cpp
toolkit/content/PrivateBrowsingUtils.jsm
xpfe/appshell/src/nsAppShellService.cpp
--- a/browser/components/preferences/jar.mn
+++ b/browser/components/preferences/jar.mn
@@ -28,17 +28,17 @@ browser.jar:
 *   content/browser/preferences/languages.xul
     content/browser/preferences/languages.js
 *   content/browser/preferences/main.xul
     content/browser/preferences/main.js
 *   content/browser/preferences/permissions.xul
     content/browser/preferences/permissions.js
 *   content/browser/preferences/preferences.xul
     content/browser/preferences/privacy.xul
-    content/browser/preferences/privacy.js
+*   content/browser/preferences/privacy.js
     content/browser/preferences/sanitize.xul
     content/browser/preferences/security.xul
     content/browser/preferences/security.js
     content/browser/preferences/selectBookmark.xul
     content/browser/preferences/selectBookmark.js
 #ifdef MOZ_SERVICES_SYNC
     content/browser/preferences/sync.xul
     content/browser/preferences/sync.js
--- a/browser/components/preferences/privacy.js
+++ b/browser/components/preferences/privacy.js
@@ -217,28 +217,32 @@ var gPrivacyPane = {
   },
 
   autoStartPrivateBrowsingObserver:
   {
     QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsIObserver]),
 
     observe: function PPP_observe(aSubject, aTopic, aData)
     {
-      let privateBrowsingService = Components.classes["@mozilla.org/privatebrowsing;1"].
-        getService(Components.interfaces.nsIPrivateBrowsingService);
-
       // Toggle the private browsing mode without switching the session
       let prefValue = document.getElementById("browser.privatebrowsing.autostart").value;
       let keepCurrentSession = document.getElementById("browser.privatebrowsing.keep_current_session");
       keepCurrentSession.value = true;
+
+#ifndef MOZ_PER_WINDOW_PRIVATE_BROWSING
+      let privateBrowsingService = Components.classes["@mozilla.org/privatebrowsing;1"].
+        getService(Components.interfaces.nsIPrivateBrowsingService);
+
       // If activating from within the private browsing mode, reset the
       // private session
       if (prefValue && privateBrowsingService.privateBrowsingEnabled)
         privateBrowsingService.privateBrowsingEnabled = false;
       privateBrowsingService.privateBrowsingEnabled = prefValue;
+#endif
+
       keepCurrentSession.reset();
     }
   },
 
   // HISTORY
 
   /**
    * Read the location bar enabled and suggestion prefs
--- a/embedding/components/windowwatcher/src/nsWindowWatcher.cpp
+++ b/embedding/components/windowwatcher/src/nsWindowWatcher.cpp
@@ -54,16 +54,17 @@
 #include "nsIWidget.h"
 #include "nsFocusManager.h"
 #include "nsIPresShell.h"
 #include "nsPresContext.h"
 #include "nsContentUtils.h"
 #include "nsIPrefBranch.h"
 #include "nsIPrefService.h"
 #include "nsSandboxFlags.h"
+#include "mozilla/Preferences.h"
 
 #ifdef USEWEAKREFS
 #include "nsIWeakReference.h"
 #endif
 
 using namespace mozilla;
 
 static const char *sJSStackContractID="@mozilla.org/js/xpc/ContextStack;1";
@@ -893,18 +894,20 @@ nsWindowWatcher::OpenWindowInternal(nsID
     // this call already happened when the window was created, but
     // SetInitialPrincipalToSubject is safe to call multiple times.
     if (newWindow) {
       newWindow->SetInitialPrincipalToSubject();
     }
   }
 
   if (windowIsNew) {
-    // See if the caller has requested a private browsing window.
+    // See if the caller has requested a private browsing window, or if all
+    // windows should be private.
     bool isPrivateBrowsingWindow =
+      Preferences::GetBool("browser.privatebrowsing.autostart") ||
       !!(chromeFlags & nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW);
     // Otherwise, propagate the privacy status of the parent window, if
     // available, to the child.
     if (!isPrivateBrowsingWindow) {
       nsCOMPtr<nsIDocShellTreeItem> parentItem;
       GetWindowTreeItem(aParent, getter_AddRefs(parentItem));
       nsCOMPtr<nsILoadContext> parentContext = do_QueryInterface(parentItem);
       if (parentContext) {
--- a/toolkit/content/PrivateBrowsingUtils.jsm
+++ b/toolkit/content/PrivateBrowsingUtils.jsm
@@ -1,31 +1,52 @@
 /* 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 EXPORTED_SYMBOLS = ["PrivateBrowsingUtils"];
 
+Components.utils.import("resource://gre/modules/Services.jsm");
+
+const kAutoStartPref = "browser.components.autostart";
+
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 
 var PrivateBrowsingUtils = {
   isWindowPrivate: function pbu_isWindowPrivate(aWindow) {
     return aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
                   .getInterface(Ci.nsIWebNavigation)
                   .QueryInterface(Ci.nsILoadContext)
                   .usePrivateBrowsing;
   },
 
   get permanentPrivateBrowsing() {
 #ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
-    return false; // permanent PB is not supported for now
+    return Services.prefs.getBoolPref(kAutoStart, false);
 #else
     try {
       return Cc["@mozilla.org/privatebrowsing;1"].
              getService(Ci.nsIPrivateBrowsingService).
              autoStarted;
     } catch (e) {
       return false; // PB not supported
     }
 #endif
   }
 };
+
+#ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
+function autoStartObserver(aSubject, aTopic, aData) {
+  var newValue = Services.prefs.getBoolPref(kAutoStart);
+  var windowsEnum = Services.wm.getEnumerator(null);
+  while (windowsEnum.hasMoreElements()) {
+    var window = windowsEnum.getNext();
+    window.QueryInterface(Ci.nsIInterfaceRequestor)
+          .getInterface(Ci.nsIWebNavigation)
+          .QueryInterface(Ci.nsILoadContext)
+          .usePrivateBrowsing = newValue;
+  }
+}
+
+Services.prefs.addObserver(kAutoStartPref, autoStartObserver, false);
+#endif
+
--- a/xpfe/appshell/src/nsAppShellService.cpp
+++ b/xpfe/appshell/src/nsAppShellService.cpp
@@ -349,28 +349,36 @@ nsAppShellService::JustCreateTopWindow(n
   }
 
   nsresult rv = window->Initialize(parent, center ? aParent : nullptr,
                                    aUrl, aInitialWidth, aInitialHeight,
                                    aIsHiddenWindow, widgetInitData);
 
   NS_ENSURE_SUCCESS(rv, rv);
 
-  // Ensure that we propagate any existing private browsing status
-  // from the parent, even if it will not actually be used
-  // as a parent value.
-  nsCOMPtr<nsIDOMWindow> domWin = do_GetInterface(aParent);
-  nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(domWin);
-  nsCOMPtr<nsILoadContext> parentContext = do_QueryInterface(webNav);
+  // Enforce the Private Browsing autoStart pref first.
+  bool isPrivateBrowsingWindow =
+    Preferences::GetBool("browser.privatebrowsing.autostart");
+  if (!isPrivateBrowsingWindow) {
+    // Ensure that we propagate any existing private browsing status
+    // from the parent, even if it will not actually be used
+    // as a parent value.
+    nsCOMPtr<nsIDOMWindow> domWin = do_GetInterface(aParent);
+    nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(domWin);
+    nsCOMPtr<nsILoadContext> parentContext = do_QueryInterface(webNav);
+    if (parentContext) {
+      isPrivateBrowsingWindow = parentContext->UsePrivateBrowsing();
+    }
+  }
   nsCOMPtr<nsIDOMWindow> newDomWin =
       do_GetInterface(NS_ISUPPORTS_CAST(nsIBaseWindow*, window));
   nsCOMPtr<nsIWebNavigation> newWebNav = do_GetInterface(newDomWin);
   nsCOMPtr<nsILoadContext> thisContext = do_GetInterface(newWebNav);
-  if (parentContext && thisContext) {
-    thisContext->SetUsePrivateBrowsing(parentContext->UsePrivateBrowsing());
+  if (thisContext) {
+    thisContext->SetUsePrivateBrowsing(isPrivateBrowsingWindow);
   }
 
   window.swap(*aResult); // transfer reference
   if (parent)
     parent->AddChildWindow(*aResult);
 
   if (center)
     rv = (*aResult)->Center(parent, parent ? false : true, false);