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

Side by Side Diff: third_party/WebKit/Source/core/html/AutoplayExperimentHelper.h

Issue 1470153004: Autoplay experiment metric fixes and additions. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebased. Created 4 years, 11 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 unified diff | Download patch
OLDNEW
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698