Bug 1430019 - Propagate gester-activation between docshell reloads for same-origin content-viewer setups. draft
authorChris Pearce <cpearce@mozilla.com>
Tue, 20 Feb 2018 09:10:41 +1300
changeset 773287 bc78594d2f6c83d011a34b3caf06d2a3936d5cfa
parent 773286 c86083b3250613d11257f7ae70683aa465503321
child 773288 cab260c4d11c8a1a0bee19ee691ef6bbe6c7173b
push id104207
push userbmo:cpearce@mozilla.com
push dateTue, 27 Mar 2018 20:19:54 +0000
bugs1430019
milestone61.0a1
Bug 1430019 - Propagate gester-activation between docshell reloads for same-origin content-viewer setups. MozReview-Commit-ID: FytSJy5pLy7
docshell/base/nsDocShell.cpp
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -8765,22 +8765,25 @@ nsDocShell::CreateContentViewer(const ns
 
   // Notify the current document that it is about to be unloaded!!
   //
   // It is important to fire the unload() notification *before* any state
   // is changed within the DocShell - otherwise, javascript will get the
   // wrong information :-(
   //
 
+  nsCOMPtr<nsIPrincipal> oldPrincipal;
+
   if (mSavingOldViewer) {
     // We determined that it was safe to cache the document presentation
     // at the time we initiated the new load.  We need to check whether
     // it's still safe to do so, since there may have been DOM mutations
     // or new requests initiated.
     nsCOMPtr<nsIDocument> doc = viewer->GetDocument();
+    oldPrincipal = doc->NodePrincipal();
     mSavingOldViewer = CanSavePresentation(mLoadType, aRequest, doc);
   }
 
   NS_ASSERTION(!mLoadingURI, "Re-entering unload?");
 
   nsCOMPtr<nsIChannel> aOpenedChannel = do_QueryInterface(aRequest);
   if (aOpenedChannel) {
     aOpenedChannel->GetURI(getter_AddRefs(mLoadingURI));
@@ -9018,17 +9021,19 @@ nsDocShell::SetupNewViewer(nsIContentVie
   int32_t hintCharsetSource;
   int32_t minFontSize;
   float textZoom;
   float pageZoom;
   float overrideDPPX;
   bool styleDisabled;
   // |newMUDV| also serves as a flag to set the data from the above vars
   nsCOMPtr<nsIContentViewer> newCv;
-
+  nsCOMPtr<nsIPrincipal> oldPrincipal;
+
+  bool activatedByUserGesture = false;
   if (mContentViewer || parent) {
     nsCOMPtr<nsIContentViewer> oldCv;
     if (mContentViewer) {
       // Get any interesting state from old content viewer
       // XXX: it would be far better to just reuse the document viewer ,
       //      since we know we're just displaying the same document as before
       oldCv = mContentViewer;
 
@@ -9042,16 +9047,22 @@ nsDocShell::SetupNewViewer(nsIContentVie
         mSavingOldViewer = false;
       }
     } else {
       // No old content viewer, so get state from parent's content viewer
       parent->GetContentViewer(getter_AddRefs(oldCv));
     }
 
     if (oldCv) {
+      // Record the user-gesture activation state from the old document, and
+      // its principal. This ensures we can forward the unblock-autoplay-media
+      // state into the new document.
+      nsIDocument* doc = oldCv->GetDocument();
+      activatedByUserGesture = doc && doc->HasBeenUserActivated();
+      oldPrincipal = doc ? doc->NodePrincipal() : nullptr;
       newCv = aNewViewer;
       if (newCv) {
         forceCharset = oldCv->GetForceCharset();
         hintCharset = oldCv->GetHintCharset();
         NS_ENSURE_SUCCESS(oldCv->GetHintCharacterSetSource(&hintCharsetSource),
                           NS_ERROR_FAILURE);
         NS_ENSURE_SUCCESS(oldCv->GetMinFontSize(&minFontSize),
                           NS_ERROR_FAILURE);
@@ -9062,16 +9073,19 @@ nsDocShell::SetupNewViewer(nsIContentVie
         NS_ENSURE_SUCCESS(oldCv->GetOverrideDPPX(&overrideDPPX),
                           NS_ERROR_FAILURE);
         NS_ENSURE_SUCCESS(oldCv->GetAuthorStyleDisabled(&styleDisabled),
                           NS_ERROR_FAILURE);
       }
     }
   }
 
+  // printf("%p %s activatedByUserGesture=%d oldPrincipal=%p\n",
+  //   this, __func__, activatedByUserGesture, oldPrincipal);
+
   nscolor bgcolor = NS_RGBA(0, 0, 0, 0);
   bool isActive = false;
   // Ensure that the content viewer is destroyed *after* the GC - bug 71515
   nsCOMPtr<nsIContentViewer> contentViewer = mContentViewer;
   if (contentViewer) {
     // Stop any activity that may be happening in the old document before
     // releasing it...
     contentViewer->Stop();
@@ -9128,16 +9142,29 @@ nsDocShell::SetupNewViewer(nsIContentVie
     NS_ENSURE_SUCCESS(newCv->SetTextZoom(textZoom),
                       NS_ERROR_FAILURE);
     NS_ENSURE_SUCCESS(newCv->SetFullZoom(pageZoom),
                       NS_ERROR_FAILURE);
     NS_ENSURE_SUCCESS(newCv->SetOverrideDPPX(overrideDPPX),
                       NS_ERROR_FAILURE);
     NS_ENSURE_SUCCESS(newCv->SetAuthorStyleDisabled(styleDisabled),
                       NS_ERROR_FAILURE);
+
+    // Restore activated-by-user-gesture state, to propogate autoplay media
+    // state into the new if it's same origin.
+    nsIDocument* doc = newCv->GetDocument();
+    if (activatedByUserGesture && doc) {
+      nsCOMPtr<nsIPrincipal> newPrincipal = doc->NodePrincipal();
+      if (oldPrincipal->Equals(newPrincipal)) {
+        // TODO: Should use Equals()? Subsumes?
+        doc->NotifyUserActivation();
+      }
+      // } else {
+      //   printf("!doc\n");
+    }
   }
 
   // Stuff the bgcolor from the old pres shell into the new
   // pres shell. This improves page load continuity.
   nsCOMPtr<nsIPresShell> shell;
   mContentViewer->GetPresShell(getter_AddRefs(shell));
 
   if (shell) {