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

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

Powered by Google App Engine
This is Rietveld 408576698