Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef AutoplayExperimentHelper_h | |
| 6 #define AutoplayExperimentHelper_h | |
| 7 | |
| 8 #include "core/html/AutoplayExperimentConfig.h" | |
| 9 #include "core/page/Page.h" | |
| 10 #include "platform/Timer.h" | |
| 11 #include "platform/geometry/IntRect.h" | |
| 12 | |
| 13 namespace blink { | |
| 14 class Document; | |
| 15 class HTMLMediaElement; | |
| 16 class EventListener; | |
| 17 | |
| 18 // These values are used for a histogram. Do not reorder. | |
| 19 enum AutoplayMetrics { | |
| 20 // Media element with autoplay seen. | |
| 21 AutoplayMediaFound = 0, | |
| 22 // Autoplay enabled and user stopped media play at any point. | |
| 23 AutoplayPaused = 1, | |
| 24 // Autoplay enabled but user bailed out on media play early. | |
| 25 AutoplayBailout = 2, | |
| 26 // Autoplay disabled but user manually started media. | |
| 27 AutoplayManualStart = 3, | |
| 28 // Autoplay was (re)enabled through a user-gesture triggered load() | |
| 29 AutoplayEnabledThroughLoad = 4, | |
| 30 // Autoplay disabled by sandbox flags. | |
| 31 AutoplayDisabledBySandbox = 5, | |
| 32 | |
| 33 // These metrics indicate "no gesture detected, but the gesture | |
| 34 // requirement was overridden by experiment". They do not include cases | |
| 35 // where no user gesture is required (!m_userGestureRequiredForPlay). | |
| 36 | |
| 37 // User gesture requirement was bypassed, and playback started, during | |
| 38 // initial load via the autoplay flag. If playback was deferred due to | |
| 39 // visibility requirements, then this does not apply. | |
| 40 GesturelessPlaybackStartedByAutoplayFlagImmediately = 6, | |
| 41 | |
| 42 // User gesture requirement was bypassed, and playback started, when | |
| 43 // the play() method was called. If playback is deferred due to | |
| 44 // visibility requirements, then this does not apply. | |
| 45 GesturelessPlaybackStartedByPlayMethodImmediately = 7, | |
| 46 | |
| 47 // User gesture requirement was bypassed, and playback started, after | |
| 48 // an element with the autoplay flag moved into the viewport. Playback | |
| 49 // was deferred earlier due to visibility requirements. | |
| 50 GesturelessPlaybackStartedByAutoplayFlagAfterScroll = 8, | |
| 51 | |
| 52 // User gesture requirement was bypassed, and playback started, after | |
| 53 // an element on which the play() method was called was moved into the | |
| 54 // viewport. Playback had been deferred due to visibility requirements. | |
| 55 GesturelessPlaybackStartedByPlayMethodAfterScroll = 9, | |
| 56 | |
| 57 // play() failed to play due to gesture requirement. | |
| 58 PlayMethodFailed = 10, | |
| 59 | |
| 60 // Some play, whether user initiated or not, started. | |
| 61 AnyPlaybackStarted = 11, | |
| 62 // Some play, whether user initiated or not, paused. | |
| 63 AnyPlaybackPaused = 12, | |
| 64 // Some playback, whether user initiated or not, bailed out early. | |
| 65 AnyPlaybackBailout = 13, | |
| 66 | |
| 67 // This enum value must be last. | |
| 68 NumberOfAutoplayMetrics, | |
| 69 }; | |
| 70 | |
| 71 class AutoplayExperimentHelper { | |
| 72 public: | |
| 73 AutoplayExperimentHelper(HTMLMediaElement&); | |
| 74 ~AutoplayExperimentHelper(); | |
| 75 | |
| 76 void becameReadyToPlay(); | |
| 77 void playMethodCalled(); | |
| 78 void pauseMethodCalled(); | |
| 79 void mutedChanged(); | |
| 80 void positionChanged(); | |
| 81 | |
| 82 // For testing. | |
| 83 void triggerAutoplayViewportCheck(); | |
| 84 | |
| 85 private: | |
| 86 // The location and size of our element, and the viewport. Also supports | |
| 87 // "not valid", in case some of the information isn't available. | |
| 88 class LocationState { | |
| 89 public: | |
| 90 LocationState() : m_valid(false) {} | |
| 91 LocationState(Element&); | |
| 92 | |
| 93 bool valid() const { return m_valid; } | |
| 94 PageVisibilityState visibilityState() const { return m_visibilityState; } | |
| 95 const IntRect& element() const { return m_element; } | |
| 96 const IntRect& screen() const { return m_screen; } | |
| 97 | |
| 98 bool operator==(const LocationState&) const; | |
| 99 bool operator!=(const LocationState&) const; | |
| 100 | |
| 101 // Return true if and only if the player is visible. | |
| 102 bool isInViewport(); | |
| 103 | |
| 104 private: | |
| 105 bool m_valid; | |
| 106 PageVisibilityState m_visibilityState; | |
| 107 IntRect m_element; | |
| 108 IntRect m_screen; | |
| 109 }; | |
| 110 | |
| 111 // Install an event listener to check for changes in visibility. If a | |
| 112 // listener is already installed, then this does nothing. | |
| 113 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
| |
| 114 | |
| 115 // Remove any event listener. It's okay to call this if one isn't | |
| 116 // installed already. | |
| 117 void clearEventListenerIfNeeded(); | |
| 118 | |
| 119 // Return true if any only if this player meets (most) of the eligibility | |
| 120 // requirements for the experiment to override the need for a user | |
| 121 // gesture. This includes everything except the visibility test. | |
| 122 bool isEligible() const; | |
| 123 | |
| 124 // Return false if and only if the player is not visible, and we care | |
| 125 // that it must be visible. | |
| 126 bool isInViewportIfNeeded(); | |
| 127 | |
| 128 // Set the muted flag on the media if we're in an experiment mode that | |
| 129 // requires it, else do nothing. | |
| 130 void muteIfNeeded(); | |
| 131 | |
| 132 // Maybe override the requirement for a user gesture, and start playing | |
| 133 // autoplay media. Returns true if only if it starts playback. | |
| 134 bool maybeStartPlaying(); | |
| 135 | |
| 136 // Configure internal state to record that the autoplay experiment is | |
| 137 // going to start playback. This doesn't actually start playback, since | |
| 138 // there are several different cases. | |
| 139 void prepareToPlay(AutoplayMetrics); | |
| 140 | |
| 141 // Process a timer for checking visibility. | |
| 142 void viewportTimerFired(Timer<AutoplayExperimentHelper>*); | |
| 143 | |
| 144 // Return our media element's document. | |
| 145 Document& document() const; | |
| 146 | |
| 147 inline bool enabled(AutoplayExperimentConfig::Mode mode) const | |
| 148 { | |
| 149 return ((int)m_mode) & ((int)mode); | |
| 150 } | |
| 151 | |
| 152 private: | |
| 153 HTMLMediaElement& m_element; | |
| 154 | |
| 155 AutoplayExperimentConfig::Mode m_mode; | |
| 156 | |
| 157 // Autoplay experiment state. | |
| 158 // True if we've received a play() without a pause(). | |
| 159 bool m_playPending : 1; | |
| 160 | |
| 161 Timer<AutoplayExperimentHelper> m_viewportTimer; | |
| 162 | |
| 163 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.
| |
| 164 | |
| 165 LocationState m_lastLocation; | |
| 166 | |
| 167 friend class Internals; | |
| 168 }; | |
| 169 | |
| 170 } // namespace blink | |
| 171 | |
| 172 #endif // AutoplayExperimentHelper_h | |
| OLD | NEW |