Index: Source/core/html/HTMLMediaElement.h |
diff --git a/Source/core/html/HTMLMediaElement.h b/Source/core/html/HTMLMediaElement.h |
index 2f1bea3fc8f96c6333f9c3c7361d47bcf86982df..8d4404087665221149e6239e48099ae86242dcc5 100644 |
--- a/Source/core/html/HTMLMediaElement.h |
+++ b/Source/core/html/HTMLMediaElement.h |
@@ -286,6 +286,46 @@ protected: |
void setControllerInternal(MediaController*); |
private: |
+ // These values are used for a histogram. Do not reorder. |
+ enum AutoplayMetrics { |
+ // Media element with autoplay seen. |
+ AutoplayMediaFound = 0, |
+ // Autoplay enabled and user stopped media play at any point. |
+ AutoplayStopped = 1, |
+ // Autoplay enabled but user bailed out on media play early. |
+ AutoplayBailout = 2, |
+ // Autoplay disabled but user manually started media. |
+ AutoplayManualStart = 3, |
+ // Autoplay was (re)enabled through a user-gesture triggered load() |
+ AutoplayEnabledThroughLoad = 4, |
+ // Autoplay disabled by sandbox flags. |
+ AutoplayDisabledBySandbox = 5, |
+ |
+ // These metrics indicate "no gesture but gesture requirement was |
+ // overridden by experiment". They do not include cases where no |
+ // user gesture is required (!m_userGestureRequiredForPlay). |
+ // Gestureless playback when media scrolled into view. We don't |
+ // record whether it was a javascript or attribute autoplay request. |
+ GesturelessPlaybackStartedByScroll = 6, |
+ // Autoplay started by experiment override during initial load. |
+ GesturelessPlaybackStartedByLoad = 7, |
+ // Autoplay started by experiment override in play() call. |
+ GesturelessPlaybackStartedByPlayMethod = 8, |
+ |
+ // play() failed to play due to gesture requirement. |
+ PlayMethodFailed = 9, |
+ |
+ // Some play, whether user initiated or not, started. |
+ AnyPlaybackStarted = 10, |
+ // Some play, whether user initiated or not, stopped. |
+ AnyPlaybackStopped = 11, |
+ // Some playback, whether user initiated or not, bailed out early. |
+ AnyPlaybackBailout = 12, |
+ |
+ // This enum value must be last. |
+ NumberOfAutoplayMetrics, |
+ }; |
+ |
void resetMediaPlayerAndMediaSource(); |
bool alwaysCreateUserAgentShadowRoot() const final { return true; } |
@@ -390,7 +430,13 @@ private: |
// This does not check user gesture restrictions. |
void playInternal(); |
- void gesturelessInitialPlayHalted(); |
+ // If we are about to enter a stopped state, call this to record |
+ // autoplay metrics. If we were already in a stopped state, then |
+ // this does nothing. |
+ void recordMetricsIfStopping(); |
+ // Could stopping at this point be considered a bailout of playback? |
+ // (as in, "The user really didn't want to play this"). |
+ bool isBailout() const; |
void autoplayMediaEncountered(); |
void allowVideoRendering(); |
@@ -426,6 +472,47 @@ private: |
bool isBlockedOnMediaController() const; |
bool isAutoplaying() const { return m_autoplaying; } |
+ void recordAutoplayMetric(AutoplayMetrics); |
+ |
+ // vvvv Helpers for clank autoplay investigation vvvv |
+ |
+ // Install an event listener to check for changes in visibility. If a |
+ // listener is already installed, then this does nothing. |
+ void autoplayExperimentInstallEventListenerIfNeeded(); |
+ |
+ // Remove any event listener. It's okay to call this if one isn't |
+ // installed already. |
+ void autoplayExperimentClearEventListenerIfNeeded(); |
+ |
+ // Return true if any only if this player meets (most) of the eligibility |
+ // requirements for the experiment to override the need for a user |
+ // gesture. This includes everything except the visibility test. |
+ bool autoplayExperimentIsEligible() const; |
+ |
+ // Return true if and only if the player is visible. |
+ bool autoplayExperimentIsInViewportIfNeeded(); |
+ |
+ // Set the mute flag on the media if we're in an experiment mode that |
+ // requires it, else do nothing. |
+ void autoplayExperimentMuteIfNeeded(); |
+ |
+ // Maybe override the requirement for a user gesture, and start playing |
+ // autoplay media. Returns true if only if it starts playback. |
+ bool autoplayExperimentMaybeStartPlaying(); |
+ |
+ // Configure internal state to record that the autoplay experiment is |
+ // going to start playback. This doesn't actually start playback, since |
+ // there are several different cases. |
+ void autoplayExperimentPrepareToPlay(AutoplayMetrics); |
+ |
+ // Begin (or start over) a periodic check for visibility. We will poll |
+ // during this check to see if the video is in the viewport. |
+ void notifyScrolled(); |
+ |
+ // Process a timer for checking visibility. |
+ void viewportTimerFired(Timer<HTMLMediaElement>*); |
+ // ^^^^ Helpers for clank autoplay investigation ^^^^ |
+ |
WebMediaPlayer::CORSMode corsMode() const; |
// Returns the "direction of playback" value as specified in the HTML5 spec. |
@@ -554,6 +641,31 @@ private: |
PersistentWillBeMember<TextTrackList> m_textTracks; |
PersistentHeapVectorWillBeHeapVector<Member<TextTrack>> m_textTracksWhenResourceSelectionBegan; |
+ // Autoplay experiment state. |
+ // True if we've received a play() without a pause(). |
+ bool m_autoplayExperimentPlayPending : 1; |
+ |
+ // Autoplay experiment state. |
+ // True if and only if we initiated playback because of the autoplay |
+ // experiment. Once set, this is never unset. |
+ bool m_autoplayExperimentStartedByExperiment : 1; |
+ |
+ // Autoplay experiment state. |
+ // Touch listener for the autoplay experiment. |
+ class AutoplayExperimentTouchListener; |
+ friend class AutoplayExperimentTouchListener; |
+ RefPtrWillBeMember<EventListener> m_autoplayExperimentTouchListener; |
+ |
+ enum AutoplayExperimentMode { |
+ ExperimentOff = 0, |
+ ExperimentEnabled = 1 << 0, |
+ ExperimentIfViewport = 1 << 1, |
+ ExperimentIfMuted = 1 << 2, |
+ ExperimentIfMobile = 1 << 3, |
+ ExperimentPlayMuted = 1 << 4 |
+ }; |
+ int m_autoplayExperimentMode; // Bitwise-or of AutoplayExperimentMode |
+ |
OwnPtrWillBeMember<CueTimeline> m_cueTimeline; |
#if ENABLE(WEB_AUDIO) |
@@ -612,6 +724,11 @@ private: |
AudioSourceProviderImpl m_audioSourceProvider; |
#endif |
+ Timer<HTMLMediaElement> m_autoplayViewportTimer; |
+ double m_autoplayLastScrollX; |
+ double m_autoplayLastScrollY; |
+ double m_autoplayViewportTimerSpan; |
+ |
friend class MediaController; |
PersistentWillBeMember<MediaController> m_mediaController; |