Bug 800193 - Print a warning when setting nsILoadContext.usePrivateBrowsing in per-window private browsing builds; r=bzbarsky
authorEhsan Akhgari <ehsan@mozilla.com>
Wed, 31 Oct 2012 00:15:24 -0400
changeset 120213 b940cf5510198615c1f2fef347497de6d23774dc
parent 120212 aca558fd4bfb19d70648e5ff7b54be348ffa097e
child 120214 a370aa5720c424886b81747543a16004cabc49f5
push id1997
push userakeybl@mozilla.com
push dateMon, 07 Jan 2013 21:25:26 +0000
treeherdermozilla-beta@4baf45cdcf21 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbzbarsky
bugs800193
milestone19.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 800193 - Print a warning when setting nsILoadContext.usePrivateBrowsing in per-window private browsing builds; r=bzbarsky
content/base/public/nsContentUtils.h
content/base/src/nsContentUtils.cpp
docshell/base/LoadContext.cpp
docshell/base/nsDocShell.cpp
docshell/base/nsDocShell.h
docshell/base/nsILoadContext.idl
embedding/components/windowwatcher/src/nsWindowWatcher.cpp
uriloader/prefetch/OfflineCacheUpdateParent.cpp
xpfe/appshell/src/nsAppShellService.cpp
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -747,16 +747,41 @@ public:
    * Return the nsIXPConnect service.
    */
   static nsIXPConnect *XPConnect()
   {
     return sXPConnect;
   }
 
   /**
+   * Report a non-localized error message to the error console.
+   *   @param aErrorText the error message
+   *   @param aErrorFlags See nsIScriptError.
+   *   @param aCategory Name of module reporting error.
+   *   @param aDocument Reference to the document which triggered the message.
+   *   @param [aURI=nullptr] (Optional) URI of resource containing error.
+   *   @param [aSourceLine=EmptyString()] (Optional) The text of the line that
+              contains the error (may be empty).
+   *   @param [aLineNumber=0] (Optional) Line number within resource
+              containing error.
+   *   @param [aColumnNumber=0] (Optional) Column number within resource
+              containing error.
+              If aURI is null, then aDocument->GetDocumentURI() is used.
+   */
+  static nsresult ReportToConsoleNonLocalized(const nsAString& aErrorText,
+                                              uint32_t aErrorFlags,
+                                              const char *aCategory,
+                                              nsIDocument* aDocument,
+                                              nsIURI* aURI = nullptr,
+                                              const nsAFlatString& aSourceLine
+                                                = EmptyString(),
+                                              uint32_t aLineNumber = 0,
+                                              uint32_t aColumnNumber = 0);
+
+  /**
    * Report a localized error message to the error console.
    *   @param aErrorFlags See nsIScriptError.
    *   @param aCategory Name of module reporting error.
    *   @param aDocument Reference to the document which triggered the message.
    *   @param aFile Properties file containing localized message.
    *   @param aMessageName Name of localized message.
    *   @param [aParams=nullptr] (Optional) Parameters to be substituted into
               localized message.
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -3209,40 +3209,57 @@ nsContentUtils::ReportToConsole(uint32_t
                                 const nsAFlatString& aSourceLine,
                                 uint32_t aLineNumber,
                                 uint32_t aColumnNumber)
 {
   NS_ASSERTION((aParams && aParamsLength) || (!aParams && !aParamsLength),
                "Supply either both parameters and their number or no"
                "parameters and 0.");
 
+  nsresult rv;
+  nsXPIDLString errorText;
+  if (aParams) {
+    rv = FormatLocalizedString(aFile, aMessageName, aParams, aParamsLength,
+                               errorText);
+  }
+  else {
+    rv = GetLocalizedString(aFile, aMessageName, errorText);
+  }
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  return ReportToConsoleNonLocalized(errorText, aErrorFlags, aCategory,
+                                     aDocument, aURI, aSourceLine,
+                                     aLineNumber, aColumnNumber);
+}
+
+
+/* static */ nsresult
+nsContentUtils::ReportToConsoleNonLocalized(const nsAString& aErrorText,
+                                            uint32_t aErrorFlags,
+                                            const char *aCategory,
+                                            nsIDocument* aDocument,
+                                            nsIURI* aURI,
+                                            const nsAFlatString& aSourceLine,
+                                            uint32_t aLineNumber,
+                                            uint32_t aColumnNumber)
+{
   uint64_t innerWindowID = 0;
   if (aDocument) {
     if (!aURI) {
       aURI = aDocument->GetDocumentURI();
     }
     innerWindowID = aDocument->InnerWindowID();
   }
 
   nsresult rv;
   if (!sConsoleService) { // only need to bother null-checking here
     rv = CallGetService(NS_CONSOLESERVICE_CONTRACTID, &sConsoleService);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
-  nsXPIDLString errorText;
-  if (aParams) {
-    rv = FormatLocalizedString(aFile, aMessageName, aParams, aParamsLength,
-                               errorText);
-  }
-  else {
-    rv = GetLocalizedString(aFile, aMessageName, errorText);
-  }
-  NS_ENSURE_SUCCESS(rv, rv);
-
   nsAutoCString spec;
   if (!aLineNumber) {
     JSContext *cx = nullptr;
     sThreadJSContextStack->Peek(&cx);
     if (cx) {
       const char* filename;
       uint32_t lineno;
       if (nsJSUtils::GetCallingLocation(cx, &filename, &lineno)) {
@@ -3253,17 +3270,17 @@ nsContentUtils::ReportToConsole(uint32_t
   }
   if (spec.IsEmpty() && aURI)
     aURI->GetSpec(spec);
 
   nsCOMPtr<nsIScriptError> errorObject =
       do_CreateInstance(NS_SCRIPTERROR_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  rv = errorObject->InitWithWindowID(errorText,
+  rv = errorObject->InitWithWindowID(aErrorText,
                                      NS_ConvertUTF8toUTF16(spec), // file name
                                      aSourceLine,
                                      aLineNumber, aColumnNumber,
                                      aErrorFlags, aCategory,
                                      innerWindowID);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return sConsoleService->LogMessage(errorObject);
--- a/docshell/base/LoadContext.cpp
+++ b/docshell/base/LoadContext.cpp
@@ -90,16 +90,25 @@ LoadContext::SetUsePrivateBrowsing(bool 
 {
   MOZ_ASSERT(mIsNotNull);
 
   // We shouldn't need this on parent...
   return NS_ERROR_UNEXPECTED;
 }
 
 NS_IMETHODIMP
+LoadContext::SetPrivateBrowsing(bool aUsePrivateBrowsing)
+{
+  MOZ_ASSERT(mIsNotNull);
+
+  // We shouldn't need this on parent...
+  return NS_ERROR_UNEXPECTED;
+}
+
+NS_IMETHODIMP
 LoadContext::GetIsInBrowserElement(bool* aIsInBrowserElement)
 {
   MOZ_ASSERT(mIsNotNull);
 
   NS_ENSURE_ARG_POINTER(aIsInBrowserElement);
 
   *aIsInBrowserElement = mIsInBrowserElement;
   return NS_OK;
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -141,17 +141,16 @@
 #include "nsICachingChannel.h"
 #include "nsICacheVisitor.h"
 #include "nsICacheEntryDescriptor.h"
 #include "nsIMultiPartChannel.h"
 #include "nsIWyciwygChannel.h"
 
 // For reporting errors with the console service.
 // These can go away if error reporting is propagated up past nsDocShell.
-#include "nsIConsoleService.h"
 #include "nsIScriptError.h"
 
 // used to dispatch urls to default protocol handlers
 #include "nsCExternalHandlerService.h"
 #include "nsIExternalProtocolService.h"
 
 #include "nsFocusManager.h"
 
@@ -2010,31 +2009,45 @@ nsDocShell::GetUsePrivateBrowsing(bool* 
     
     *aUsePrivateBrowsing = mInPrivateBrowsing;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocShell::SetUsePrivateBrowsing(bool aUsePrivateBrowsing)
 {
+#ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
+    nsContentUtils::ReportToConsoleNonLocalized(
+        NS_LITERAL_STRING("Only internal code is allowed to set the usePrivateBrowsing attribute"),
+        nsIScriptError::warningFlag,
+        "Internal API Used",
+        mContentViewer ? mContentViewer->GetDocument() : nullptr);
+#endif
+
+    return SetPrivateBrowsing(aUsePrivateBrowsing);
+}
+
+NS_IMETHODIMP
+nsDocShell::SetPrivateBrowsing(bool aUsePrivateBrowsing)
+{
     bool changed = aUsePrivateBrowsing != mInPrivateBrowsing;
     if (changed) {
         mInPrivateBrowsing = aUsePrivateBrowsing;
         if (aUsePrivateBrowsing) {
             IncreasePrivateDocShellCount();
         } else {
             DecreasePrivateDocShellCount();
         }
     }
-    
+
     int32_t count = mChildList.Count();
     for (int32_t i = 0; i < count; ++i) {
         nsCOMPtr<nsILoadContext> shell = do_QueryInterface(ChildAt(i));
         if (shell) {
-            shell->SetUsePrivateBrowsing(aUsePrivateBrowsing);
+            shell->SetPrivateBrowsing(aUsePrivateBrowsing);
         }
     }
 
     if (changed) {
         nsTObserverArray<nsWeakPtr>::ForwardIterator iter(mPrivacyObservers);
         while (iter.HasMore()) {
             nsWeakPtr ref = iter.GetNext();
             nsCOMPtr<nsIPrivacyTransitionObserver> obs = do_QueryReferent(ref);
@@ -2764,17 +2777,17 @@ nsDocShell::SetDocLoaderParent(nsDocLoad
         }
         SetAllowDNSPrefetch(value);
     }
 
     nsCOMPtr<nsILoadContext> parentAsLoadContext(do_QueryInterface(parent));
     if (parentAsLoadContext &&
         NS_SUCCEEDED(parentAsLoadContext->GetUsePrivateBrowsing(&value)))
     {
-        SetUsePrivateBrowsing(value);
+        SetPrivateBrowsing(value);
 #ifndef MOZ_PER_WINDOW_PRIVATE_BROWSING
         // Belt and suspenders - we want to catch any instances where the flag
         // we're propagating doesn't match the global state.
         nsCOMPtr<nsIPrivateBrowsingService> pbs =
                 do_GetService(NS_PRIVATE_BROWSING_SERVICE_CONTRACTID);
         if (pbs) {
             bool inPrivateBrowsing = false;
             pbs->GetPrivateBrowsingEnabled(&inPrivateBrowsing);
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -222,16 +222,17 @@ public:
     // are shared with nsIDocShell (appID, etc.) and can't be declared twice.
     NS_IMETHOD GetAssociatedWindow(nsIDOMWindow**);
     NS_IMETHOD GetTopWindow(nsIDOMWindow**);
     NS_IMETHOD GetTopFrameElement(nsIDOMElement**);
     NS_IMETHOD IsAppOfType(uint32_t, bool*);
     NS_IMETHOD GetIsContent(bool*);
     NS_IMETHOD GetUsePrivateBrowsing(bool*);
     NS_IMETHOD SetUsePrivateBrowsing(bool);
+    NS_IMETHOD SetPrivateBrowsing(bool);
 
     // Restores a cached presentation from history (mLSHE).
     // This method swaps out the content viewer and simulates loads for
     // subframes.  It then simulates the completion of the toplevel load.
     nsresult RestoreFromHistory();
 
     // Perform a URI load from a refresh timer.  This is just like the
     // ForceRefreshURI method on nsIRefreshURI, but makes sure to take
--- a/docshell/base/nsILoadContext.idl
+++ b/docshell/base/nsILoadContext.idl
@@ -9,17 +9,17 @@
 interface nsIDOMWindow;
 interface nsIDOMElement;
 
 /**
  * An nsILoadContext represents the context of a load.  This interface
  * can be queried for various information about where the load is
  * happening.
  */
-[scriptable, uuid(17f6a38a-3f4b-4c94-8252-9d9f7dbf4960)]
+[scriptable, uuid(d0029474-0cc4-42fd-bb21-d9ff22f5293c)]
 interface nsILoadContext : nsISupports
 {
   /**
    * associatedWindow is the window with which the load is associated, if any.
    * Note that the load may be triggered by a document which is different from
    * the document in associatedWindow, and in fact the source of the load need
    * not be same-origin with the document in associatedWindow.  This attribute
    * may be null if there is no associated window.
@@ -73,16 +73,21 @@ interface nsILoadContext : nsISupports
   bool UsePrivateBrowsing() {
     bool usingPB;
     GetUsePrivateBrowsing(&usingPB);
     return usingPB;
   }
 %}
 
   /**
+   * Set the private browsing state of the load context, meant to be used internally.
+   */
+  [noscript] void SetPrivateBrowsing(in boolean aInPrivateBrowsing);
+
+  /**
    * Returns true iif the load is occurring inside a browser element.
    */
   readonly attribute boolean isInBrowserElement;
 
   /**
    * Returns the app id of the app the load is occurring is in. Returns
    * nsIScriptSecurityManager::NO_APP_ID if the load is not part of an app.
    */
--- a/embedding/components/windowwatcher/src/nsWindowWatcher.cpp
+++ b/embedding/components/windowwatcher/src/nsWindowWatcher.cpp
@@ -914,17 +914,17 @@ nsWindowWatcher::OpenWindowInternal(nsID
         isPrivateBrowsingWindow = parentContext->UsePrivateBrowsing();
       }
     }
 
     nsCOMPtr<nsIDocShellTreeItem> childRoot;
     newDocShellItem->GetRootTreeItem(getter_AddRefs(childRoot));
     nsCOMPtr<nsILoadContext> childContext = do_QueryInterface(childRoot);
     if (childContext) {
-      childContext->SetUsePrivateBrowsing(isPrivateBrowsingWindow);
+      childContext->SetPrivateBrowsing(isPrivateBrowsingWindow);
     }
   }
 
   if (uriToLoad && aNavigate) { // get the script principal and pass it to docshell
     JSContextAutoPopper contextGuard;
 
     cx = GetJSContextFromCallStack();
 
--- a/uriloader/prefetch/OfflineCacheUpdateParent.cpp
+++ b/uriloader/prefetch/OfflineCacheUpdateParent.cpp
@@ -211,16 +211,22 @@ OfflineCacheUpdateParent::GetUsePrivateB
 }
 NS_IMETHODIMP
 OfflineCacheUpdateParent::SetUsePrivateBrowsing(bool aUsePrivateBrowsing)
 {
     return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
+OfflineCacheUpdateParent::SetPrivateBrowsing(bool aUsePrivateBrowsing)
+{
+    return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
 OfflineCacheUpdateParent::GetIsInBrowserElement(bool *aIsInBrowserElement)
 {
     *aIsInBrowserElement = mIsInBrowserElement;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 OfflineCacheUpdateParent::GetAppId(uint32_t *aAppId)
--- a/xpfe/appshell/src/nsAppShellService.cpp
+++ b/xpfe/appshell/src/nsAppShellService.cpp
@@ -368,17 +368,17 @@ nsAppShellService::JustCreateTopWindow(n
       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 (thisContext) {
-    thisContext->SetUsePrivateBrowsing(isPrivateBrowsingWindow);
+    thisContext->SetPrivateBrowsing(isPrivateBrowsingWindow);
   }
 
   window.swap(*aResult); // transfer reference
   if (parent)
     parent->AddChildWindow(*aResult);
 
   if (center)
     rv = (*aResult)->Center(parent, parent ? false : true, false);