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

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: ...because tests. Created 4 years, 8 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 was never overridden. This
88 // includes the case in which no gesture was ever required.
89 GesturelessPlaybackNotOverridden = 20,
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 public NoBaseWillBeGarbageCollectedFinalized<AutoplayExperimentHelper> {
100 friend class AutoplayExperimentTest;
101
72 public: 102 public:
73 explicit AutoplayExperimentHelper(HTMLMediaElement&); 103 // For easier testing, collect all the things we care about here.
104 class Client : public NoBaseWillBeGarbageCollectedFinalized<Client> {
105 public:
106 virtual ~Client() {}
107
108 // HTMLMediaElement
109 virtual double currentTime() const = 0;
110 virtual double duration() const = 0;
111 virtual bool ended() const = 0;
112 virtual bool muted() const = 0;
113 virtual void setMuted(bool) = 0;
114 virtual void playInternal() = 0;
115 virtual bool isUserGestureRequiredForPlay() const = 0;
116 virtual void removeUserGestureRequirement() = 0;
117 virtual void recordAutoplayMetric(AutoplayMetrics) = 0;
118 virtual bool shouldAutoplay() = 0;
119 virtual bool isHTMLVideoElement() const = 0;
120 virtual bool isHTMLAudioElement() const = 0;
121
122 // Document
123 virtual bool isLegacyViewportType() = 0;
124 virtual PageVisibilityState pageVisibilityState() const = 0;
125 virtual String autoplayExperimentMode() const = 0;
126
127 // LayoutObject
128 virtual void setRequestPositionUpdates(bool) = 0;
129 virtual IntRect absoluteBoundingBoxRect() const = 0;
130
131 DEFINE_INLINE_VIRTUAL_TRACE() { }
132 };
133
134 static PassOwnPtrWillBeRawPtr<AutoplayExperimentHelper> create(Client* clien t)
135 {
136 return adoptPtrWillBeNoop(new AutoplayExperimentHelper(client));
137 }
138
74 ~AutoplayExperimentHelper(); 139 ~AutoplayExperimentHelper();
75 140
76 void becameReadyToPlay(); 141 void becameReadyToPlay();
77 void playMethodCalled(); 142 void playMethodCalled();
78 void pauseMethodCalled(); 143 void pauseMethodCalled();
144 void loadMethodCalled();
79 void mutedChanged(); 145 void mutedChanged();
80 void positionChanged(const IntRect&); 146 void positionChanged(const IntRect&);
81 void updatePositionNotificationRegistration(); 147 void updatePositionNotificationRegistration();
148 void recordSandboxFailure();
149 void loadingStarted();
150 void playbackStarted();
151 void playbackStopped();
152 void initialPlayWithUserGesture();
82 153
154 // Clean up. For Oilpan, this means "early in HTMLMediaElement's dispose".
155 // For non-Oilpan, just delete the object.
156 void dispose();
157
158 // Remove the user gesture requirement, and record why. If there is no
159 // gesture requirement, then this does nothing.
160 void removeUserGestureRequirement(AutoplayMetrics);
161
162 // Set the position to the current view's position, and
83 void triggerAutoplayViewportCheckForTesting(); 163 void triggerAutoplayViewportCheckForTesting();
84 164
85 enum Mode { 165 enum Mode {
86 // Do not enable the autoplay experiment. 166 // Do not enable the autoplay experiment.
87 ExperimentOff = 0, 167 ExperimentOff = 0,
88 // Enable gestureless autoplay for video elements. 168 // Enable gestureless autoplay for video elements.
89 ForVideo = 1 << 0, 169 ForVideo = 1 << 0,
90 // Enable gestureless autoplay for audio elements. 170 // Enable gestureless autoplay for audio elements.
91 ForAudio = 1 << 1, 171 ForAudio = 1 << 1,
92 // Restrict gestureless autoplay to media that is in a visible page. 172 // Restrict gestureless autoplay to media that is in a visible page.
93 IfPageVisible = 1 << 2, 173 IfPageVisible = 1 << 2,
94 // Restrict gestureless autoplay to media that is visible in 174 // Restrict gestureless autoplay to media that is visible in
95 // the viewport. 175 // the viewport.
96 IfViewport = 1 << 3, 176 IfViewport = 1 << 3,
97 // Restrict gestureless autoplay to audio-less or muted media. 177 // Restrict gestureless autoplay to audio-less or muted media.
98 IfMuted = 1 << 4, 178 IfMuted = 1 << 4,
99 // Restrict gestureless autoplay to sites which contain the 179 // Restrict gestureless autoplay to sites which contain the
100 // viewport tag. 180 // viewport tag.
101 IfMobile = 1 << 5, 181 IfMobile = 1 << 5,
102 // If gestureless autoplay is allowed, then mute the media before 182 // If gestureless autoplay is allowed, then mute the media before
103 // starting to play. 183 // starting to play.
104 PlayMuted = 1 << 6, 184 PlayMuted = 1 << 6,
105 }; 185 };
106 186
107 DEFINE_INLINE_TRACE() 187 DEFINE_INLINE_TRACE() { visitor->trace(m_client); }
108 {
109 visitor->trace(m_element);
110 }
111 188
112 private: 189 private:
190 explicit AutoplayExperimentHelper(Client*);
191
113 // Register to receive position updates, if we haven't already. If we 192 // Register to receive position updates, if we haven't already. If we
114 // have, then this does nothing. 193 // have, then this does nothing.
115 void registerForPositionUpdatesIfNeeded(); 194 void registerForPositionUpdatesIfNeeded();
116 195
117 // Un-register for position updates, if we are currently registered. 196 // Un-register for position updates, if we are currently registered.
118 void unregisterForPositionUpdatesIfNeeded(); 197 void unregisterForPositionUpdatesIfNeeded();
119 198
120 // Return true if any only if this player meets (most) of the eligibility 199 // 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 200 // requirements for the experiment to override the need for a user
122 // gesture. This includes everything except the visibility test. 201 // gesture. This includes everything except the visibility test.
123 bool isEligible() const; 202 bool isEligible() const;
124 203
125 // Return false if and only if m_element is not visible, and we care 204 // Return false if and only if m_element is not visible, and we care
126 // that it must be visible. 205 // that it must be visible.
127 bool meetsVisibilityRequirements() const; 206 bool meetsVisibilityRequirements() const;
128 207
129 // Set the muted flag on the media if we're in an experiment mode that 208 // Set the muted flag on the media if we're in an experiment mode that
130 // requires it, else do nothing. 209 // requires it, else do nothing.
131 void muteIfNeeded(); 210 void muteIfNeeded();
132 211
133 // Maybe override the requirement for a user gesture, and start playing 212 // Maybe override the requirement for a user gesture, and start playing
134 // autoplay media. Returns true if only if it starts playback. 213 // autoplay media. Returns true if only if it starts playback.
135 bool maybeStartPlaying(); 214 bool maybeStartPlaying();
136 215
137 // Configure internal state to record that the autoplay experiment is 216 // Configure internal state to record that the autoplay experiment is
138 // going to start playback. This doesn't actually start playback, since 217 // going to start playback. This doesn't actually start playback, since
139 // there are several different cases. 218 // there are several different cases.
140 void prepareToPlay(AutoplayMetrics); 219 void prepareToAutoplay(AutoplayMetrics);
220
221 // Record that an attempt to play without a user gesture has happened.
222 // This does not assume whether or not the play attempt will succeed.
223 // This method takes no action after it is called once.
224 void autoplayMediaEncountered();
225
226 // If we are about to enter a paused state, call this to record
227 // autoplay metrics.
228 void recordMetricsBeforePause();
141 229
142 // Process a timer for checking visibility. 230 // Process a timer for checking visibility.
143 void viewportTimerFired(Timer<AutoplayExperimentHelper>*); 231 void viewportTimerFired(Timer<AutoplayExperimentHelper>*);
144 232
145 // Return our media element's document. 233 // Return our media element's document.
146 Document& document() const; 234 Document& document() const;
147 235
148 HTMLMediaElement& element() const; 236 Client& client() const;
237
238 bool isUserGestureRequiredForPlay() const;
149 239
150 inline bool enabled(Mode mode) const 240 inline bool enabled(Mode mode) const
151 { 241 {
152 return ((int)m_mode) & ((int)mode); 242 return ((int)m_mode) & ((int)mode);
153 } 243 }
154 244
155 Mode fromString(const String& mode); 245 Mode fromString(const String& mode);
156 246
157 RawPtrWillBeMember<HTMLMediaElement> m_element; 247 void recordAutoplayMetric(AutoplayMetrics);
248
249 // Could stopping at this point be considered a bailout of playback?
250 // (as in, "The user really didn't want to play this").
251 bool isBailout() const;
252
253 RawPtrWillBeMember<Client> m_client;
158 254
159 Mode m_mode; 255 Mode m_mode;
160 256
161 // Autoplay experiment state. 257 // Autoplay experiment state.
162 // True if we've received a play() without a pause(). 258 // True if we've received a play() without a pause().
163 bool m_playPending : 1; 259 bool m_playPending : 1;
164 260
165 // Are we registered with the view for position updates? 261 // Are we registered with the view for position updates?
166 bool m_registeredWithLayoutObject : 1; 262 bool m_registeredWithLayoutObject : 1;
167 263
168 // According to our last position update, are we in the viewport? 264 // According to our last position update, are we in the viewport?
169 bool m_wasInViewport : 1; 265 bool m_wasInViewport : 1;
170 266
267 // Have we counted this autoplay media in the metrics yet? This is set when
268 // a media element tries to autoplay, and we record that via the
269 // AutoplayMediaFound metric.
270 bool m_autoplayMediaEncountered : 1;
271
272 // Have we recorded a metric about the cause of the initial playback of
273 // this media yet?
274 bool m_playbackStartedMetricRecorded : 1;
275
276 // Is the current playback the result of autoplay? If so, then this flag
277 // records that the pause / stop should be counted in the autoplay metrics.
278 bool m_waitingForAutoplayPlaybackEnd : 1;
279
280 // Did we record that this media element exists in the metrics yet? This is
281 // independent of whether it autoplays; we just want to know how many
282 // elements exist for the Any{Audio|Video}Element metrics.
283 bool m_recordedElement : 1;
284
171 // According to our last position update, where was our element? 285 // According to our last position update, where was our element?
172 IntRect m_lastLocation; 286 IntRect m_lastLocation;
173 IntRect m_lastVisibleRect; 287 IntRect m_lastVisibleRect;
174 288
175 // When was m_lastLocation set? 289 // When was m_lastLocation set?
176 double m_lastLocationUpdateTime; 290 double m_lastLocationUpdateTime;
177 291
178 Timer<AutoplayExperimentHelper> m_viewportTimer; 292 Timer<AutoplayExperimentHelper> m_viewportTimer;
293
294 // Reason that autoplay would be allowed to proceed without a user gesture.
295 AutoplayMetrics m_autoplayDeferredMetric;
179 }; 296 };
180 297
181 inline AutoplayExperimentHelper::Mode& operator|=(AutoplayExperimentHelper::Mode & a, 298 inline AutoplayExperimentHelper::Mode& operator|=(AutoplayExperimentHelper::Mode & a,
182 const AutoplayExperimentHelper::Mode& b) 299 const AutoplayExperimentHelper::Mode& b)
183 { 300 {
184 a = static_cast<AutoplayExperimentHelper::Mode>(static_cast<int>(a) | static _cast<int>(b)); 301 a = static_cast<AutoplayExperimentHelper::Mode>(static_cast<int>(a) | static _cast<int>(b));
185 return a; 302 return a;
186 } 303 }
187 304
188
189 } // namespace blink 305 } // namespace blink
190 306
191 #endif // AutoplayExperimentHelper_h 307 #endif // AutoplayExperimentHelper_h
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/core.gypi ('k') | third_party/WebKit/Source/core/html/AutoplayExperimentHelper.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698