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

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

Powered by Google App Engine
This is Rietveld 408576698