Chromium Code Reviews| Index: Source/core/html/HTMLMediaElement.h |
| diff --git a/Source/core/html/HTMLMediaElement.h b/Source/core/html/HTMLMediaElement.h |
| index 2f1bea3fc8f96c6333f9c3c7361d47bcf86982df..2f5fd9d5ea9b6c990fc5f4b08f3eefcc537f0800 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; |
|
dglazkov
2015/08/06 20:55:23
This seems like it could be a separate CL.
|
| 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 |
|
dglazkov
2015/08/06 20:55:23
Please no ASCII art -___-
liberato (no reviews please)
2015/08/07 21:53:16
.-'''-.
______
|
| + |
| + // Install an event listener to check for changes in visibility. If a |
| + // listener is already installed, then this does nothing. |
| + void autoplayExperimentInstallEventListenerIfNeeded(); |
|
dglazkov
2015/08/06 20:55:23
I would like to avoid spamming already-large class
liberato (no reviews please)
2015/08/07 21:53:16
this change makes me happy. PS19 has most of the
|
| + |
| + // 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,32 @@ 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. |
| + // Scroll listener for the autoplay experiment, to help us determine when |
| + // the user has scrolled the player into the viewport. |
| + class AutoplayExperimentScrollListener; |
| + friend class AutoplayExperimentScrollListener; |
| + RefPtrWillBeMember<EventListener> m_autoplayExperimentScrollListener; |
| + |
| + 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 +725,11 @@ private: |
| AudioSourceProviderImpl m_audioSourceProvider; |
| #endif |
| + Timer<HTMLMediaElement> m_autoplayViewportTimer; |
|
dglazkov
2015/08/06 20:55:23
Using timers here seems bad. Why?
liberato (no reviews please)
2015/08/07 21:53:17
we want to know when a scroll has (probably) ended
ojan
2015/08/11 02:45:21
I think having a timer is good. The problem is wha
liberato (no reviews please)
2015/09/01 06:54:19
thanks for the detailed description! the most rec
|
| + double m_autoplayLastScrollX; |
| + double m_autoplayLastScrollY; |
| + double m_autoplayViewportTimerSpan; |
| + |
| friend class MediaController; |
| PersistentWillBeMember<MediaController> m_mediaController; |