Bug 1368046 - Part 2: Propagate OriginAttributes across processes for RecvCreateWindowInDifferentProcess, r=smaug
authorMichael Layzell <michael@thelayzells.com>
Tue, 06 Jun 2017 14:22:17 -0400
changeset 413207 8dd6234e2a18f9fb9ab6ec32d84fbb38c8a7d7fa
parent 413206 548be4ca230bf01b914dd685f92d35897803a31b
child 413208 77154e843ebc364a9dba989f8ebc71e29e1cb08c
push id1490
push usermtabara@mozilla.com
push dateMon, 31 Jul 2017 14:08:16 +0000
treeherdermozilla-release@70e32e6bf15e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1368046
milestone55.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 1368046 - Part 2: Propagate OriginAttributes across processes for RecvCreateWindowInDifferentProcess, r=smaug MozReview-Commit-ID: 8ok4DI9zgfR
dom/base/nsOpenURIInFrameParams.cpp
dom/base/nsOpenURIInFrameParams.h
dom/interfaces/base/nsIBrowserDOMWindow.idl
dom/ipc/ContentChild.cpp
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/PBrowser.ipdl
dom/ipc/PContent.ipdl
dom/ipc/TabChild.cpp
dom/ipc/TabChild.h
toolkit/components/windowwatcher/nsPIWindowWatcher.idl
toolkit/components/windowwatcher/nsWindowWatcher.cpp
--- a/dom/base/nsOpenURIInFrameParams.cpp
+++ b/dom/base/nsOpenURIInFrameParams.cpp
@@ -7,17 +7,16 @@
 #include "nsOpenURIInFrameParams.h"
 #include "mozilla/BasePrincipal.h"
 #include "mozilla/dom/ToJSValue.h"
 
 NS_IMPL_ISUPPORTS(nsOpenURIInFrameParams, nsIOpenURIInFrameParams)
 
 nsOpenURIInFrameParams::nsOpenURIInFrameParams(const mozilla::OriginAttributes& aOriginAttributes)
   : mOpenerOriginAttributes(aOriginAttributes)
-  , mIsPrivate(false)
 {
 }
 
 nsOpenURIInFrameParams::~nsOpenURIInFrameParams() {
 }
 
 NS_IMETHODIMP
 nsOpenURIInFrameParams::GetReferrer(nsAString& aReferrer)
@@ -32,24 +31,17 @@ nsOpenURIInFrameParams::SetReferrer(cons
   mReferrer = aReferrer;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsOpenURIInFrameParams::GetIsPrivate(bool* aIsPrivate)
 {
   NS_ENSURE_ARG_POINTER(aIsPrivate);
-  *aIsPrivate = mIsPrivate;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsOpenURIInFrameParams::SetIsPrivate(bool aIsPrivate)
-{
-  mIsPrivate = aIsPrivate;
+  *aIsPrivate = mOpenerOriginAttributes.mPrivateBrowsingId > 0;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsOpenURIInFrameParams::GetOpenerOriginAttributes(JSContext* aCx,
                                                   JS::MutableHandle<JS::Value> aValue)
 {
   bool ok = ToJSValue(aCx, mOpenerOriginAttributes, aValue);
--- a/dom/base/nsOpenURIInFrameParams.h
+++ b/dom/base/nsOpenURIInFrameParams.h
@@ -20,10 +20,9 @@ public:
 
   explicit nsOpenURIInFrameParams(const mozilla::OriginAttributes& aOriginAttributes);
 
 private:
   ~nsOpenURIInFrameParams();
 
   mozilla::OriginAttributes mOpenerOriginAttributes;
   nsString mReferrer;
-  bool mIsPrivate;
 };
--- a/dom/interfaces/base/nsIBrowserDOMWindow.idl
+++ b/dom/interfaces/base/nsIBrowserDOMWindow.idl
@@ -9,17 +9,17 @@ interface mozIDOMWindowProxy;
 interface nsIDOMWindow;
 interface nsIURI;
 interface nsIFrameLoaderOwner;
 
 [scriptable, uuid(e774db14-79ac-4156-a7a3-aa3fd0a22c10)]
 interface nsIOpenURIInFrameParams : nsISupports
 {
   attribute DOMString referrer;
-  attribute boolean isPrivate;
+  readonly attribute boolean isPrivate;
 
   [implicit_jscontext]
   readonly attribute jsval openerOriginAttributes;
 };
 
 [scriptable, uuid(9d17f3dd-672b-451e-afd2-b1115df780d5)]
 
 /**
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -679,18 +679,17 @@ ContentChild::ProvideWindow(mozIDOMWindo
   return ProvideWindowCommon(nullptr, aParent, false, aChromeFlags,
                              aCalledFromJS, aPositionSpecified,
                              aSizeSpecified, aURI, aName, aFeatures,
                              aForceNoOpener, aWindowIsNew, aReturn);
 }
 
 static nsresult
 GetWindowParamsFromParent(mozIDOMWindowProxy* aParent,
-                          nsACString& aBaseURIString, float* aFullZoom,
-                          OriginAttributes& aOriginAttributes)
+                          nsACString& aBaseURIString, float* aFullZoom)
 {
   *aFullZoom = 1.0f;
   auto* opener = nsPIDOMWindowOuter::From(aParent);
   if (!opener) {
     return NS_OK;
   }
 
   nsCOMPtr<nsIDocument> doc = opener->GetDoc();
@@ -703,18 +702,16 @@ GetWindowParamsFromParent(mozIDOMWindowP
   baseURI->GetSpec(aBaseURIString);
 
   RefPtr<nsDocShell> openerDocShell =
     static_cast<nsDocShell*>(opener->GetDocShell());
   if (!openerDocShell) {
     return NS_OK;
   }
 
-  aOriginAttributes = openerDocShell->GetOriginAttributes();
-
   nsCOMPtr<nsIContentViewer> cv;
   nsresult rv = openerDocShell->GetContentViewer(getter_AddRefs(cv));
   if (NS_SUCCEEDED(rv) && cv) {
     cv->GetFullZoom(aFullZoom);
   }
 
   return NS_OK;
 }
@@ -747,32 +744,32 @@ ContentChild::ProvideWindowCommon(TabChi
     nsCOMPtr<nsIWebBrowserChrome3> browserChrome3;
     rv = aTabOpener->GetWebBrowserChrome(getter_AddRefs(browserChrome3));
     if (NS_SUCCEEDED(rv) && browserChrome3) {
       bool shouldLoad;
       rv = browserChrome3->ShouldLoadURIInThisProcess(aURI, &shouldLoad);
       if (NS_SUCCEEDED(rv) && !shouldLoad) {
         nsAutoCString baseURIString;
         float fullZoom;
-        OriginAttributes originAttributes;
-        rv = GetWindowParamsFromParent(aParent, baseURIString, &fullZoom,
-                                       originAttributes);
+        rv = GetWindowParamsFromParent(aParent, baseURIString, &fullZoom);
         if (NS_WARN_IF(NS_FAILED(rv))) {
           return rv;
         }
 
         URIParams uriToLoad;
         SerializeURI(aURI, uriToLoad);
-        Unused << SendCreateWindowInDifferentProcess(aTabOpener, aChromeFlags,
+        Unused << SendCreateWindowInDifferentProcess(aTabOpener,
+                                                     aChromeFlags,
                                                      aCalledFromJS,
                                                      aPositionSpecified,
                                                      aSizeSpecified,
-                                                     uriToLoad, features,
+                                                     uriToLoad,
+                                                     features,
                                                      baseURIString,
-                                                     originAttributes, fullZoom);
+                                                     fullZoom);
 
         // We return NS_ERROR_ABORT, so that the caller knows that we've abandoned
         // the window open as far as it is concerned.
         return NS_ERROR_ABORT;
       }
     }
 
     PopupIPCTabContext context;
@@ -846,29 +843,26 @@ ContentChild::ProvideWindowCommon(TabChi
 
     newChild->SendBrowserFrameOpenWindow(aTabOpener, renderFrame, NS_ConvertUTF8toUTF16(url),
                                          name, NS_ConvertUTF8toUTF16(features),
                                          aWindowIsNew, &textureFactoryIdentifier,
                                          &layersId, &compositorOptions, &maxTouchPoints);
   } else {
     nsAutoCString baseURIString;
     float fullZoom;
-    OriginAttributes originAttributes;
-    rv = GetWindowParamsFromParent(aParent, baseURIString, &fullZoom,
-                                   originAttributes);
+    rv = GetWindowParamsFromParent(aParent, baseURIString, &fullZoom);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
 
     if (!SendCreateWindow(aTabOpener, newChild, renderFrame,
                           aChromeFlags, aCalledFromJS, aPositionSpecified,
                           aSizeSpecified,
                           features,
                           baseURIString,
-                          originAttributes,
                           fullZoom,
                           &rv,
                           aWindowIsNew,
                           &frameScripts,
                           &urlToLoad,
                           &textureFactoryIdentifier,
                           &layersId,
                           &compositorOptions,
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -4404,17 +4404,16 @@ ContentParent::CommonCreateWindow(PBrows
                                   bool aSetOpener,
                                   const uint32_t& aChromeFlags,
                                   const bool& aCalledFromJS,
                                   const bool& aPositionSpecified,
                                   const bool& aSizeSpecified,
                                   nsIURI* aURIToLoad,
                                   const nsCString& aFeatures,
                                   const nsCString& aBaseURI,
-                                  const OriginAttributes& aOpenerOriginAttributes,
                                   const float& aFullZoom,
                                   uint64_t aNextTabParentId,
                                   const nsString& aName,
                                   nsresult& aResult,
                                   nsCOMPtr<nsITabParent>& aNewTabParent,
                                   bool* aWindowIsNew)
 
 {
@@ -4470,32 +4469,34 @@ ContentParent::CommonCreateWindow(PBrows
   }
 
   int32_t openLocation = nsWindowWatcher::GetWindowOpenLocation(
     outerWin, aChromeFlags, aCalledFromJS, aPositionSpecified, aSizeSpecified);
 
   MOZ_ASSERT(openLocation == nsIBrowserDOMWindow::OPEN_NEWTAB ||
              openLocation == nsIBrowserDOMWindow::OPEN_NEWWINDOW);
 
+  // Read the origin attributes for the tab from the opener tabParent.
+  OriginAttributes openerOriginAttributes;
+  if (thisTabParent) {
+    nsCOMPtr<nsILoadContext> loadContext = thisTabParent->GetLoadContext();
+    loadContext->GetOriginAttributes(openerOriginAttributes);
+  } else if (Preferences::GetBool("browser.privatebrowsing.autostart")) {
+    openerOriginAttributes.mPrivateBrowsingId = 1;
+  }
+
   if (openLocation == nsIBrowserDOMWindow::OPEN_NEWTAB) {
     if (NS_WARN_IF(!browserDOMWin)) {
       aResult = NS_ERROR_ABORT;
       return IPC_OK();
     }
 
-    bool isPrivate = false;
-    if (thisTabParent) {
-      nsCOMPtr<nsILoadContext> loadContext = thisTabParent->GetLoadContext();
-      loadContext->GetUsePrivateBrowsing(&isPrivate);
-    }
-
     nsCOMPtr<nsIOpenURIInFrameParams> params =
-      new nsOpenURIInFrameParams(aOpenerOriginAttributes);
+      new nsOpenURIInFrameParams(openerOriginAttributes);
     params->SetReferrer(NS_ConvertUTF8toUTF16(aBaseURI));
-    params->SetIsPrivate(isPrivate);
 
     nsCOMPtr<nsIFrameLoaderOwner> frameLoaderOwner;
     aResult = browserDOMWin->OpenURIInFrame(aURIToLoad, params, openLocation,
                                             nsIBrowserDOMWindow::OPEN_NEW,
                                             aNextTabParentId, aName,
                                             getter_AddRefs(frameLoaderOwner));
     if (NS_SUCCEEDED(aResult) && frameLoaderOwner) {
       RefPtr<nsFrameLoader> frameLoader = frameLoaderOwner->GetFrameLoader();
@@ -4510,31 +4511,42 @@ ContentParent::CommonCreateWindow(PBrows
   }
 
   nsCOMPtr<nsPIWindowWatcher> pwwatch =
     do_GetService(NS_WINDOWWATCHER_CONTRACTID, &aResult);
   if (NS_WARN_IF(NS_FAILED(aResult))) {
     return IPC_OK();
   }
 
-  aResult = pwwatch->OpenWindowWithTabParent(aSetOpener ? thisTabParent : nullptr,
+  aResult = pwwatch->OpenWindowWithTabParent(thisTabParent,
                                              aFeatures, aCalledFromJS, aFullZoom,
                                              aNextTabParentId,
+                                             !aSetOpener,
                                              getter_AddRefs(aNewTabParent));
   if (NS_WARN_IF(NS_FAILED(aResult))) {
     return IPC_OK();
   }
 
   MOZ_ASSERT(aNewTabParent);
   // If we were passed a name for the window which would override the default,
   // we should send it down to the new tab.
   if (nsContentUtils::IsOverridingWindowName(aName)) {
     Unused << TabParent::GetFrom(aNewTabParent)->SendSetWindowName(aName);
   }
 
+  // Don't send down the OriginAttributes if the content process is handling
+  // setting up the window for us. We only want to send them in the async case.
+  //
+  // If we send it down in the non-async case, then we might set the
+  // OriginAttributes after the document has already navigated.
+  if (!aSetOpener) {
+    Unused << TabParent::GetFrom(aNewTabParent)
+      ->SendSetOriginAttributes(openerOriginAttributes);
+  }
+
   if (aURIToLoad) {
     nsCOMPtr<mozIDOMWindowProxy> openerWindow;
     if (aSetOpener && thisTabParent) {
       openerWindow = thisTabParent->GetParentWindowOuter();
     }
     nsCOMPtr<nsIBrowserDOMWindow> newBrowserDOMWin =
       TabParent::GetFrom(aNewTabParent)->GetBrowserDOMWindow();
     if (NS_WARN_IF(!newBrowserDOMWin)) {
@@ -4556,17 +4568,16 @@ ContentParent::RecvCreateWindow(PBrowser
                                 PBrowserParent* aNewTab,
                                 PRenderFrameParent* aRenderFrame,
                                 const uint32_t& aChromeFlags,
                                 const bool& aCalledFromJS,
                                 const bool& aPositionSpecified,
                                 const bool& aSizeSpecified,
                                 const nsCString& aFeatures,
                                 const nsCString& aBaseURI,
-                                const OriginAttributes& aOpenerOriginAttributes,
                                 const float& aFullZoom,
                                 nsresult* aResult,
                                 bool* aWindowIsNew,
                                 InfallibleTArray<FrameScriptInfo>* aFrameScripts,
                                 nsCString* aURLToLoad,
                                 TextureFactoryIdentifier* aTextureFactoryIdentifier,
                                 uint64_t* aLayersId,
                                 CompositorOptions* aCompositorOptions,
@@ -4594,18 +4605,18 @@ ContentParent::RecvCreateWindow(PBrowser
   TabParent::AutoUseNewTab aunt(newTab, aURLToLoad);
   const uint64_t nextTabParentId = ++sNextTabParentId;
   sNextTabParents.Put(nextTabParentId, newTab);
 
   nsCOMPtr<nsITabParent> newRemoteTab;
   mozilla::ipc::IPCResult ipcResult =
     CommonCreateWindow(aThisTab, /* aSetOpener = */ true, aChromeFlags,
                        aCalledFromJS, aPositionSpecified, aSizeSpecified,
-                       nullptr, aFeatures, aBaseURI, aOpenerOriginAttributes,
-                       aFullZoom, nextTabParentId, NullString(), *aResult,
+                       nullptr, aFeatures, aBaseURI, aFullZoom,
+                       nextTabParentId, NullString(), *aResult,
                        newRemoteTab, aWindowIsNew);
   if (!ipcResult) {
     return ipcResult;
   }
 
   if (NS_WARN_IF(NS_FAILED(*aResult))) {
     return IPC_OK();
   }
@@ -4635,29 +4646,28 @@ ContentParent::RecvCreateWindowInDiffere
   PBrowserParent* aThisTab,
   const uint32_t& aChromeFlags,
   const bool& aCalledFromJS,
   const bool& aPositionSpecified,
   const bool& aSizeSpecified,
   const URIParams& aURIToLoad,
   const nsCString& aFeatures,
   const nsCString& aBaseURI,
-  const OriginAttributes& aOpenerOriginAttributes,
   const float& aFullZoom,
   const nsString& aName)
 {
   nsCOMPtr<nsITabParent> newRemoteTab;
   bool windowIsNew;
   nsCOMPtr<nsIURI> uriToLoad = DeserializeURI(aURIToLoad);
   nsresult rv;
   mozilla::ipc::IPCResult ipcResult =
     CommonCreateWindow(aThisTab, /* aSetOpener = */ false, aChromeFlags,
                        aCalledFromJS, aPositionSpecified, aSizeSpecified,
-                       uriToLoad, aFeatures, aBaseURI, aOpenerOriginAttributes,
-                       aFullZoom, /* aNextTabParentId = */ 0, aName, rv,
+                       uriToLoad, aFeatures, aBaseURI, aFullZoom,
+                       /* aNextTabParentId = */ 0, aName, rv,
                        newRemoteTab, &windowIsNew);
   if (!ipcResult) {
     return ipcResult;
   }
 
   if (NS_FAILED(rv)) {
     NS_WARNING("Call to CommonCreateWindow failed.");
   }
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -530,17 +530,16 @@ public:
                    PBrowserParent* aNewTab,
                    layout::PRenderFrameParent* aRenderFrame,
                    const uint32_t& aChromeFlags,
                    const bool& aCalledFromJS,
                    const bool& aPositionSpecified,
                    const bool& aSizeSpecified,
                    const nsCString& aFeatures,
                    const nsCString& aBaseURI,
-                   const OriginAttributes& aOpenerOriginAttributes,
                    const float& aFullZoom,
                    nsresult* aResult,
                    bool* aWindowIsNew,
                    InfallibleTArray<FrameScriptInfo>* aFrameScripts,
                    nsCString* aURLToLoad,
                    layers::TextureFactoryIdentifier* aTextureFactoryIdentifier,
                    uint64_t* aLayersId,
                    mozilla::layers::CompositorOptions* aCompositorOptions,
@@ -550,17 +549,16 @@ public:
     PBrowserParent* aThisTab,
     const uint32_t& aChromeFlags,
     const bool& aCalledFromJS,
     const bool& aPositionSpecified,
     const bool& aSizeSpecified,
     const URIParams& aURIToLoad,
     const nsCString& aFeatures,
     const nsCString& aBaseURI,
-    const OriginAttributes& aOpenerOriginAttributes,
     const float& aFullZoom,
     const nsString& aName) override;
 
   static bool AllocateLayerTreeId(TabParent* aTabParent, uint64_t* aId);
 
   static void
   BroadcastBlobURLRegistration(const nsACString& aURI,
                                BlobImpl* aBlobImpl,
@@ -708,17 +706,16 @@ private:
                      bool aSetOpener,
                      const uint32_t& aChromeFlags,
                      const bool& aCalledFromJS,
                      const bool& aPositionSpecified,
                      const bool& aSizeSpecified,
                      nsIURI* aURIToLoad,
                      const nsCString& aFeatures,
                      const nsCString& aBaseURI,
-                     const OriginAttributes& aOpenerOriginAttributes,
                      const float& aFullZoom,
                      uint64_t aNextTabParentId,
                      const nsString& aName,
                      nsresult& aResult,
                      nsCOMPtr<nsITabParent>& aNewTabParent,
                      bool* aWindowIsNew);
 
   FORWARD_SHMEM_ALLOCATOR_TO(PContentParent)
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -78,16 +78,17 @@ using class mozilla::dom::ipc::Structure
 using mozilla::EventMessage from "mozilla/EventForwards.h";
 using nsEventStatus from "mozilla/EventForwards.h";
 using mozilla::Modifiers from "mozilla/EventForwards.h";
 using nsSizeMode from "nsIWidgetListener.h";
 using mozilla::widget::CandidateWindowPosition from "ipc/nsGUIEventIPC.h";
 using class mozilla::NativeEventData from "ipc/nsGUIEventIPC.h";
 using mozilla::FontRange from "ipc/nsGUIEventIPC.h";
 using mozilla::a11y::IAccessibleHolder from "mozilla/a11y/IPCTypes.h";
+using mozilla::OriginAttributes from "mozilla/ipc/BackgroundUtils.h";
 
 namespace mozilla {
 namespace dom {
 
 struct ShowInfo
 {
   nsString name;
   bool fullscreenAllowed;
@@ -890,16 +891,22 @@ child:
      */
     async AwaitLargeAlloc();
 
     /**
      * Tell the TabChild to set the name of its toplevel docshell to the given name.
      */
     async SetWindowName(nsString aName);
 
+    /**
+     * Tell the TabChild what OriginAttributes it should inherit from. This must
+     * be called before the first non-blank document is loaded in the TabChild.
+     */
+    async SetOriginAttributes(OriginAttributes aOriginAttributes);
+
 /*
  * FIXME: write protocol!
 
 state LIVE:
     send LoadURL goto LIVE;
 //etc.
     send Destroy goto DYING;
 
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -983,17 +983,16 @@ parent:
                       PBrowser aNewTab,
                       PRenderFrame aRenderFrame,
                       uint32_t aChromeFlags,
                       bool aCalledFromJS,
                       bool aPositionSpecified,
                       bool aSizeSpecified,
                       nsCString aFeatures,
                       nsCString aBaseURI,
-                      OriginAttributes aOpenerOriginAttributes,
                       float aFullZoom)
       returns (nsresult rv,
                bool windowOpened,
                FrameScriptInfo[] frameScripts,
                nsCString urlToLoad,
                TextureFactoryIdentifier textureFactoryIdentifier,
                uint64_t layersId,
                CompositorOptions compositorOptions,
@@ -1003,17 +1002,16 @@ parent:
       PBrowser aThisTab,
       uint32_t aChromeFlags,
       bool aCalledFromJS,
       bool aPositionSpecified,
       bool aSizeSpecified,
       URIParams aURIToLoad,
       nsCString aFeatures,
       nsCString aBaseURI,
-      OriginAttributes aOpenerOriginAttributes,
       float aFullZoom,
       nsString aName);
 
     sync GetAndroidSystemInfo()
         returns (AndroidSystemInfo info);
 
     /**
      * Tells the parent to ungrab the pointer on the default display.
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -3163,16 +3163,25 @@ TabChild::RecvSetWindowName(const nsStri
 {
   nsCOMPtr<nsIDocShellTreeItem> item = do_QueryInterface(WebNavigation());
   if (item) {
     item->SetName(aName);
   }
   return IPC_OK();
 }
 
+mozilla::ipc::IPCResult
+TabChild::RecvSetOriginAttributes(const OriginAttributes& aOriginAttributes)
+{
+  nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation());
+  nsDocShell::Cast(docShell)->SetOriginAttributes(aOriginAttributes);
+
+  return IPC_OK();
+}
+
 mozilla::plugins::PPluginWidgetChild*
 TabChild::AllocPPluginWidgetChild()
 {
 #ifdef XP_WIN
   return new mozilla::plugins::PluginWidgetChild();
 #else
   MOZ_ASSERT_UNREACHABLE();
   return nullptr;
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -732,16 +732,18 @@ protected:
                                                                   const uint32_t& aTargetLocalIndex) override;
 
   virtual mozilla::ipc::IPCResult RecvNotifyPartialSHistoryDeactive() override;
 
   virtual mozilla::ipc::IPCResult RecvAwaitLargeAlloc() override;
 
   virtual mozilla::ipc::IPCResult RecvSetWindowName(const nsString& aName) override;
 
+  virtual mozilla::ipc::IPCResult RecvSetOriginAttributes(const OriginAttributes& aOriginAttributes) override;
+
 private:
   void HandleDoubleTap(const CSSPoint& aPoint, const Modifiers& aModifiers,
                        const ScrollableLayerGuid& aGuid);
 
   // Notify others that our TabContext has been updated.
   //
   // You should call this after calling TabContext::SetTabContext().  We also
   // call this during Init().
--- a/toolkit/components/windowwatcher/nsPIWindowWatcher.idl
+++ b/toolkit/components/windowwatcher/nsPIWindowWatcher.idl
@@ -100,25 +100,29 @@ interface nsPIWindowWatcher : nsISupport
    * @param aCalledFromJS
    *        True if called via window.open or similar.
    * @param aOpenerFullZoom
    *        The current zoom multiplier for the opener tab. This is then
    *        applied to the newly opened window.
    * @param aNextTabParentId
    *        The integer ID for the next tab parent actor.
    *        0 means there is no next tab parent actor to use.
+   * @param aForceNoOpener
+   *        If true, then aOpeningTab will not be used to set the opener
+   *        for the newly created window.
    *
    * @return the nsITabParent of the initial browser for the newly opened
    *         window.
    */
   nsITabParent openWindowWithTabParent(in nsITabParent aOpeningTab,
                                        in ACString aFeatures,
                                        in boolean aCalledFromJS,
                                        in float aOpenerFullZoom,
-                                       in unsigned long long aNextTabParentId);
+                                       in unsigned long long aNextTabParentId,
+                                       in boolean aForceNoOpener);
 
   /**
    * Find a named docshell tree item amongst all windows registered
    * with the window watcher.  This may be a subframe in some window,
    * for example.
    *
    * @param aName the name of the window.  Must not be null.
    * @param aRequestor the tree item immediately making the request.
--- a/toolkit/components/windowwatcher/nsWindowWatcher.cpp
+++ b/toolkit/components/windowwatcher/nsWindowWatcher.cpp
@@ -545,16 +545,17 @@ nsWindowWatcher::MaybeDisablePersistence
 }
 
 NS_IMETHODIMP
 nsWindowWatcher::OpenWindowWithTabParent(nsITabParent* aOpeningTabParent,
                                          const nsACString& aFeatures,
                                          bool aCalledFromJS,
                                          float aOpenerFullZoom,
                                          uint64_t aNextTabParentId,
+                                         bool aForceNoOpener,
                                          nsITabParent** aResult)
 {
   MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(mWindowCreator);
 
   if (!nsContentUtils::IsSafeToRunScript()) {
     nsContentUtils::WarnScriptWasIgnored(nullptr);
     return NS_ERROR_FAILURE;
@@ -612,17 +613,17 @@ nsWindowWatcher::OpenWindowWithTabParent
   // A content process has asked for a new window, which implies
   // that the new window will need to be remote.
   chromeFlags |= nsIWebBrowserChrome::CHROME_REMOTE_WINDOW;
 
   nsCOMPtr<nsIWebBrowserChrome> parentChrome(do_GetInterface(parentTreeOwner));
   nsCOMPtr<nsIWebBrowserChrome> newWindowChrome;
 
   CreateChromeWindow(aFeatures, parentChrome, chromeFlags,
-                     aOpeningTabParent, nullptr,
+                     aForceNoOpener ? nullptr : aOpeningTabParent, nullptr,
                      aNextTabParentId,
                      getter_AddRefs(newWindowChrome));
 
   if (NS_WARN_IF(!newWindowChrome)) {
     return NS_ERROR_UNEXPECTED;
   }
 
   nsCOMPtr<nsIDocShellTreeItem> chromeTreeItem = do_GetInterface(newWindowChrome);