Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(780)

Unified Diff: Source/core/html/HTMLMediaElement.h

Issue 1179223002: Implement autoplay gesture override experiment. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: fixed comments and names. Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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;

Powered by Google App Engine
This is Rietveld 408576698