Index: Source/core/html/AutoplayExperimentHelper.h |
diff --git a/Source/core/html/AutoplayExperimentHelper.h b/Source/core/html/AutoplayExperimentHelper.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..cad39ef9b8cad5dd164e01b3e99c49c663903ec7 |
--- /dev/null |
+++ b/Source/core/html/AutoplayExperimentHelper.h |
@@ -0,0 +1,172 @@ |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef AutoplayExperimentHelper_h |
+#define AutoplayExperimentHelper_h |
+ |
+#include "core/html/AutoplayExperimentConfig.h" |
+#include "core/page/Page.h" |
+#include "platform/Timer.h" |
+#include "platform/geometry/IntRect.h" |
+ |
+namespace blink { |
+class Document; |
+class HTMLMediaElement; |
+class EventListener; |
+ |
+// 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. |
+ AutoplayPaused = 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 detected, but the gesture |
+ // requirement was overridden by experiment". They do not include cases |
+ // where no user gesture is required (!m_userGestureRequiredForPlay). |
+ |
+ // User gesture requirement was bypassed, and playback started, during |
+ // initial load via the autoplay flag. If playback was deferred due to |
+ // visibility requirements, then this does not apply. |
+ GesturelessPlaybackStartedByAutoplayFlagImmediately = 6, |
+ |
+ // User gesture requirement was bypassed, and playback started, when |
+ // the play() method was called. If playback is deferred due to |
+ // visibility requirements, then this does not apply. |
+ GesturelessPlaybackStartedByPlayMethodImmediately = 7, |
+ |
+ // User gesture requirement was bypassed, and playback started, after |
+ // an element with the autoplay flag moved into the viewport. Playback |
+ // was deferred earlier due to visibility requirements. |
+ GesturelessPlaybackStartedByAutoplayFlagAfterScroll = 8, |
+ |
+ // User gesture requirement was bypassed, and playback started, after |
+ // an element on which the play() method was called was moved into the |
+ // viewport. Playback had been deferred due to visibility requirements. |
+ GesturelessPlaybackStartedByPlayMethodAfterScroll = 9, |
+ |
+ // play() failed to play due to gesture requirement. |
+ PlayMethodFailed = 10, |
+ |
+ // Some play, whether user initiated or not, started. |
+ AnyPlaybackStarted = 11, |
+ // Some play, whether user initiated or not, paused. |
+ AnyPlaybackPaused = 12, |
+ // Some playback, whether user initiated or not, bailed out early. |
+ AnyPlaybackBailout = 13, |
+ |
+ // This enum value must be last. |
+ NumberOfAutoplayMetrics, |
+}; |
+ |
+class AutoplayExperimentHelper { |
+public: |
+ AutoplayExperimentHelper(HTMLMediaElement&); |
+ ~AutoplayExperimentHelper(); |
+ |
+ void becameReadyToPlay(); |
+ void playMethodCalled(); |
+ void pauseMethodCalled(); |
+ void mutedChanged(); |
+ void positionChanged(); |
+ |
+ // For testing. |
+ void triggerAutoplayViewportCheck(); |
+ |
+private: |
+ // The location and size of our element, and the viewport. Also supports |
+ // "not valid", in case some of the information isn't available. |
+ class LocationState { |
+ public: |
+ LocationState() : m_valid(false) {} |
+ LocationState(Element&); |
+ |
+ bool valid() const { return m_valid; } |
+ PageVisibilityState visibilityState() const { return m_visibilityState; } |
+ const IntRect& element() const { return m_element; } |
+ const IntRect& screen() const { return m_screen; } |
+ |
+ bool operator==(const LocationState&) const; |
+ bool operator!=(const LocationState&) const; |
+ |
+ // Return true if and only if the player is visible. |
+ bool isInViewport(); |
+ |
+ private: |
+ bool m_valid; |
+ PageVisibilityState m_visibilityState; |
+ IntRect m_element; |
+ IntRect m_screen; |
+ }; |
+ |
+ // Install an event listener to check for changes in visibility. If a |
+ // listener is already installed, then this does nothing. |
+ void installEventListenerIfNeeded(); |
ojan
2015/09/01 20:20:11
Nit: They're not event listeners anymore now that
liberato (no reviews please)
2015/09/04 06:49:46
i renamed to "[un]registerForPositionUpdatesIfNeed
|
+ |
+ // Remove any event listener. It's okay to call this if one isn't |
+ // installed already. |
+ void clearEventListenerIfNeeded(); |
+ |
+ // 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 isEligible() const; |
+ |
+ // Return false if and only if the player is not visible, and we care |
+ // that it must be visible. |
+ bool isInViewportIfNeeded(); |
+ |
+ // Set the muted flag on the media if we're in an experiment mode that |
+ // requires it, else do nothing. |
+ void muteIfNeeded(); |
+ |
+ // Maybe override the requirement for a user gesture, and start playing |
+ // autoplay media. Returns true if only if it starts playback. |
+ bool maybeStartPlaying(); |
+ |
+ // 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 prepareToPlay(AutoplayMetrics); |
+ |
+ // Process a timer for checking visibility. |
+ void viewportTimerFired(Timer<AutoplayExperimentHelper>*); |
+ |
+ // Return our media element's document. |
+ Document& document() const; |
+ |
+ inline bool enabled(AutoplayExperimentConfig::Mode mode) const |
+ { |
+ return ((int)m_mode) & ((int)mode); |
+ } |
+ |
+private: |
+ HTMLMediaElement& m_element; |
+ |
+ AutoplayExperimentConfig::Mode m_mode; |
+ |
+ // Autoplay experiment state. |
+ // True if we've received a play() without a pause(). |
+ bool m_playPending : 1; |
+ |
+ Timer<AutoplayExperimentHelper> m_viewportTimer; |
+ |
+ bool m_registeredWithView; |
philipj_slow
2015/09/02 09:24:12
Put this together with the other bool to get them
liberato (no reviews please)
2015/09/04 06:49:46
Done.
|
+ |
+ LocationState m_lastLocation; |
+ |
+ friend class Internals; |
+}; |
+ |
+} // namespace blink |
+ |
+#endif // AutoplayExperimentHelper_h |