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

Side by Side Diff: third_party/WebKit/Source/core/html/AutoplayExperimentTest.cpp

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
(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 #include "core/dom/Document.h"
6 #include "core/html/AutoplayExperimentHelper.h"
7 #include "platform/UserGestureIndicator.h"
8 #include "testing/gmock/include/gmock/gmock.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10
11 namespace blink {
12
13 using namespace testing;
14 using RecordMetricsBehavior = AutoplayExperimentHelper::Client::RecordMetricsBeh avior;
15
16 class MockAutoplayClient : public AutoplayExperimentHelper::Client {
17 public:
18 enum ElementType { Video, Audio };
19
20 MockAutoplayClient(const char* mode, ElementType type)
21 : m_mode(mode)
22 , m_duration(100)
23 {
24 // Set up default behaviors that the helper is allowed to use or cache
25 // during construction.
26
27 ON_CALL(*this, autoplayExperimentMode())
28 .WillByDefault(Return(m_mode));
29
30 // Use m_isVideo to answer these.
31 ON_CALL(*this, isHTMLVideoElement())
32 .WillByDefault(Return(type == Video));
33 ON_CALL(*this, isHTMLAudioElement())
34 .WillByDefault(Return(type == Audio));
35
36 // Now set up some useful defaults.
37 // Remember that this are only evaluated once.
38 ON_CALL(*this, duration())
39 .WillByDefault(Return(m_duration));
40 ON_CALL(*this, currentTime())
41 .WillByDefault(Return(0));
42
43 // Default to "not optimized for mobile" page.
44 ON_CALL(*this, isLegacyViewportType())
45 .WillByDefault(Return(false));
46
47 // Other handy defaults.
48 ON_CALL(*this, paused())
49 .WillByDefault(Return(true));
50 ON_CALL(*this, pageVisibilityState())
51 .WillByDefault(Return(PageVisibilityStateVisible));
52 ON_CALL(*this, absoluteBoundingBoxRect())
53 .WillByDefault(Return(
54 IntRect(10, 10, 100, 100)));
55
56 // Normally, the autoplay experiment should not modify lots of other
57 // state unless we explicitly expect it.
58 EXPECT_CALL(*this, setMuted(_))
59 .Times(0);
60 EXPECT_CALL(*this, removeUserGestureRequirement())
61 .Times(0);
62 EXPECT_CALL(*this, setRequestPositionUpdates(true))
63 .Times(0);
64 EXPECT_CALL(*this, recordAutoplayMetric(_))
65 .Times(0);
66 }
67
68 virtual ~MockAutoplayClient() {}
69
70 MOCK_CONST_METHOD0(currentTime, double());
71 MOCK_CONST_METHOD0(duration, double());
72 MOCK_CONST_METHOD0(paused, bool());
73 MOCK_CONST_METHOD0(muted, bool());
74 MOCK_METHOD1(setMuted, void(bool));
75 MOCK_METHOD0(playInternal, void());
76 MOCK_CONST_METHOD0(isUserGestureRequiredForPlay, bool());
77 MOCK_METHOD0(removeUserGestureRequirement, void());
78 MOCK_METHOD1(recordAutoplayMetric, void(AutoplayMetrics));
79 MOCK_METHOD1(shouldAutoplay, bool(RecordMetricsBehavior));
80 MOCK_CONST_METHOD0(isHTMLVideoElement, bool());
81 MOCK_CONST_METHOD0(isHTMLAudioElement, bool());
82 MOCK_METHOD0(isLegacyViewportType, bool());
83 MOCK_CONST_METHOD0(pageVisibilityState, PageVisibilityState());
84 MOCK_CONST_METHOD0(autoplayExperimentMode, String());
85 MOCK_METHOD1(setRequestPositionUpdates, void(bool));
86 MOCK_CONST_METHOD0(absoluteBoundingBoxRect, IntRect());
87
88 const char* m_mode;
89 // const since changes to it won't affect the mocked value.
90 const double m_duration;
91 };
92
93 class AutoplayExperimentTest : public ::testing::Test {
94 public:
95 AutoplayExperimentTest() {}
96
97 ~AutoplayExperimentTest() {}
98
99 bool isEligible()
100 {
101 return m_helper->isEligible();
102 }
103
104 void setInterface(PassOwnPtr<MockAutoplayClient> client)
105 {
106 m_client = client;
107
108 // Set some defaults.
109 setUserGestureRequiredForPlay(true);
110 setShouldAutoplay(true);
111 setIsMuted(false);
112
113 m_helper = adoptPtr(new AutoplayExperimentHelper(*m_client));
114 }
115
116 OwnPtr<MockAutoplayClient> m_client;
117 OwnPtr<AutoplayExperimentHelper> m_helper;
118
119 // Mirror updatePlayState to transition to play.
120 void startPlayback()
121 {
122 ON_CALL(*m_client, paused())
123 .WillByDefault(Return(false));
124 EXPECT_CALL(*m_client, recordAutoplayMetric(AnyPlaybackStarted))
125 .Times(1);
126 m_helper->playbackStarted();
127 }
128
129 void startPlaybackWithoutUserGesture()
130 {
131 EXPECT_FALSE(UserGestureIndicator::processingUserGesture());
132 startPlayback();
133 }
134
135 void startPlaybackWithUserGesture()
136 {
137 UserGestureIndicator indicator(DefinitelyProcessingUserGesture);
138 EXPECT_TRUE(UserGestureIndicator::processingUserGesture());
139 startPlayback();
140 }
141
142 void setCurrentTimeToEnd()
143 {
144 ON_CALL(*m_client, currentTime())
145 .WillByDefault(Return(m_client->m_duration));
146 }
147
148 void setUserGestureRequiredForPlay(bool required)
149 {
150 ON_CALL(*m_client, isUserGestureRequiredForPlay())
151 .WillByDefault(Return(required));
152 }
153
154 void setShouldAutoplay(bool should)
155 {
156 ON_CALL(*m_client, shouldAutoplay(_))
157 .WillByDefault(Return(should));
158 }
159
160 void setIsMuted(bool isMuted)
161 {
162 ON_CALL(*m_client, muted())
163 .WillByDefault(Return(isMuted));
164 }
165
166 void pausePlaybackExpectingBailout(bool expectingAutoplay)
167 {
168 EXPECT_CALL(*m_client, recordAutoplayMetric(AnyPlaybackPaused))
169 .Times(1);
170 EXPECT_CALL(*m_client, recordAutoplayMetric(AnyPlaybackBailout))
171 .Times(1);
172 if (expectingAutoplay) {
173 EXPECT_CALL(*m_client, recordAutoplayMetric(AutoplayPaused))
174 .Times(1);
175 EXPECT_CALL(*m_client, recordAutoplayMetric(AutoplayBailout))
176 .Times(1);
177 }
178 m_helper->pauseMethodCalled();
179 }
180
181 void pausePlaybackNotExpectingBailout(bool expectingAutoplay)
182 {
183 EXPECT_CALL(*m_client, recordAutoplayMetric(AnyPlaybackPaused))
184 .Times(1);
185 if (expectingAutoplay)
186 EXPECT_CALL(*m_client, recordAutoplayMetric(AutoplayPaused)).Times(1 );
187 EXPECT_CALL(*m_client, recordAutoplayMetric(AnyPlaybackBailout)).Times(0 );
188 EXPECT_CALL(*m_client, recordAutoplayMetric(AutoplayBailout)).Times(0);
189
190 setCurrentTimeToEnd();
191 m_helper->pauseMethodCalled();
192 }
193
194 void endPlayback(bool expectingAutoplay)
195 {
196 EXPECT_CALL(*m_client, recordAutoplayMetric(AnyPlaybackComplete))
197 .Times(1);
198 if (expectingAutoplay)
199 EXPECT_CALL(*m_client, recordAutoplayMetric(AutoplayComplete)).Times (1);
200 m_helper->playbackEnded();
201 }
202
203 void moveIntoViewport()
204 {
205 m_helper->positionChanged(IntRect(0, 0, 200, 200));
206 m_helper->triggerAutoplayViewportCheckForTesting();
207 }
208 };
209
210 TEST_F(AutoplayExperimentTest, IsNotEligibleWithEmptyMode)
211 {
212 setInterface(adoptPtr(new NiceMock<MockAutoplayClient>("", MockAutoplayClien t::Video)));
213 EXPECT_FALSE(isEligible());
214 }
215
216 TEST_F(AutoplayExperimentTest, IsVideoEligibleForVideoMode)
217 {
218 // Video should be eligible in "forvideo" mode.
219 setInterface(adoptPtr(new NiceMock<MockAutoplayClient>("enabled-forvideo", M ockAutoplayClient::Video)));
220 EXPECT_TRUE(isEligible());
221 }
222
223 TEST_F(AutoplayExperimentTest, IsAudioNotEligibleForVideoMode)
224 {
225 // Audio should not be eligible for video mode.
226 setInterface(adoptPtr(new NiceMock<MockAutoplayClient>("enabled-forvideo", M ockAutoplayClient::Audio)));
227 EXPECT_FALSE(isEligible());
228 }
229
230 TEST_F(AutoplayExperimentTest, IsEligibleRequiresUserGesture)
231 {
232 setInterface(adoptPtr(new NiceMock<MockAutoplayClient>("enabled-forvideo", M ockAutoplayClient::Video)));
233 // If a user gesture is not required, then we're not eligible.
234 ON_CALL(*m_client, isUserGestureRequiredForPlay())
235 .WillByDefault(Return(false));
236 EXPECT_FALSE(isEligible());
237 }
238
239 TEST_F(AutoplayExperimentTest, IsEligibleRequiresShouldAutoplay)
240 {
241 setInterface(adoptPtr(new NiceMock<MockAutoplayClient>("enabled-forvideo", M ockAutoplayClient::Video)));
242 // If we shouldn't autoplay, then we're not eligible.
243 ON_CALL(*m_client, shouldAutoplay(_))
244 .WillByDefault(Return(false));
245 EXPECT_FALSE(isEligible());
246 }
247
248 TEST_F(AutoplayExperimentTest, IsAudioEligibleForAudioMode)
249 {
250 setInterface(adoptPtr(new NiceMock<MockAutoplayClient>("enabled-foraudio", M ockAutoplayClient::Audio)));
251 EXPECT_TRUE(isEligible());
252 }
253
254 TEST_F(AutoplayExperimentTest, EligibleIfOptimizedForMobile)
255 {
256 setInterface(adoptPtr(new NiceMock<MockAutoplayClient>("enabled-forvideo-ifm obile", MockAutoplayClient::Video)));
257 // Should not be eligible with our default of "not mobile".
258 EXPECT_FALSE(isEligible());
259
260 ON_CALL(*m_client, isLegacyViewportType())
261 .WillByDefault(Return(true));
262 EXPECT_TRUE(isEligible());
263 }
264
265 TEST_F(AutoplayExperimentTest, EligibleIfMuted)
266 {
267 setInterface(adoptPtr(new NiceMock<MockAutoplayClient>("enabled-forvideo-ifm uted", MockAutoplayClient::Video)));
268 // Should not be eligible with our default of "not muted".
269 EXPECT_FALSE(isEligible());
270
271 ON_CALL(*m_client, muted())
272 .WillByDefault(Return(true));
273 EXPECT_TRUE(isEligible());
274 }
275
276 TEST_F(AutoplayExperimentTest, BecameReadyAutoplayThenBailout)
277 {
278 setInterface(adoptPtr(new NiceMock<MockAutoplayClient>("enabled-forvideo", M ockAutoplayClient::Video)));
279
280 EXPECT_CALL(*m_client, removeUserGestureRequirement())
281 .Times(1);
282 EXPECT_CALL(*m_client, recordAutoplayMetric(AutoplayMediaFound))
283 .Times(1);
284 m_helper->becameReadyToPlay();
285
286 EXPECT_CALL(*m_client, recordAutoplayMetric(GesturelessPlaybackStartedByAuto playFlagImmediately))
287 .Times(1);
288 startPlaybackWithoutUserGesture();
289
290 pausePlaybackExpectingBailout(true);
291 }
292
293 TEST_F(AutoplayExperimentTest, BecameReadyAutoplayThenPause)
294 {
295 setInterface(adoptPtr(new NiceMock<MockAutoplayClient>("enabled-forvideo", M ockAutoplayClient::Video)));
296
297 EXPECT_CALL(*m_client, removeUserGestureRequirement())
298 .Times(1);
299 EXPECT_CALL(*m_client, recordAutoplayMetric(AutoplayMediaFound))
300 .Times(1);
301 m_helper->becameReadyToPlay();
302
303 EXPECT_CALL(*m_client, recordAutoplayMetric(GesturelessPlaybackStartedByAuto playFlagImmediately))
304 .Times(1);
305 startPlaybackWithoutUserGesture();
306
307 pausePlaybackNotExpectingBailout(true);
308 }
309
310 TEST_F(AutoplayExperimentTest, BecameReadyAutoplayThenComplete)
311 {
312 setInterface(adoptPtr(new NiceMock<MockAutoplayClient>("enabled-forvideo", M ockAutoplayClient::Video)));
313
314 EXPECT_CALL(*m_client, removeUserGestureRequirement())
315 .Times(1);
316 EXPECT_CALL(*m_client, recordAutoplayMetric(AutoplayMediaFound))
317 .Times(1);
318 m_helper->becameReadyToPlay();
319
320 EXPECT_CALL(*m_client, recordAutoplayMetric(GesturelessPlaybackStartedByAuto playFlagImmediately))
321 .Times(1);
322 startPlaybackWithoutUserGesture();
323
324 // Now stop at the end.
325 endPlayback(true);
326 }
327
328 TEST_F(AutoplayExperimentTest, NoUserGestureNeededShouldNotOverride)
329 {
330 // Make sure that we don't override the user gesture if it isn't needed.
331 setInterface(adoptPtr(new NiceMock<MockAutoplayClient>("enabled-forvideo", M ockAutoplayClient::Video)));
332 setUserGestureRequiredForPlay(false);
333
334 // It is still autoplay media, though.
335 EXPECT_CALL(*m_client, recordAutoplayMetric(AutoplayMediaFound))
336 .Times(1);
337 m_helper->becameReadyToPlay();
338
339 EXPECT_CALL(*m_client, recordAutoplayMetric(GesturelessPlaybackNotOverridden ))
340 .Times(1);
341 startPlaybackWithoutUserGesture();
342 }
343
344 TEST_F(AutoplayExperimentTest, NoAutoplayMetricsIfNoAutoplay)
345 {
346 // If playback is started while processing a user gesture, then nothing
347 // should be overridden or logged about autoplay.
348 setInterface(adoptPtr(new NiceMock<MockAutoplayClient>("enabled-forvideo", M ockAutoplayClient::Video)));
349 setUserGestureRequiredForPlay(false);
350 setShouldAutoplay(false);
351 startPlaybackWithUserGesture();
352
353 // Expect bailout, but not from autoplay.
354 pausePlaybackExpectingBailout(false);
355 }
356
357 TEST_F(AutoplayExperimentTest, PlayMethodThenBailout)
358 {
359 setInterface(adoptPtr(new NiceMock<MockAutoplayClient>("enabled-forvideo", M ockAutoplayClient::Video)));
360 setShouldAutoplay(false); // No autoplay attribute.
361
362 EXPECT_CALL(*m_client, removeUserGestureRequirement())
363 .Times(1);
364 EXPECT_CALL(*m_client, recordAutoplayMetric(AutoplayMediaFound))
365 .Times(1);
366 m_helper->playMethodCalled();
367
368 EXPECT_CALL(*m_client, recordAutoplayMetric(GesturelessPlaybackStartedByPlay MethodImmediately))
369 .Times(1);
370 startPlaybackWithoutUserGesture();
371
372 pausePlaybackExpectingBailout(true);
373 }
374
375 TEST_F(AutoplayExperimentTest, DeferAutoplayUntilMuted)
376 {
377 setInterface(adoptPtr(new NiceMock<MockAutoplayClient>("enabled-forvideo-ifm uted", MockAutoplayClient::Video)));
378
379 // Should not override the gesture requirement yet.
380 EXPECT_CALL(*m_client, recordAutoplayMetric(AutoplayMediaFound))
381 .Times(1);
382 m_helper->becameReadyToPlay();
383
384 // When we toggle the muted attribute, it should start.
385 EXPECT_CALL(*m_client, removeUserGestureRequirement())
386 .Times(1);
387 EXPECT_CALL(*m_client, playInternal())
388 .Times(1);
389 setIsMuted(true);
390 m_helper->mutedChanged();
391
392 // When playback starts (in response to playInternal()), it should also
393 // record why. 'After scroll' isn't the best name, but this isn't a common case.
394 EXPECT_CALL(*m_client, recordAutoplayMetric(GesturelessPlaybackStartedByAuto playFlagAfterScroll))
395 .Times(1);
396 startPlaybackWithoutUserGesture();
397 }
398
399 TEST_F(AutoplayExperimentTest, DeferPlaybackUntilInViewport)
400 {
401 setInterface(adoptPtr(new NiceMock<MockAutoplayClient>("enabled-forvideo-ifv iewport", MockAutoplayClient::Video)));
402
403 // Should not override the gesture requirement yet.
404 EXPECT_CALL(*m_client, recordAutoplayMetric(AutoplayMediaFound))
405 .Times(1);
406 EXPECT_CALL(*m_client, setRequestPositionUpdates(true))
407 .Times(1);
408 m_helper->becameReadyToPlay();
409
410 EXPECT_CALL(*m_client, removeUserGestureRequirement())
411 .Times(1);
412 EXPECT_CALL(*m_client, playInternal())
413 .Times(1);
414 EXPECT_CALL(*m_client, setRequestPositionUpdates(false))
415 .Times(1);
416 moveIntoViewport();
417 }
418 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698