Bug 1324883 - part1: Pass the unload to MediaElement when OnPageHide(), then MediaElement can shutdown the decoder. r=smaug draft
authorbechen@mozilla.com <bechen@mozilla.com>
Tue, 26 Sep 2017 16:53:53 +0800
changeset 670279 bde3d3ad7053cc284cf6397f44ce14c5afd2829e
parent 666196 c5d8edcea43b1d186f467f5138c825d80705e109
child 670280 b0425353c9da113974dcb2a8894a8fd72971fa29
push id81595
push userbmo:bechen@mozilla.com
push dateTue, 26 Sep 2017 08:55:26 +0000
reviewerssmaug
bugs1324883
milestone57.0a1
Bug 1324883 - part1: Pass the unload to MediaElement when OnPageHide(), then MediaElement can shutdown the decoder. r=smaug MozReview-Commit-ID: PZZAAjHYgL
dom/base/nsDocument.cpp
dom/html/HTMLMediaElement.cpp
dom/html/HTMLMediaElement.h
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -4913,24 +4913,26 @@ nsDocument::ContainsMSEContent()
 {
   bool containsMSE = false;
   EnumerateActivityObservers(CheckIfContainsMSEContent,
                              static_cast<void*>(&containsMSE));
   return containsMSE;
 }
 
 static void
-NotifyActivityChanged(nsISupports *aSupports, void *aUnused)
+NotifyActivityChanged(nsISupports *aSupports, void *aPersisted)
 {
   nsCOMPtr<nsIDOMHTMLMediaElement> domMediaElem(do_QueryInterface(aSupports));
   if (domMediaElem) {
     nsCOMPtr<nsIContent> content(do_QueryInterface(domMediaElem));
     MOZ_ASSERT(content, "aSupports is not a content");
     HTMLMediaElement* mediaElem = static_cast<HTMLMediaElement*>(content.get());
-    mediaElem->NotifyOwnerDocumentActivityChanged();
+    bool unload = static_cast<bool*>(aPersisted) ?
+                  !(*static_cast<bool*>(aPersisted)) : false;
+    mediaElem->NotifyOwnerDocumentActivityChanged(unload);
   }
   nsCOMPtr<nsIObjectLoadingContent> objectLoadingContent(do_QueryInterface(aSupports));
   if (objectLoadingContent) {
     nsObjectLoadingContent* olc = static_cast<nsObjectLoadingContent*>(objectLoadingContent.get());
     olc->NotifyOwnerDocumentActivityChanged();
   }
   nsCOMPtr<nsIDocumentActivity> objectDocumentActivity(do_QueryInterface(aSupports));
   if (objectDocumentActivity) {
@@ -9379,17 +9381,17 @@ nsDocument::OnPageHide(bool aPersisted,
     }
   }
 
   mVisible = false;
 
   UpdateVisibilityState();
 
   EnumerateExternalResources(NotifyPageHide, &aPersisted);
-  EnumerateActivityObservers(NotifyActivityChanged, nullptr);
+  EnumerateActivityObservers(NotifyActivityChanged, &aPersisted);
 
   ClearPendingFullscreenRequests(this);
   if (GetFullscreenElement()) {
     // If this document was fullscreen, we should exit fullscreen in this
     // doctree branch. This ensures that if the user navigates while in
     // fullscreen mode we don't leave its still visible ancestor documents
     // in fullscreen mode. So exit fullscreen in the document's fullscreen
     // root document, as this will exit fullscreen in all the root's
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -6337,17 +6337,17 @@ bool HTMLMediaElement::IsBeingDestroyed(
   nsIDocShell* docShell = ownerDoc ? ownerDoc->GetDocShell() : nullptr;
   bool isBeingDestroyed = false;
   if (docShell) {
     docShell->IsBeingDestroyed(&isBeingDestroyed);
   }
   return isBeingDestroyed;
 }
 
-void HTMLMediaElement::NotifyOwnerDocumentActivityChanged()
+void HTMLMediaElement::NotifyOwnerDocumentActivityChanged(bool aDocumentUnload)
 {
   bool visible = !IsHidden();
   if (visible) {
     // Visible -> Just pause hidden play time (no-op if already paused).
     HiddenVideoStop();
   } else if (mPlayTime.IsStarted()) {
     // Not visible, play time is running -> Start hidden play time if needed.
     HiddenVideoStart();
@@ -6357,22 +6357,26 @@ void HTMLMediaElement::NotifyOwnerDocume
     NotifyDecoderActivityChanges();
   }
 
   bool pauseElement = ShouldElementBePaused();
   SuspendOrResumeElement(pauseElement, !IsActive());
 
   // If the owning document has become inactive we should shutdown the CDM.
   if (!OwnerDoc()->IsCurrentActiveDocument() && mMediaKeys) {
-      mMediaKeys->Shutdown();
-      mMediaKeys = nullptr;
-      if (mDecoder) {
-        ShutdownDecoder();
-      }
-    }
+    mMediaKeys->Shutdown();
+    mMediaKeys = nullptr;
+    if (mDecoder) {
+      ShutdownDecoder();
+    }
+  }
+
+  if (aDocumentUnload && mDecoder) {
+    ShutdownDecoder();
+  }
 
   AddRemoveSelfReference();
 }
 
 void HTMLMediaElement::AddRemoveSelfReference()
 {
   // XXX we could release earlier here in many situations if we examined
   // which event listeners are attached. Right now we assume there is a
--- a/dom/html/HTMLMediaElement.h
+++ b/dom/html/HTMLMediaElement.h
@@ -232,17 +232,17 @@ public:
   // ImageContainer containing the video data.
   virtual VideoFrameContainer* GetVideoFrameContainer() final override;
   layers::ImageContainer* GetImageContainer();
 
   /**
    * Call this to reevaluate whether we should start/stop due to our owner
    * document being active, inactive, visible or hidden.
    */
-  void NotifyOwnerDocumentActivityChanged();
+  void NotifyOwnerDocumentActivityChanged(bool aDocumentUnload = false);
 
   // From PrincipalChangeObserver<DOMMediaStream>.
   void PrincipalChanged(DOMMediaStream* aStream) override;
 
   void UpdateSrcStreamVideoPrincipal(const PrincipalHandle& aPrincipalHandle);
 
   // Called after the MediaStream we're playing rendered a frame to aContainer
   // with a different principalHandle than the previous frame.