Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef AutoplayExperimentHelper_h | 5 #ifndef AutoplayExperimentHelper_h |
| 6 #define AutoplayExperimentHelper_h | 6 #define AutoplayExperimentHelper_h |
| 7 | 7 |
| 8 #include "core/page/Page.h" | 8 #include "core/page/Page.h" |
| 9 #include "platform/Timer.h" | 9 #include "platform/Timer.h" |
| 10 #include "platform/geometry/IntRect.h" | 10 #include "platform/geometry/IntRect.h" |
| 11 | 11 |
| 12 namespace blink { | 12 namespace blink { |
| 13 class Document; | 13 class Document; |
| 14 class HTMLMediaElement; | 14 class HTMLMediaElement; |
| 15 class EventListener; | 15 class EventListener; |
| 16 class LayoutObject; | |
| 17 class AutoplayExperimentTest; | |
| 16 | 18 |
| 17 // These values are used for a histogram. Do not reorder. | 19 // These values are used for a histogram. Do not reorder. |
| 18 enum AutoplayMetrics { | 20 enum AutoplayMetrics { |
| 19 // Media element with autoplay seen. | 21 // Media element with autoplay seen. |
| 20 AutoplayMediaFound = 0, | 22 AutoplayMediaFound = 0, |
| 21 // Autoplay enabled and user stopped media play at any point. | 23 // Autoplay enabled and user stopped media play at any point. |
| 22 AutoplayPaused = 1, | 24 AutoplayPaused = 1, |
| 23 // Autoplay enabled but user bailed out on media play early. | 25 // Autoplay enabled but user bailed out on media play early. |
| 24 AutoplayBailout = 2, | 26 AutoplayBailout = 2, |
| 25 // Autoplay disabled but user manually started media. | 27 // Autoplay disabled but user manually started media. |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 55 | 57 |
| 56 // play() failed to play due to gesture requirement. | 58 // play() failed to play due to gesture requirement. |
| 57 PlayMethodFailed = 10, | 59 PlayMethodFailed = 10, |
| 58 | 60 |
| 59 // Some play, whether user initiated or not, started. | 61 // Some play, whether user initiated or not, started. |
| 60 AnyPlaybackStarted = 11, | 62 AnyPlaybackStarted = 11, |
| 61 // Some play, whether user initiated or not, paused. | 63 // Some play, whether user initiated or not, paused. |
| 62 AnyPlaybackPaused = 12, | 64 AnyPlaybackPaused = 12, |
| 63 // Some playback, whether user initiated or not, bailed out early. | 65 // Some playback, whether user initiated or not, bailed out early. |
| 64 AnyPlaybackBailout = 13, | 66 AnyPlaybackBailout = 13, |
| 67 // Some playback, whether user initiated or not, played to completion. | |
| 68 AnyPlaybackComplete = 14, | |
| 69 | |
| 70 // Number of audio elements detected that reach the resource fetch algorithm . | |
| 71 AnyAudioElement = 15, | |
| 72 // Numer of video elements detected that reach the resource fetch algorithm. | |
| 73 AnyVideoElement = 16, | |
| 74 | |
| 75 // User gesture was bypassed, and playback started, and media played to | |
| 76 // completion without a user-initiated pause. | |
| 77 AutoplayComplete = 17, | |
| 78 | |
| 79 // Autoplay started after the gesture requirement was removed by a | |
| 80 // user gesture load(). | |
| 81 GesturelessPlaybackEnabledByLoad = 18, | |
| 82 | |
| 83 // Gestureless playback started after the gesture requirement was removed | |
| 84 // because src is media stream. | |
| 85 GesturelessPlaybackEnabledByStream = 19, | |
| 86 | |
| 87 // Gestureless playback was started, but it is unknown why a user gesture | |
| 88 // was not required. This includes the case where none is ever required. | |
| 89 GesturelessPlaybackUnknownReason = 20, | |
|
philipj_slow
2016/01/12 15:12:17
As I said in an earlier comment, there should be n
liberato (no reviews please)
2016/01/29 08:25:24
yeah, i tried to comment around it.
it is intende
philipj_slow
2016/02/02 08:08:15
Acknowledged.
| |
| 90 | |
| 91 // Gestureless playback was enabled by a user gesture play() call. | |
| 92 GesturelessPlaybackEnabledByPlayMethod = 21, | |
| 65 | 93 |
| 66 // This enum value must be last. | 94 // This enum value must be last. |
| 67 NumberOfAutoplayMetrics, | 95 NumberOfAutoplayMetrics, |
| 68 }; | 96 }; |
| 69 | 97 |
| 70 class AutoplayExperimentHelper final { | 98 class CORE_EXPORT AutoplayExperimentHelper final { |
| 71 DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); | 99 friend class blink::AutoplayExperimentTest; |
|
philipj_slow
2016/01/12 15:12:18
This is in namespace blink {}, is the prefix reall
liberato (no reviews please)
2016/01/29 08:25:24
Done.
| |
| 100 | |
| 72 public: | 101 public: |
| 73 explicit AutoplayExperimentHelper(HTMLMediaElement&); | 102 // For easier testing, collect all the things we care about here. |
| 103 class Client { | |
| 104 public: | |
| 105 virtual ~Client() {} | |
| 106 | |
| 107 // HTMLMediaElement | |
| 108 virtual double currentTime() const = 0; | |
| 109 virtual double duration() const = 0; | |
| 110 virtual bool paused() const = 0; | |
| 111 virtual bool muted() const = 0; | |
| 112 virtual void setMuted(bool) = 0; | |
| 113 virtual void playInternal() = 0; | |
| 114 virtual bool isUserGestureRequiredForPlay() const = 0; | |
| 115 virtual void removeUserGestureRequirement() = 0; | |
| 116 virtual void recordAutoplayMetric(AutoplayMetrics) = 0; | |
| 117 enum class RecordMetricsBehavior { DoNotRecord, | |
| 118 RecordOnSandboxFailure }; | |
| 119 virtual bool shouldAutoplay(RecordMetricsBehavior = RecordMetricsBehavio r::DoNotRecord) = 0; | |
| 120 virtual bool isHTMLVideoElement() const = 0; | |
| 121 virtual bool isHTMLAudioElement() const = 0; | |
| 122 | |
| 123 // Document | |
| 124 virtual bool isLegacyViewportType() = 0; | |
| 125 virtual PageVisibilityState pageVisibilityState() const = 0; | |
| 126 virtual WTF::String autoplayExperimentMode() const = 0; | |
|
philipj_slow
2016/01/12 15:12:18
Is the WTF:: prefix really needed? It's not in HTM
liberato (no reviews please)
2016/01/29 08:25:24
Done.
| |
| 127 | |
| 128 // LayoutObject | |
| 129 virtual void setRequestPositionUpdates(bool) = 0; | |
| 130 virtual IntRect absoluteBoundingBoxRect() const = 0; | |
| 131 }; | |
| 132 | |
| 133 explicit AutoplayExperimentHelper(Client&); | |
| 74 ~AutoplayExperimentHelper(); | 134 ~AutoplayExperimentHelper(); |
| 75 | 135 |
| 76 void becameReadyToPlay(); | 136 void becameReadyToPlay(); |
| 77 void playMethodCalled(); | 137 void playMethodCalled(); |
| 78 void pauseMethodCalled(); | 138 void pauseMethodCalled(); |
| 139 void loadMethodCalled(); | |
| 79 void mutedChanged(); | 140 void mutedChanged(); |
| 80 void positionChanged(const IntRect&); | 141 void positionChanged(const IntRect&); |
| 81 void updatePositionNotificationRegistration(); | 142 void updatePositionNotificationRegistration(); |
| 143 void recordSandboxFailure(); | |
| 144 void loadingStarted(); | |
| 145 void playbackStarted(); | |
| 146 void playbackEnded(); | |
| 147 void initialPlayWithUserGesture(); | |
| 82 | 148 |
| 149 // Remove the user gesture requirement, and record why. If there is no | |
| 150 // gesture requirement, then this does nothing. | |
| 151 void removeUserGestureRequirement(AutoplayMetrics); | |
| 152 | |
| 153 // Set the position to the current view's position, and | |
| 83 void triggerAutoplayViewportCheckForTesting(); | 154 void triggerAutoplayViewportCheckForTesting(); |
| 155 // | |
|
philipj_slow
2016/01/12 15:12:18
Missing comment?
liberato (no reviews please)
2016/01/29 08:25:24
i meant to delete the method.
| |
| 156 void triggerViewportTimerForTesting(); | |
| 84 | 157 |
| 85 enum Mode { | 158 enum Mode { |
| 86 // Do not enable the autoplay experiment. | 159 // Do not enable the autoplay experiment. |
| 87 ExperimentOff = 0, | 160 ExperimentOff = 0, |
| 88 // Enable gestureless autoplay for video elements. | 161 // Enable gestureless autoplay for video elements. |
| 89 ForVideo = 1 << 0, | 162 ForVideo = 1 << 0, |
| 90 // Enable gestureless autoplay for audio elements. | 163 // Enable gestureless autoplay for audio elements. |
| 91 ForAudio = 1 << 1, | 164 ForAudio = 1 << 1, |
| 92 // Restrict gestureless autoplay to media that is in a visible page. | 165 // Restrict gestureless autoplay to media that is in a visible page. |
| 93 IfPageVisible = 1 << 2, | 166 IfPageVisible = 1 << 2, |
| 94 // Restrict gestureless autoplay to media that is visible in | 167 // Restrict gestureless autoplay to media that is visible in |
| 95 // the viewport. | 168 // the viewport. |
| 96 IfViewport = 1 << 3, | 169 IfViewport = 1 << 3, |
| 97 // Restrict gestureless autoplay to audio-less or muted media. | 170 // Restrict gestureless autoplay to audio-less or muted media. |
| 98 IfMuted = 1 << 4, | 171 IfMuted = 1 << 4, |
| 99 // Restrict gestureless autoplay to sites which contain the | 172 // Restrict gestureless autoplay to sites which contain the |
| 100 // viewport tag. | 173 // viewport tag. |
| 101 IfMobile = 1 << 5, | 174 IfMobile = 1 << 5, |
| 102 // If gestureless autoplay is allowed, then mute the media before | 175 // If gestureless autoplay is allowed, then mute the media before |
| 103 // starting to play. | 176 // starting to play. |
| 104 PlayMuted = 1 << 6, | 177 PlayMuted = 1 << 6, |
| 105 }; | 178 }; |
| 106 | 179 |
| 107 DEFINE_INLINE_TRACE() | |
| 108 { | |
| 109 visitor->trace(m_element); | |
| 110 } | |
| 111 | |
| 112 private: | 180 private: |
| 113 // Register to receive position updates, if we haven't already. If we | 181 // Register to receive position updates, if we haven't already. If we |
| 114 // have, then this does nothing. | 182 // have, then this does nothing. |
| 115 void registerForPositionUpdatesIfNeeded(); | 183 void registerForPositionUpdatesIfNeeded(); |
| 116 | 184 |
| 117 // Un-register for position updates, if we are currently registered. | 185 // Un-register for position updates, if we are currently registered. |
| 118 void unregisterForPositionUpdatesIfNeeded(); | 186 void unregisterForPositionUpdatesIfNeeded(); |
| 119 | 187 |
| 120 // Return true if any only if this player meets (most) of the eligibility | 188 // Return true if any only if this player meets (most) of the eligibility |
| 121 // requirements for the experiment to override the need for a user | 189 // requirements for the experiment to override the need for a user |
| 122 // gesture. This includes everything except the visibility test. | 190 // gesture. This includes everything except the visibility test. |
| 123 bool isEligible() const; | 191 bool isEligible() const; |
| 124 | 192 |
| 125 // Return false if and only if m_element is not visible, and we care | 193 // Return false if and only if m_element is not visible, and we care |
| 126 // that it must be visible. | 194 // that it must be visible. |
| 127 bool meetsVisibilityRequirements() const; | 195 bool meetsVisibilityRequirements() const; |
| 128 | 196 |
| 129 // Set the muted flag on the media if we're in an experiment mode that | 197 // Set the muted flag on the media if we're in an experiment mode that |
| 130 // requires it, else do nothing. | 198 // requires it, else do nothing. |
| 131 void muteIfNeeded(); | 199 void muteIfNeeded(); |
| 132 | 200 |
| 133 // Maybe override the requirement for a user gesture, and start playing | 201 // Maybe override the requirement for a user gesture, and start playing |
| 134 // autoplay media. Returns true if only if it starts playback. | 202 // autoplay media. Returns true if only if it starts playback. |
| 135 bool maybeStartPlaying(); | 203 bool maybeStartPlaying(); |
| 136 | 204 |
| 137 // Configure internal state to record that the autoplay experiment is | 205 // Configure internal state to record that the autoplay experiment is |
| 138 // going to start playback. This doesn't actually start playback, since | 206 // going to start playback. This doesn't actually start playback, since |
| 139 // there are several different cases. | 207 // there are several different cases. |
| 140 void prepareToPlay(AutoplayMetrics); | 208 void prepareToAutoplay(AutoplayMetrics); |
| 209 | |
| 210 // Record that an attempt to play without a user gesture has happened. | |
| 211 // This does not assume whether or not the play attempt will succeed. | |
| 212 // This method takes no action after it is called once. | |
| 213 void autoplayMediaEncountered(); | |
| 214 | |
| 215 // If we are about to enter a paused state, call this to record | |
| 216 // autoplay metrics. | |
| 217 void recordMetricsBeforePause(); | |
| 141 | 218 |
| 142 // Process a timer for checking visibility. | 219 // Process a timer for checking visibility. |
| 143 void viewportTimerFired(Timer<AutoplayExperimentHelper>*); | 220 void viewportTimerFired(Timer<AutoplayExperimentHelper>*); |
| 144 | 221 |
| 145 // Return our media element's document. | 222 // Return our media element's document. |
| 146 Document& document() const; | 223 Document& document() const; |
| 147 | 224 |
| 148 HTMLMediaElement& element() const; | 225 Client& client() const; |
| 226 | |
| 227 bool isUserGestureRequiredForPlay() const; | |
| 149 | 228 |
| 150 inline bool enabled(Mode mode) const | 229 inline bool enabled(Mode mode) const |
| 151 { | 230 { |
| 152 return ((int)m_mode) & ((int)mode); | 231 return ((int)m_mode) & ((int)mode); |
| 153 } | 232 } |
| 154 | 233 |
| 155 Mode fromString(const String& mode); | 234 Mode fromString(const String& mode); |
| 156 | 235 |
| 157 RawPtrWillBeMember<HTMLMediaElement> m_element; | 236 void recordAutoplayMetric(AutoplayMetrics); |
| 237 | |
| 238 // Could stopping at this point be considered a bailout of playback? | |
| 239 // (as in, "The user really didn't want to play this"). | |
| 240 bool isBailout() const; | |
| 241 | |
| 242 Client& m_client; | |
| 158 | 243 |
| 159 Mode m_mode; | 244 Mode m_mode; |
| 160 | 245 |
| 161 // Autoplay experiment state. | 246 // Autoplay experiment state. |
| 162 // True if we've received a play() without a pause(). | 247 // True if we've received a play() without a pause(). |
| 163 bool m_playPending : 1; | 248 bool m_playPending : 1; |
| 164 | 249 |
| 165 // Are we registered with the view for position updates? | 250 // Are we registered with the view for position updates? |
| 166 bool m_registeredWithLayoutObject : 1; | 251 bool m_registeredWithLayoutObject : 1; |
| 167 | 252 |
| 168 // According to our last position update, are we in the viewport? | 253 // According to our last position update, are we in the viewport? |
| 169 bool m_wasInViewport : 1; | 254 bool m_wasInViewport : 1; |
| 170 | 255 |
| 256 // Have we counted this autoplay media in the metrics yet? | |
| 257 bool m_autoplayMediaCounted : 1; | |
| 258 | |
| 259 // Have we started playback of this media yet? | |
| 260 bool m_playbackStartedBefore : 1; | |
| 261 | |
| 262 // Did the first playback of the media occur without a user gesture? | |
| 263 bool m_initialPlayWithoutUserGesture : 1; | |
| 264 | |
| 265 // Did we record that this media element exists in the metrics yet? | |
| 266 bool m_recordedElement : 1; | |
|
philipj_slow
2016/01/12 15:12:18
The distinction between this and m_autoplayMediaCo
liberato (no reviews please)
2016/01/29 08:25:24
Done.
| |
| 267 | |
| 171 // According to our last position update, where was our element? | 268 // According to our last position update, where was our element? |
| 172 IntRect m_lastLocation; | 269 IntRect m_lastLocation; |
| 173 IntRect m_lastVisibleRect; | 270 IntRect m_lastVisibleRect; |
| 174 | 271 |
| 175 // When was m_lastLocation set? | 272 // When was m_lastLocation set? |
| 176 double m_lastLocationUpdateTime; | 273 double m_lastLocationUpdateTime; |
| 177 | 274 |
| 178 Timer<AutoplayExperimentHelper> m_viewportTimer; | 275 Timer<AutoplayExperimentHelper> m_viewportTimer; |
| 276 | |
| 277 // Reason that autoplay would be allowed to proceed without a user gesture. | |
| 278 AutoplayMetrics m_autoplayDeferredMetric; | |
| 179 }; | 279 }; |
| 180 | 280 |
| 181 inline AutoplayExperimentHelper::Mode& operator|=(AutoplayExperimentHelper::Mode & a, | 281 inline AutoplayExperimentHelper::Mode& operator|=(AutoplayExperimentHelper::Mode & a, |
| 182 const AutoplayExperimentHelper::Mode& b) | 282 const AutoplayExperimentHelper::Mode& b) |
| 183 { | 283 { |
| 184 a = static_cast<AutoplayExperimentHelper::Mode>(static_cast<int>(a) | static _cast<int>(b)); | 284 a = static_cast<AutoplayExperimentHelper::Mode>(static_cast<int>(a) | static _cast<int>(b)); |
| 185 return a; | 285 return a; |
| 186 } | 286 } |
| 187 | 287 |
| 188 | |
| 189 } // namespace blink | 288 } // namespace blink |
| 190 | 289 |
| 191 #endif // AutoplayExperimentHelper_h | 290 #endif // AutoplayExperimentHelper_h |
| OLD | NEW |