Bug 1467350 - Make HTMLMediaElement::mPaused Watchable and update Wakelock status via a watcher. r?jya
We currently observe changes to HTMLMediaElement::mPaused via a hand-rolled
wrapper class. We can use use mozilla::Watchable<> and avoid rolling our
own equivalent here.
This also paves the way for using state watching on other observable state
in HTMLMediaElement.
MozReview-Commit-ID: 4lBlJiV15iG
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -3879,29 +3879,32 @@ private:
Phase mPhase = Phase::Init;
};
NS_IMPL_ISUPPORTS(HTMLMediaElement::ShutdownObserver, nsIObserver)
HTMLMediaElement::HTMLMediaElement(
already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
: nsGenericHTMLElement(aNodeInfo)
+ , mWatchManager(this, OwnerDoc()->AbstractMainThreadFor(TaskCategory::Other))
, mMainThreadEventTarget(OwnerDoc()->EventTargetFor(TaskCategory::Other))
, mAbstractMainThread(OwnerDoc()->AbstractMainThreadFor(TaskCategory::Other))
, mShutdownObserver(new ShutdownObserver)
, mPlayed(new TimeRanges(ToSupports(OwnerDoc())))
- , mPaused(true, *this)
+ , mPaused(true, "HTMLMediaElement::mPaused")
, mErrorSink(new ErrorSink(this))
, mAudioChannelWrapper(new AudioChannelAgentCallback(this))
{
MOZ_ASSERT(mMainThreadEventTarget);
MOZ_ASSERT(mAbstractMainThread);
DecoderDoctorLogger::LogConstruction(this);
+ mWatchManager.Watch(mPaused, &HTMLMediaElement::UpdateWakeLock);
+
ErrorResult rv;
double defaultVolume = Preferences::GetFloat("media.default_volume", 1.0);
SetVolume(defaultVolume, rv);
RegisterActivityObserver();
NotifyOwnerDocumentActivityChanged();
@@ -4175,41 +4178,30 @@ HTMLMediaElement::PlayInternal(ErrorResu
void
HTMLMediaElement::MaybeDoLoad()
{
if (mNetworkState == NETWORK_EMPTY) {
DoLoad();
}
}
-HTMLMediaElement::WakeLockBoolWrapper&
-HTMLMediaElement::WakeLockBoolWrapper::operator=(bool val)
-{
- if (mValue == val) {
- return *this;
- }
-
- mValue = val;
- UpdateWakeLock();
- return *this;
-}
-
-void
-HTMLMediaElement::WakeLockBoolWrapper::UpdateWakeLock()
+void
+HTMLMediaElement::UpdateWakeLock()
{
MOZ_ASSERT(NS_IsMainThread());
-
- bool playing = !mValue;
+ // 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 =
- mOuter.Volume() > 0.0 && !mOuter.mMuted && mOuter.mIsAudioTrackAudible;
- // when playing audible media.
+ Volume() > 0.0 && !mMuted && mIsAudioTrackAudible;
+ // WakeLock when playing audible media.
if (playing && isAudible) {
- mOuter.WakeLockCreate();
+ WakeLockCreate();
} else {
- mOuter.WakeLockRelease();
+ WakeLockRelease();
}
}
void
HTMLMediaElement::WakeLockCreate()
{
if (!mWakeLock) {
RefPtr<power::PowerManagerService> pmService =
@@ -7544,17 +7536,17 @@ HTMLMediaElement::SetAudibleState(bool a
void
HTMLMediaElement::NotifyAudioPlaybackChanged(AudibleChangedReasons aReason)
{
if (mAudioChannelWrapper) {
mAudioChannelWrapper->NotifyAudioPlaybackChanged(aReason);
}
// only request wake lock for audible media.
- mPaused.UpdateWakeLock();
+ UpdateWakeLock();
}
bool
HTMLMediaElement::ShouldElementBePaused()
{
// Bfcached page or inactive document.
if (!IsActive()) {
return true;
--- a/dom/html/HTMLMediaElement.h
+++ b/dom/html/HTMLMediaElement.h
@@ -834,36 +834,17 @@ protected:
class StreamListener;
class StreamSizeListener;
class ShutdownObserver;
MediaDecoderOwner::NextFrameStatus NextFrameStatus();
void SetDecoder(MediaDecoder* aDecoder);
- class WakeLockBoolWrapper {
- public:
- WakeLockBoolWrapper(bool aVal, HTMLMediaElement& aOuter)
- : mValue(aVal)
- , mOuter(aOuter)
- {}
-
- ~WakeLockBoolWrapper() {};
-
- MOZ_IMPLICIT operator bool() const { return mValue; }
-
- WakeLockBoolWrapper& operator=(bool val);
-
- bool operator !() const { return !mValue; }
-
- void UpdateWakeLock();
- private:
- bool mValue;
- HTMLMediaElement& mOuter;
- };
+ void UpdateWakeLock();
// Holds references to the DOM wrappers for the MediaStreams that we're
// writing to.
struct OutputMediaStream {
OutputMediaStream();
~OutputMediaStream();
RefPtr<DOMMediaStream> mStream;
@@ -891,18 +872,18 @@ 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 by the WakeLockBoolWrapper when the wakelock
- * has to be created or released.
+ * These two methods are called when mPaused is changed to ensure we have
+ * a wake lock active when we're playing audibly.
*/
virtual void WakeLockCreate();
virtual void WakeLockRelease();
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
@@ -1368,16 +1349,18 @@ protected:
bool AttachNewMediaKeys();
bool TryMakeAssociationWithCDM(CDMProxy* aProxy);
void MakeAssociationWithCDMResolved();
void SetCDMProxyFailure(const MediaResult& aResult);
void ResetSetMediaKeysTempVariables();
void PauseIfShouldNotBePlaying();
+ WatchManager<HTMLMediaElement> mWatchManager;
+
// The current decoder. Load() has been called on this decoder.
// At most one of mDecoder and mSrcStream can be non-null.
RefPtr<MediaDecoder> mDecoder;
// The DocGroup-specific nsISerialEventTarget of this HTML element on the main
// thread.
nsCOMPtr<nsISerialEventTarget> mMainThreadEventTarget;
@@ -1595,17 +1578,17 @@ protected:
// start playing when loaded. The 'autoplay' attribute of the object
// is a mirror of the HTML attribute. These are different from this
// 'mAutoplaying' flag, which indicates whether the current playback
// is a result of the autoplay attribute.
bool mAutoplaying = true;
// Playback of the video is paused either due to calling the
// 'Pause' method, or playback not yet having started.
- WakeLockBoolWrapper mPaused;
+ Watchable<bool> mPaused;
// The following two fields are here for the private storage of the builtin
// video controls, and control 'casting' of the video to external devices
// (TVs, projectors etc.)
// True if casting is currently allowed
bool mAllowCasting = false;
// True if currently casting this video
bool mIsCasting = false;