Bug 1526355 - part1 : notify the front end side to show the blocking icon if the site is still being blocked after it's back from the bfcache. r=cpearce a=lizzard
authorAlastor Wu <alwu@mozilla.com>
Mon, 04 Mar 2019 17:25:52 +0000
changeset 516293 cd093abd9a5c
parent 516292 8704ee5785b6
child 516294 30da98d1f31c
push id1953
push userffxbld-merge
push dateMon, 11 Mar 2019 12:10:20 +0000
treeherdermozilla-release@9c35dcbaa899 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpearce, lizzard
bugs1526355
milestone66.0
Bug 1526355 - part1 : notify the front end side to show the blocking icon if the site is still being blocked after it's back from the bfcache. r=cpearce a=lizzard In order to display blocking icon when the document comes back from the bfcache, we have to notify front end what's the current blocking status. As the front end side would clear blocking autoplay information when nagivation occurs, and the media might not invoke the play again when they comes back from the bfcache. Therefore, we should notify front end side that the site is still being blocked, and we should show blocking icon for it. Differential Revision: https://phabricator.services.mozilla.com/D21582
dom/html/HTMLMediaElement.cpp
dom/html/HTMLMediaElement.h
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -3665,16 +3665,17 @@ void HTMLMediaElement::DispatchEventsWhe
 #if defined(MOZ_WIDGET_ANDROID)
   RefPtr<AsyncEventDispatcher> asyncDispatcher = new AsyncEventDispatcher(
       this, NS_LITERAL_STRING("MozAutoplayMediaBlocked"), CanBubble::eYes,
       ChromeOnlyDispatch::eYes);
   asyncDispatcher->PostDOMEvent();
 #endif
   OwnerDoc()->MaybeNotifyAutoplayBlocked();
   ReportToConsole(nsIScriptError::warningFlag, "BlockAutoplayError");
+  mHasEverBeenBlockedForAutoplay = true;
 }
 
 void HTMLMediaElement::PlayInternal(bool aHandlingUserInput) {
   if (mPreloadAction == HTMLMediaElement::PRELOAD_NONE) {
     // The media load algorithm will be initiated by a user interaction.
     // We want to boost the channel priority for better responsiveness.
     // Note this must be done before UpdatePreloadAction() which will
     // update |mPreloadAction|.
@@ -5894,16 +5895,24 @@ void HTMLMediaElement::SuspendOrResumeEl
         if (!mPaused && !mDecoder->IsEnded()) {
           mDecoder->Play();
         }
       }
       if (mEventDeliveryPaused) {
         mEventDeliveryPaused = false;
         DispatchPendingMediaEvents();
       }
+      // If the media element has been blocked and isn't still allowed to play
+      // when it comes back from the bfcache, we would notify front end to show
+      // the blocking icon in order to inform user that the site is still being
+      // blocked.
+      if (mHasEverBeenBlockedForAutoplay &&
+          !AutoplayPolicy::IsAllowedToPlay(*this)) {
+        OwnerDoc()->MaybeNotifyAutoplayBlocked();
+      }
     }
   }
 }
 
 bool HTMLMediaElement::IsBeingDestroyed() {
   Document* ownerDoc = OwnerDoc();
   nsIDocShell* docShell = ownerDoc ? ownerDoc->GetDocShell() : nullptr;
   bool isBeingDestroyed = false;
--- a/dom/html/HTMLMediaElement.h
+++ b/dom/html/HTMLMediaElement.h
@@ -1663,16 +1663,21 @@ class HTMLMediaElement : public nsGeneri
   // yet.
   bool mBlockedAsWithoutMetadata = false;
 
   // This promise is used to notify MediaElementAudioSourceNode that media
   // element is allowed to play when MediaElement is used as a source for web
   // audio.
   MozPromiseHolder<GenericNonExclusivePromise> mAllowedToPlayPromise;
 
+  // True if media has ever been blocked for autoplay, it's used to notify front
+  // end to show the correct blocking icon when the document goes back from
+  // bfcache.
+  bool mHasEverBeenBlockedForAutoplay = false;
+
  public:
   // Helper class to measure times for MSE telemetry stats
   class TimeDurationAccumulator {
    public:
     TimeDurationAccumulator() : mCount(0) {}
     void Start() {
       if (IsStarted()) {
         return;