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

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

Powered by Google App Engine
This is Rietveld 408576698