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

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

Issue 2510353004: Deprecating AutoplayExperimentHelper (Closed)
Patch Set: rebased Created 4 years 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
(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/page/PageVisibilityState.h"
9 #include "platform/Timer.h"
10 #include "platform/geometry/IntRect.h"
11
12 namespace blink {
13
14 class Document;
15 class AutoplayExperimentTest;
16
17 // These values are used for a histogram. Do not reorder.
18 enum AutoplayMetrics {
19 // Media element with autoplay seen.
20 AutoplayMediaFound = 0,
21 // Autoplay enabled and user stopped media play at any point.
22 AutoplayPaused = 1,
23 // Autoplay enabled but user bailed out on media play early.
24 AutoplayBailout = 2,
25 // Autoplay disabled but user manually started media.
26 AutoplayManualStart = 3,
27 // Autoplay was (re)enabled through a user-gesture triggered load()
28 AutoplayEnabledThroughLoad = 4,
29 // Autoplay disabled by sandbox flags.
30 AutoplayDisabledBySandbox = 5,
31
32 // These metrics indicate "no gesture detected, but the gesture
33 // requirement was overridden by experiment". They do not include cases
34 // where no user gesture is required (!m_userGestureRequiredForPlay).
35
36 // User gesture requirement was bypassed, and playback started, during
37 // initial load via the autoplay flag. If playback was deferred due to
38 // visibility requirements, then this does not apply.
39 GesturelessPlaybackStartedByAutoplayFlagImmediately = 6,
40
41 // User gesture requirement was bypassed, and playback started, when
42 // the play() method was called. If playback is deferred due to
43 // visibility requirements, then this does not apply.
44 GesturelessPlaybackStartedByPlayMethodImmediately = 7,
45
46 // User gesture requirement was bypassed, and playback started, after
47 // an element with the autoplay flag moved into the viewport. Playback
48 // was deferred earlier due to visibility requirements.
49 GesturelessPlaybackStartedByAutoplayFlagAfterScroll = 8,
50
51 // User gesture requirement was bypassed, and playback started, after
52 // an element on which the play() method was called was moved into the
53 // viewport. Playback had been deferred due to visibility requirements.
54 GesturelessPlaybackStartedByPlayMethodAfterScroll = 9,
55
56 // play() failed to play due to gesture requirement.
57 PlayMethodFailed = 10,
58
59 // Some play, whether user initiated or not, started.
60 AnyPlaybackStarted = 11,
61 // Some play, whether user initiated or not, paused.
62 AnyPlaybackPaused = 12,
63 // Some playback, whether user initiated or not, bailed out early.
64 AnyPlaybackBailout = 13,
65 // Some playback, whether user initiated or not, played to completion.
66 AnyPlaybackComplete = 14,
67
68 // Number of audio elements detected that reach the resource fetch algorithm.
69 AnyAudioElement = 15,
70 // Numer of video elements detected that reach the resource fetch algorithm.
71 AnyVideoElement = 16,
72
73 // User gesture was bypassed, and playback started, and media played to
74 // completion without a user-initiated pause.
75 AutoplayComplete = 17,
76
77 // Autoplay started after the gesture requirement was removed by a
78 // user gesture load().
79 GesturelessPlaybackEnabledByLoad = 18,
80
81 // Gestureless playback started after the gesture requirement was removed
82 // because src is media stream.
83 GesturelessPlaybackEnabledByStream = 19,
84
85 // Gestureless playback was started, but was never overridden. This
86 // includes the case in which no gesture was ever required.
87 GesturelessPlaybackNotOverridden = 20,
88
89 // Gestureless playback was enabled by a user gesture play() call.
90 GesturelessPlaybackEnabledByPlayMethod = 21,
91
92 // This enum value must be last.
93 NumberOfAutoplayMetrics,
94 };
95
96 class CORE_EXPORT AutoplayExperimentHelper final
97 : public GarbageCollectedFinalized<AutoplayExperimentHelper> {
98 friend class AutoplayExperimentTest;
99
100 public:
101 // For easier testing, collect all the things we care about here.
102 class Client : public GarbageCollectedFinalized<Client> {
103 public:
104 virtual ~Client() {}
105
106 // HTMLMediaElement
107 virtual double currentTime() const = 0;
108 virtual double duration() const = 0;
109 virtual bool paused() const = 0;
110 virtual bool ended() const = 0;
111 virtual bool muted() const = 0;
112 virtual void setMuted(bool) = 0;
113 virtual void playInternal() = 0;
114 virtual void pauseInternal() = 0;
115 virtual bool isLockedPendingUserGesture() const = 0;
116 virtual void unlockUserGesture() = 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 // Frame
128 virtual bool isCrossOrigin() const = 0;
129 virtual bool isAutoplayAllowedPerSettings() const = 0;
130
131 // LayoutObject
132 virtual void setRequestPositionUpdates(bool) = 0;
133 virtual IntRect absoluteBoundingBoxRect() const = 0;
134
135 DEFINE_INLINE_VIRTUAL_TRACE() {}
136 };
137
138 static AutoplayExperimentHelper* create(Client* client) {
139 return new AutoplayExperimentHelper(client);
140 }
141
142 ~AutoplayExperimentHelper();
143
144 void becameReadyToPlay();
145 void playMethodCalled();
146 void pauseMethodCalled();
147 void loadMethodCalled();
148 void mutedChanged();
149 void positionChanged(const IntRect&);
150 void updatePositionNotificationRegistration();
151 void recordSandboxFailure();
152 void loadingStarted();
153 void playbackStarted();
154 void playbackStopped();
155 void initialPlayWithUserGesture();
156
157 // Returns true if and only if any experiment is enabled (i.e., |m_mode|
158 // is not ExperimentOff).
159 bool isExperimentEnabled();
160
161 // Remove the user gesture requirement, and record why. If there is no
162 // gesture requirement, then this does nothing.
163 void unlockUserGesture(AutoplayMetrics);
164
165 // Set the reason that we're overridding the user gesture. If there is no
166 // gesture requirement, then this does nothing.
167 void setDeferredOverrideReason(AutoplayMetrics);
168
169 // Return true if and only if the user gesture requirement is currently
170 // overridden by the experiment, permitting playback.
171 bool isGestureRequirementOverridden() const;
172
173 // Return true if and only if playback is queued but hasn't started yet,
174 // such as if the element doesn't meet visibility requirements.
175 bool isPlaybackDeferred() const;
176
177 // Set the position to the current view's position, and
178 void triggerAutoplayViewportCheckForTesting();
179
180 enum Mode {
181 // Do not enable the autoplay experiment.
182 ExperimentOff = 0,
183 // Enable gestureless autoplay for video elements.
184 ForVideo = 1 << 0,
185 // Enable gestureless autoplay for audio elements.
186 ForAudio = 1 << 1,
187 // Restrict gestureless autoplay to media that is in a visible page.
188 IfPageVisible = 1 << 2,
189 // Restrict gestureless autoplay to media that is entirely visible in
190 // the viewport.
191 IfViewport = 1 << 3,
192 // Restrict gestureless autoplay to media that is partially visible in
193 // the viewport.
194 IfPartialViewport = 1 << 4,
195 // Restrict gestureless autoplay to audio-less or muted media.
196 IfMuted = 1 << 5,
197 // Restrict gestureless autoplay to sites which contain the
198 // viewport tag.
199 IfMobile = 1 << 6,
200 // Restrict gestureless autoplay to sites which are from the same origin
201 // as the top-level frame.
202 IfSameOrigin = 1 << 7,
203 // Extend IfSameOrigin to allow autoplay of cross-origin elements if
204 // they're muted. This has no effect on same-origin or if IfSameOrigin
205 // isn't enabled.
206 OrMuted = 1 << 8,
207 // If gestureless autoplay is allowed, then mute the media before
208 // starting to play.
209 PlayMuted = 1 << 9,
210 };
211
212 DEFINE_INLINE_TRACE() { visitor->trace(m_client); }
213
214 private:
215 explicit AutoplayExperimentHelper(Client*);
216
217 // Register to receive position updates, if we haven't already. If we
218 // have, then this does nothing.
219 void registerForPositionUpdatesIfNeeded();
220
221 // Un-register for position updates, if we are currently registered.
222 void unregisterForPositionUpdatesIfNeeded();
223
224 // Modifiers for checking isEligible().
225 enum EligibilityMode {
226 // Perform all normal eligibility checks.
227 Normal = 0,
228
229 // Perform normal eligibility checks, but skip checking if autoplay has
230 // actually been requested. In other words, don't fail just becase
231 // nobody has called play() and/or set the autoplay attribute.
232 IgnorePendingPlayback = 1
233 };
234
235 // Return true if any only if this player meets (most) of the eligibility
236 // requirements for the experiment to override the need for a user
237 // gesture. This includes everything except the visibility test.
238 // |mode| modifies the eligibility check, as described above.
239 bool isEligible(EligibilityMode = Normal) const;
240
241 // Return false if and only if m_element is not visible, and we care
242 // that it must be visible.
243 bool meetsVisibilityRequirements() const;
244
245 // Set the muted flag on the media if we're in an experiment mode that
246 // requires it, else do nothing.
247 void muteIfNeeded();
248
249 // Maybe override the requirement for a user gesture, and start playing
250 // autoplay media. Returns true if only if it starts playback.
251 bool maybeStartPlaying();
252
253 // Configure internal state to record that the autoplay experiment is
254 // going to start playback. This doesn't actually start playback, since
255 // there are several different cases.
256 void prepareToAutoplay(AutoplayMetrics);
257
258 // Record that an attempt to play without a user gesture has happened.
259 // This does not assume whether or not the play attempt will succeed.
260 // This method takes no action after it is called once.
261 void autoplayMediaEncountered();
262
263 // If we are about to enter a paused state, call this to record
264 // autoplay metrics.
265 void recordMetricsBeforePause();
266
267 // Process a timer for checking visibility.
268 void viewportTimerFired(TimerBase*);
269
270 Client& client() const { return *m_client; }
271
272 bool isLockedPendingUserGesture() const;
273
274 inline bool enabled(Mode mode) const {
275 return static_cast<int>(m_mode) & static_cast<int>(mode);
276 }
277
278 Mode fromString(const String& mode);
279
280 void recordAutoplayMetric(AutoplayMetrics);
281
282 // Could stopping at this point be considered a bailout of playback?
283 // (as in, "The user really didn't want to play this").
284 bool isBailout() const;
285
286 // Returns true if and only if the experiment requires some sort of viewport
287 // visibility check for autoplay.
288 bool requiresViewportVisibility() const;
289
290 Member<Client> m_client;
291
292 Mode m_mode;
293
294 // Autoplay experiment state.
295 // True if we've received a play() without a pause().
296 bool m_playPending : 1;
297
298 // Are we registered with the view for position updates?
299 bool m_registeredWithLayoutObject : 1;
300
301 // According to our last position update, are we in the viewport?
302 bool m_wasInViewport : 1;
303
304 // Have we counted this autoplay media in the metrics yet? This is set when
305 // a media element tries to autoplay, and we record that via the
306 // AutoplayMediaFound metric.
307 bool m_autoplayMediaEncountered : 1;
308
309 // Have we recorded a metric about the cause of the initial playback of
310 // this media yet?
311 bool m_playbackStartedMetricRecorded : 1;
312
313 // Is the current playback the result of autoplay? If so, then this flag
314 // records that the pause / stop should be counted in the autoplay metrics.
315 bool m_waitingForAutoplayPlaybackStop : 1;
316
317 // Did we record that this media element exists in the metrics yet? This is
318 // independent of whether it autoplays; we just want to know how many
319 // elements exist for the Any{Audio|Video}Element metrics.
320 bool m_recordedElement : 1;
321
322 // According to our last position update, where was our element?
323 IntRect m_lastLocation;
324 IntRect m_lastVisibleRect;
325
326 // When was m_lastLocation set?
327 double m_lastLocationUpdateTime;
328
329 Timer<AutoplayExperimentHelper> m_viewportTimer;
330
331 // Reason that autoplay would be allowed to proceed without a user gesture.
332 AutoplayMetrics m_autoplayDeferredMetric;
333 };
334
335 inline AutoplayExperimentHelper::Mode& operator|=(
336 AutoplayExperimentHelper::Mode& a,
337 const AutoplayExperimentHelper::Mode& b) {
338 a = static_cast<AutoplayExperimentHelper::Mode>(static_cast<int>(a) |
339 static_cast<int>(b));
340 return a;
341 }
342
343 } // namespace blink
344
345 #endif // AutoplayExperimentHelper_h
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/frame/Settings.in ('k') | third_party/WebKit/Source/core/html/AutoplayExperimentHelper.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698