Bug 1654959 - part1 : start listener when media enters fullscreen. r=bryce
authoralwu <alwu@mozilla.com>
Fri, 24 Jul 2020 02:43:33 +0000
changeset 541869 4e685f4aa90e2e28235c1e756105b4743676c88e
parent 541868 e7e5ac6a20365bb3af92424239d52370fb391a49
child 541870 f10c1afc8bf0943e077a76f0978f49230aff2060
push id37633
push userccoroiu@mozilla.com
push dateFri, 24 Jul 2020 09:32:06 +0000
treeherdermozilla-central@141543043270 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbryce
bugs1654959, 13429
milestone80.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 1654959 - part1 : start listener when media enters fullscreen. r=bryce When a media enters fullscreen mode, we should consider it as an important one which user might want to control. Therefore, start the listener in order to notify the media has been started, then we would update the fullscreen state [1] which would activate the controller. [1] https://searchfox.org/mozilla-central/rev/9b282b34b5aa0f836beb735656c55efb2cc4c617/dom/base/Document.cpp#13429 Differential Revision: https://phabricator.services.mozilla.com/D84118
dom/base/Document.cpp
dom/html/HTMLMediaElement.cpp
dom/html/HTMLMediaElement.h
--- a/dom/base/Document.cpp
+++ b/dom/base/Document.cpp
@@ -13418,16 +13418,19 @@ static void UpdateViewportScrollbarOverr
 
 static void NotifyFullScreenChangedForMediaControl(Element* aElement,
                                                    bool aIsInFullScreen) {
   // When a media element enters the fullscreen, we would like to notify that
   // to the media controller in order to update its status.
   if (!aElement->IsAnyOfHTMLElements(nsGkAtoms::audio, nsGkAtoms::video)) {
     return;
   }
+  HTMLMediaElement* mediaElem = HTMLMediaElement::FromNodeOrNull(aElement);
+  mediaElem->NotifyFullScreenChanged();
+
   RefPtr<BrowsingContext> bc = aElement->OwnerDoc()->GetBrowsingContext();
   if (!bc) {
     return;
   }
   if (RefPtr<IMediaInfoUpdater> updater = ContentMediaAgent::Get(bc)) {
     updater->NotifyMediaFullScreenState(bc->Id(), aIsInFullScreen);
   }
 }
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -6613,16 +6613,24 @@ void HTMLMediaElement::NotifyOwnerDocume
     if (mDecoder) {
       ShutdownDecoder();
     }
   }
 
   AddRemoveSelfReference();
 }
 
+void HTMLMediaElement::NotifyFullScreenChanged() {
+  if (IsInFullScreen()) {
+    StartMediaControlKeyListenerIfNeeded();
+    MOZ_ASSERT(mMediaControlKeyListener->IsStarted(),
+               "Failed to start the listener when entering fullscreen!");
+  }
+}
+
 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
   // potential listener for every event. We would also have to keep the
   // element alive if it was playing and producing audio output --- right now
   // that's covered by the !mPaused check.
   Document* ownerDoc = OwnerDoc();
 
@@ -7863,17 +7871,26 @@ void HTMLMediaElement::NotifyMediaContro
   }
   if (mPaused) {
     mMediaControlKeyListener->NotifyMediaStoppedPlaying();
   } else {
     mMediaControlKeyListener->NotifyMediaStartedPlaying();
   }
 }
 
+bool HTMLMediaElement::IsInFullScreen() const {
+  return State().HasState(NS_EVENT_STATE_FULLSCREEN);
+}
+
 bool HTMLMediaElement::ShouldStartMediaControlKeyListener() const {
+  if (IsInFullScreen()) {
+    MEDIACONTROL_LOG("Start listener because of being used in fullscreen");
+    return true;
+  }
+
   // In order to filter out notification-ish sound, we use this pref to set the
   // eligible media duration to prevent showing media control for those short
   // sound.
   if (Duration() <
       StaticPrefs::media_mediacontrol_eligible_media_duration_s()) {
     MEDIACONTROL_LOG("Not listening because media's duration %f is too short.",
                      Duration());
     return false;
--- a/dom/html/HTMLMediaElement.h
+++ b/dom/html/HTMLMediaElement.h
@@ -253,16 +253,21 @@ class HTMLMediaElement : public nsGeneri
   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();
 
+  // Called when the media element enters or leaves the fullscreen.
+  void NotifyFullScreenChanged();
+
+  bool IsInFullScreen() const;
+
   // From PrincipalChangeObserver<MediaStreamTrack>.
   void PrincipalChanged(MediaStreamTrack* aTrack) 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.
   void PrincipalHandleChangedForVideoFrameContainer(