Bug 1495064 - part1 : refactor the logic of requesting wakelock. r=jya
authoralwu <alwu@mozilla.com>
Tue, 02 Oct 2018 17:56:21 +0000
changeset 495755 9b3be971c8b013743fc9a819c641c2fb98d55c5f
parent 495754 b9efe1ec39cb3ac95f5f94365dffd5bad9e29b6b
child 495756 696f01b5d804309cedfb82debc291a822efd9072
push id9984
push userffxbld-merge
push dateMon, 15 Oct 2018 21:07:35 +0000
treeherdermozilla-beta@183d27ea8570 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjya
bugs1495064
milestone64.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 1495064 - part1 : refactor the logic of requesting wakelock. r=jya HTMLMediaElement::UpdateWakeLock() is responsible for creating and releasing audio wakelock. HTMLVideoElement::UpdateWakeLock() is responsible for creating and releasing video wakelock. In addition, each platform would handle system wakelock properly depending on different requests. Differential Revision: https://phabricator.services.mozilla.com/D7214
dom/html/HTMLMediaElement.cpp
dom/html/HTMLMediaElement.h
dom/html/HTMLVideoElement.cpp
dom/html/HTMLVideoElement.h
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -4277,47 +4277,54 @@ HTMLMediaElement::UpdateWakeLock()
   MOZ_ASSERT(NS_IsMainThread());
   // Ensure we have a wake lock if we're playing audibly. This ensures the
   // device doesn't sleep while playing.
   bool playing = !mPaused;
   bool isAudible =
     Volume() > 0.0 && !mMuted && mIsAudioTrackAudible;
   // WakeLock when playing audible media.
   if (playing && isAudible) {
-    WakeLockCreate();
+    CreateAudioWakeLockIfNeeded();
   } else {
-    WakeLockRelease();
-  }
-}
-
-void
-HTMLMediaElement::WakeLockCreate()
+    ReleaseAudioWakeLockIfExists();
+  }
+}
+
+void
+HTMLMediaElement::CreateAudioWakeLockIfNeeded()
 {
   if (!mWakeLock) {
     RefPtr<power::PowerManagerService> pmService =
       power::PowerManagerService::GetInstance();
     NS_ENSURE_TRUE_VOID(pmService);
 
     ErrorResult rv;
-    mWakeLock = pmService->NewWakeLock(
-      NS_LITERAL_STRING("audio-playing"), OwnerDoc()->GetInnerWindow(), rv);
-  }
-}
-
-void
-HTMLMediaElement::WakeLockRelease()
+    mWakeLock = pmService->NewWakeLock(NS_LITERAL_STRING("audio-playing"),
+                                       OwnerDoc()->GetInnerWindow(),
+                                       rv);
+  }
+}
+
+void
+HTMLMediaElement::ReleaseAudioWakeLockIfExists()
 {
   if (mWakeLock) {
     ErrorResult rv;
     mWakeLock->Unlock(rv);
     rv.SuppressException();
     mWakeLock = nullptr;
   }
 }
 
+void
+HTMLMediaElement::WakeLockRelease()
+{
+  ReleaseAudioWakeLockIfExists();
+}
+
 HTMLMediaElement::OutputMediaStream::OutputMediaStream()
   : mNextAvailableTrackID(1)
   , mFinishWhenEnded(false)
   , mCapturingAudioOnly(false)
   , mCapturingDecoder(false)
   , mCapturingMediaStream(false)
 {
 }
--- a/dom/html/HTMLMediaElement.h
+++ b/dom/html/HTMLMediaElement.h
@@ -839,18 +839,16 @@ protected:
   class StreamListener;
   class StreamSizeListener;
   class ShutdownObserver;
 
   MediaDecoderOwner::NextFrameStatus NextFrameStatus();
 
   void SetDecoder(MediaDecoder* aDecoder);
 
-  void UpdateWakeLock();
-
   // Holds references to the DOM wrappers for the MediaStreams that we're
   // writing to.
   struct OutputMediaStream {
     OutputMediaStream();
     ~OutputMediaStream();
 
     RefPtr<DOMMediaStream> mStream;
     TrackID mNextAvailableTrackID;
@@ -877,21 +875,24 @@ protected:
 
   /**
    * Use this method to change the mNetworkState member, so required
    * actions will be taken during the transition.
    */
   void ChangeNetworkState(nsMediaNetworkState aState);
 
   /**
-   * These two methods are called when mPaused is changed to ensure we have
-   * a wake lock active when we're playing audibly.
+   * The MediaElement will be responsible for creating and releasing the audio
+   * wakelock depending on the playing and audible state.
    */
-  virtual void WakeLockCreate();
   virtual void WakeLockRelease();
+  virtual void UpdateWakeLock();
+
+  void CreateAudioWakeLockIfNeeded();
+  void ReleaseAudioWakeLockIfExists();
   RefPtr<WakeLock> mWakeLock;
 
   /**
    * Logs a warning message to the web console to report various failures.
    * aMsg is the localized message identifier, aParams is the parameters to
    * be substituted into the localized message, and aParamCount is the number
    * of parameters in aParams.
    */
--- a/dom/html/HTMLVideoElement.cpp
+++ b/dom/html/HTMLVideoElement.cpp
@@ -291,54 +291,63 @@ HTMLVideoElement::GetVideoPlaybackQualit
   }
 
   RefPtr<VideoPlaybackQuality> playbackQuality =
     new VideoPlaybackQuality(this, creationTime, totalFrames, droppedFrames,
                              corruptedFrames);
   return playbackQuality.forget();
 }
 
-void
-HTMLVideoElement::WakeLockCreate()
-{
-  HTMLMediaElement::WakeLockCreate();
-  UpdateScreenWakeLock();
-}
 
 void
 HTMLVideoElement::WakeLockRelease()
 {
-  UpdateScreenWakeLock();
   HTMLMediaElement::WakeLockRelease();
+  ReleaseVideoWakeLockIfExists();
 }
 
 void
-HTMLVideoElement::UpdateScreenWakeLock()
+HTMLVideoElement::UpdateWakeLock()
 {
-  if (mScreenWakeLock && mPaused) {
-    ErrorResult rv;
-    mScreenWakeLock->Unlock(rv);
-    rv.SuppressException();
-    mScreenWakeLock = nullptr;
-    return;
+  HTMLMediaElement::UpdateWakeLock();
+  if (!mPaused) {
+    CreateVideoWakeLockIfNeeded();
+  } else {
+    ReleaseVideoWakeLockIfExists();
   }
+}
 
-  if (!mScreenWakeLock && !mPaused && HasVideo()) {
+void
+HTMLVideoElement::CreateVideoWakeLockIfNeeded()
+{
+  if (!mScreenWakeLock && HasVideo()) {
     RefPtr<power::PowerManagerService> pmService =
       power::PowerManagerService::GetInstance();
     NS_ENSURE_TRUE_VOID(pmService);
 
     ErrorResult rv;
     mScreenWakeLock = pmService->NewWakeLock(NS_LITERAL_STRING("video-playing"),
                                              OwnerDoc()->GetInnerWindow(),
                                              rv);
   }
 }
 
 void
+HTMLVideoElement::ReleaseVideoWakeLockIfExists()
+{
+  if (mScreenWakeLock) {
+    ErrorResult rv;
+    mScreenWakeLock->Unlock(rv);
+    rv.SuppressException();
+    mScreenWakeLock = nullptr;
+    return;
+  }
+}
+
+void
 HTMLVideoElement::Init()
 {
   Preferences::AddBoolVarCache(&sVideoStatsEnabled, "media.video_stats.enabled");
 }
 
 /* static */
 bool
 HTMLVideoElement::IsVideoStatsEnabled()
--- a/dom/html/HTMLVideoElement.h
+++ b/dom/html/HTMLVideoElement.h
@@ -150,19 +150,27 @@ public:
     mIsOrientationLocked = aLock;
   }
 
 protected:
   virtual ~HTMLVideoElement();
 
   virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
-  virtual void WakeLockCreate() override;
-  virtual void WakeLockRelease() override;
-  void UpdateScreenWakeLock();
+  /**
+   * We create video wakelock when the video is playing and release it when
+   * video pauses. Note, the actual platform wakelock will automatically be
+   * released when the page is in the background, so we don't need to check the
+   * video's visibility by ourselves.
+   */
+  void WakeLockRelease() override;
+  void UpdateWakeLock() override;
+
+  void CreateVideoWakeLockIfNeeded();
+  void ReleaseVideoWakeLockIfExists();
 
   RefPtr<WakeLock> mScreenWakeLock;
 
   bool mIsOrientationLocked;
 
 private:
   static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
                                     MappedDeclarations&);