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

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

Issue 1470153004: Autoplay experiment metric fixes and additions. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: more oilpan. 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
1 /* 1 /*
2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved. 2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 19 matching lines...) Expand all
30 #include "bindings/core/v8/ScriptController.h" 30 #include "bindings/core/v8/ScriptController.h"
31 #include "bindings/core/v8/ScriptEventListener.h" 31 #include "bindings/core/v8/ScriptEventListener.h"
32 #include "bindings/core/v8/ScriptPromiseResolver.h" 32 #include "bindings/core/v8/ScriptPromiseResolver.h"
33 #include "core/HTMLNames.h" 33 #include "core/HTMLNames.h"
34 #include "core/css/MediaList.h" 34 #include "core/css/MediaList.h"
35 #include "core/dom/Attribute.h" 35 #include "core/dom/Attribute.h"
36 #include "core/dom/ElementTraversal.h" 36 #include "core/dom/ElementTraversal.h"
37 #include "core/dom/Fullscreen.h" 37 #include "core/dom/Fullscreen.h"
38 #include "core/dom/shadow/ShadowRoot.h" 38 #include "core/dom/shadow/ShadowRoot.h"
39 #include "core/events/Event.h" 39 #include "core/events/Event.h"
40 #include "core/frame/FrameView.h"
40 #include "core/frame/LocalFrame.h" 41 #include "core/frame/LocalFrame.h"
41 #include "core/frame/Settings.h" 42 #include "core/frame/Settings.h"
42 #include "core/frame/UseCounter.h" 43 #include "core/frame/UseCounter.h"
43 #include "core/frame/csp/ContentSecurityPolicy.h" 44 #include "core/frame/csp/ContentSecurityPolicy.h"
44 #include "core/html/HTMLMediaSource.h" 45 #include "core/html/HTMLMediaSource.h"
45 #include "core/html/HTMLSourceElement.h" 46 #include "core/html/HTMLSourceElement.h"
46 #include "core/html/HTMLTrackElement.h" 47 #include "core/html/HTMLTrackElement.h"
47 #include "core/html/MediaError.h" 48 #include "core/html/MediaError.h"
48 #include "core/html/MediaFragmentURIParser.h" 49 #include "core/html/MediaFragmentURIParser.h"
49 #include "core/html/TimeRanges.h" 50 #include "core/html/TimeRanges.h"
50 #include "core/html/shadow/MediaControls.h" 51 #include "core/html/shadow/MediaControls.h"
51 #include "core/html/track/AudioTrack.h" 52 #include "core/html/track/AudioTrack.h"
52 #include "core/html/track/AudioTrackList.h" 53 #include "core/html/track/AudioTrackList.h"
53 #include "core/html/track/AutomaticTrackSelection.h" 54 #include "core/html/track/AutomaticTrackSelection.h"
54 #include "core/html/track/CueTimeline.h" 55 #include "core/html/track/CueTimeline.h"
55 #include "core/html/track/InbandTextTrack.h" 56 #include "core/html/track/InbandTextTrack.h"
56 #include "core/html/track/TextTrackContainer.h" 57 #include "core/html/track/TextTrackContainer.h"
57 #include "core/html/track/TextTrackList.h" 58 #include "core/html/track/TextTrackList.h"
58 #include "core/html/track/VideoTrack.h" 59 #include "core/html/track/VideoTrack.h"
59 #include "core/html/track/VideoTrackList.h" 60 #include "core/html/track/VideoTrackList.h"
60 #include "core/inspector/ConsoleMessage.h" 61 #include "core/inspector/ConsoleMessage.h"
61 #include "core/layout/LayoutVideo.h" 62 #include "core/layout/LayoutVideo.h"
62 #include "core/layout/LayoutView.h" 63 #include "core/layout/LayoutView.h"
64 #include "core/layout/api/LayoutMediaItem.h"
63 #include "core/layout/compositing/PaintLayerCompositor.h" 65 #include "core/layout/compositing/PaintLayerCompositor.h"
64 #include "core/loader/FrameLoader.h" 66 #include "core/loader/FrameLoader.h"
65 #include "core/loader/FrameLoaderClient.h" 67 #include "core/loader/FrameLoaderClient.h"
66 #include "core/page/ChromeClient.h" 68 #include "core/page/ChromeClient.h"
67 #include "core/page/NetworkStateNotifier.h" 69 #include "core/page/NetworkStateNotifier.h"
68 #include "platform/ContentType.h" 70 #include "platform/ContentType.h"
69 #include "platform/Histogram.h" 71 #include "platform/Histogram.h"
70 #include "platform/LayoutTestSupport.h" 72 #include "platform/LayoutTestSupport.h"
71 #include "platform/Logging.h" 73 #include "platform/Logging.h"
72 #include "platform/MIMETypeFromURL.h" 74 #include "platform/MIMETypeFromURL.h"
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 if (contentMIMEType != "application/octet-stream" || contentTypeCodecs.isEmp ty()) { 248 if (contentMIMEType != "application/octet-stream" || contentTypeCodecs.isEmp ty()) {
247 WebMimeRegistry::SupportsType supported = Platform::current()->mimeRegis try()->supportsMediaMIMEType(contentMIMEType, contentTypeCodecs); 249 WebMimeRegistry::SupportsType supported = Platform::current()->mimeRegis try()->supportsMediaMIMEType(contentMIMEType, contentTypeCodecs);
248 return supported > WebMimeRegistry::IsNotSupported; 250 return supported > WebMimeRegistry::IsNotSupported;
249 } 251 }
250 252
251 return false; 253 return false;
252 } 254 }
253 255
254 } // anonymous namespace 256 } // anonymous namespace
255 257
258 class HTMLMediaElement::AutoplayHelperClientImpl :
259 public AutoplayExperimentHelper::Client {
260
261 public:
262 static PassOwnPtrWillBeRawPtr<AutoplayHelperClientImpl> create(HTMLMediaElem ent* element)
263 {
264 return adoptPtrWillBeNoop(new AutoplayHelperClientImpl(element));
265 }
266
267 virtual ~AutoplayHelperClientImpl();
268
269 using RecordMetricsBehavior = HTMLMediaElement::RecordMetricsBehavior;
270
271 double currentTime() const override { return m_element->currentTime(); }
272 double duration() const override { return m_element->duration(); }
273 bool paused() const override
274 {
275 bool isPlaying = m_element->webMediaPlayer()
276 &&!m_element->webMediaPlayer()->paused();
liberato (no reviews please) 2016/03/15 14:10:49 here. sorry, i forgot that i rebased somewhere in
philipj_slow 2016/03/16 11:37:43 Looks a bit odd to check both the paused state (wh
liberato (no reviews please) 2016/03/16 14:59:58 i added a comment. i also tried removing m_paused
277 return m_element->paused() || !isPlaying;
278 }
279 bool muted() const override { return m_element->muted(); }
280 void setMuted(bool muted) override { m_element->setMuted(muted); }
281 void playInternal() override { m_element->playInternal(); }
282 bool isUserGestureRequiredForPlay() const override { return m_element->isUse rGestureRequiredForPlay(); }
283 void removeUserGestureRequirement() override { m_element->removeUserGestureR equirement(); }
284 void recordAutoplayMetric(AutoplayMetrics metric) override { m_element->reco rdAutoplayMetric(metric); }
285 bool shouldAutoplay() override
286 {
287 return m_element->shouldAutoplay(RecordMetricsBehavior::DoNotRecord);
288 }
289 bool isHTMLVideoElement() const override { return m_element->isHTMLVideoElem ent(); }
290 bool isHTMLAudioElement() const override { return m_element->isHTMLAudioElem ent(); }
291
292 // Document
293 bool isLegacyViewportType() override;
294 PageVisibilityState pageVisibilityState() const override;
295 String autoplayExperimentMode() const override;
296
297 // LayoutObject
298 void setRequestPositionUpdates(bool) override;
299 IntRect absoluteBoundingBoxRect() const override;
300
301 DEFINE_INLINE_VIRTUAL_TRACE()
302 {
303 visitor->trace(m_element);
304 Client::trace(visitor);
305 }
306
307 private:
308 AutoplayHelperClientImpl(HTMLMediaElement* element) : m_element(element) {}
309
310 RawPtrWillBeMember<HTMLMediaElement> m_element;
311 };
312
313
256 void HTMLMediaElement::recordAutoplayMetric(AutoplayMetrics metric) 314 void HTMLMediaElement::recordAutoplayMetric(AutoplayMetrics metric)
257 { 315 {
258 DEFINE_STATIC_LOCAL(EnumerationHistogram, autoplayHistogram, ("Blink.MediaEl ement.Autoplay", NumberOfAutoplayMetrics)); 316 DEFINE_STATIC_LOCAL(EnumerationHistogram, autoplayHistogram, ("Blink.MediaEl ement.Autoplay", NumberOfAutoplayMetrics));
259 autoplayHistogram.count(metric); 317 autoplayHistogram.count(metric);
260 } 318 }
261 319
262 WebMimeRegistry::SupportsType HTMLMediaElement::supportsType(const ContentType& contentType) 320 WebMimeRegistry::SupportsType HTMLMediaElement::supportsType(const ContentType& contentType)
263 { 321 {
264 DEFINE_STATIC_LOCAL(const String, codecs, ("codecs")); 322 DEFINE_STATIC_LOCAL(const String, codecs, ("codecs"));
265 323
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 , m_seeking(false) 389 , m_seeking(false)
332 , m_sentStalledEvent(false) 390 , m_sentStalledEvent(false)
333 , m_sentEndEvent(false) 391 , m_sentEndEvent(false)
334 , m_closedCaptionsVisible(false) 392 , m_closedCaptionsVisible(false)
335 , m_havePreparedToPlay(false) 393 , m_havePreparedToPlay(false)
336 , m_tracksAreReady(true) 394 , m_tracksAreReady(true)
337 , m_processingPreferenceChange(false) 395 , m_processingPreferenceChange(false)
338 , m_remoteRoutesAvailable(false) 396 , m_remoteRoutesAvailable(false)
339 , m_playingRemotely(false) 397 , m_playingRemotely(false)
340 , m_isFinalizing(false) 398 , m_isFinalizing(false)
341 , m_initialPlayWithoutUserGesture(false)
342 , m_autoplayMediaCounted(false)
343 , m_inOverlayFullscreenVideo(false) 399 , m_inOverlayFullscreenVideo(false)
344 , m_audioTracks(AudioTrackList::create(*this)) 400 , m_audioTracks(AudioTrackList::create(*this))
345 , m_videoTracks(VideoTrackList::create(*this)) 401 , m_videoTracks(VideoTrackList::create(*this))
346 , m_textTracks(nullptr) 402 , m_textTracks(nullptr)
347 , m_playPromiseResolveTask(CancellableTaskFactory::create(this, &HTMLMediaEl ement::resolvePlayPromises)) 403 , m_playPromiseResolveTask(CancellableTaskFactory::create(this, &HTMLMediaEl ement::resolvePlayPromises))
348 , m_playPromiseRejectTask(CancellableTaskFactory::create(this, &HTMLMediaEle ment::rejectPlayPromises)) 404 , m_playPromiseRejectTask(CancellableTaskFactory::create(this, &HTMLMediaEle ment::rejectPlayPromises))
349 , m_audioSourceNode(nullptr) 405 , m_audioSourceNode(nullptr)
350 , m_autoplayHelper(*this) 406 , m_autoplayHelperClient(AutoplayHelperClientImpl::create(this))
407 , m_autoplayHelper(AutoplayExperimentHelper::create(m_autoplayHelperClient.g et()))
351 { 408 {
352 #if ENABLE(OILPAN) 409 #if ENABLE(OILPAN)
353 ThreadState::current()->registerPreFinalizer(this); 410 ThreadState::current()->registerPreFinalizer(this);
354 #endif 411 #endif
355 412
356 WTF_LOG(Media, "HTMLMediaElement::HTMLMediaElement(%p)", this); 413 WTF_LOG(Media, "HTMLMediaElement::HTMLMediaElement(%p)", this);
357 414
358 if (document.settings() && document.settings()->mediaPlaybackRequiresUserGes ture()) 415 if (document.settings() && document.settings()->mediaPlaybackRequiresUserGes ture())
359 m_userGestureRequiredForPlay = true; 416 m_userGestureRequiredForPlay = true;
360 417
361 setHasCustomStyleCallbacks(); 418 setHasCustomStyleCallbacks();
362 addElementToDocumentMap(this, &document); 419 addElementToDocumentMap(this, &document);
363 420
364 UseCounter::count(document, UseCounter::HTMLMediaElement); 421 UseCounter::count(document, UseCounter::HTMLMediaElement);
365 } 422 }
366 423
367 HTMLMediaElement::~HTMLMediaElement() 424 HTMLMediaElement::~HTMLMediaElement()
368 { 425 {
369 WTF_LOG(Media, "HTMLMediaElement::~HTMLMediaElement(%p)", this); 426 WTF_LOG(Media, "HTMLMediaElement::~HTMLMediaElement(%p)", this);
370 427
371 #if !ENABLE(OILPAN) 428 #if !ENABLE(OILPAN)
429 // Destruction of the autoplay helper requires the client, so be sure that
430 // this happens before the client is destructed.
431 if (m_autoplayHelper)
432 m_autoplayHelper.clear();
433
372 // HTMLMediaElement and m_asyncEventQueue always become unreachable 434 // HTMLMediaElement and m_asyncEventQueue always become unreachable
373 // together. So HTMLMediaElement and m_asyncEventQueue are destructed in 435 // together. So HTMLMediaElement and m_asyncEventQueue are destructed in
374 // the same GC. We don't need to close it explicitly in Oilpan. 436 // the same GC. We don't need to close it explicitly in Oilpan.
375 m_asyncEventQueue->close(); 437 m_asyncEventQueue->close();
376 438
377 setShouldDelayLoadEvent(false); 439 setShouldDelayLoadEvent(false);
378 440
379 if (m_textTracks) 441 if (m_textTracks)
380 m_textTracks->clearOwner(); 442 m_textTracks->clearOwner();
381 m_audioTracks->shutdown(); 443 m_audioTracks->shutdown();
(...skipping 19 matching lines...) Expand all
401 // m_audioSourceNode is explicitly cleared by AudioNode::dispose(). 463 // m_audioSourceNode is explicitly cleared by AudioNode::dispose().
402 // Since AudioNode::dispose() is guaranteed to be always called before 464 // Since AudioNode::dispose() is guaranteed to be always called before
403 // the AudioNode is destructed, m_audioSourceNode is explicitly cleared 465 // the AudioNode is destructed, m_audioSourceNode is explicitly cleared
404 // even if the AudioNode and the HTMLMediaElement die together. 466 // even if the AudioNode and the HTMLMediaElement die together.
405 ASSERT(!m_audioSourceNode); 467 ASSERT(!m_audioSourceNode);
406 } 468 }
407 469
408 #if ENABLE(OILPAN) 470 #if ENABLE(OILPAN)
409 void HTMLMediaElement::dispose() 471 void HTMLMediaElement::dispose()
410 { 472 {
473 // This must happen before we're destructed.
474 if (m_autoplayHelper)
475 m_autoplayHelper->dispose();
476
411 // If the HTMLMediaElement dies with the Document we are not 477 // If the HTMLMediaElement dies with the Document we are not
412 // allowed to touch the Document to adjust delay load event counts 478 // allowed to touch the Document to adjust delay load event counts
413 // from the destructor, as the Document could have been already 479 // from the destructor, as the Document could have been already
414 // destructed. 480 // destructed.
415 // 481 //
416 // Work around that restriction by accessing the Document from 482 // Work around that restriction by accessing the Document from
417 // a prefinalizer action instead, updating its delayed load count. 483 // a prefinalizer action instead, updating its delayed load count.
418 // If needed - if the Document has been detached and informed its 484 // If needed - if the Document has been detached and informed its
419 // ContextLifecycleObservers (which HTMLMediaElement is) that 485 // ContextLifecycleObservers (which HTMLMediaElement is) that
420 // it is being destroyed, the connection to the Document will 486 // it is being destroyed, the connection to the Document will
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
661 case WebMimeRegistry::IsSupported: 727 case WebMimeRegistry::IsSupported:
662 canPlay = "probably"; 728 canPlay = "probably";
663 break; 729 break;
664 } 730 }
665 731
666 WTF_LOG(Media, "HTMLMediaElement::canPlayType(%p, %s) -> %s", this, mimeType .utf8().data(), canPlay.utf8().data()); 732 WTF_LOG(Media, "HTMLMediaElement::canPlayType(%p, %s) -> %s", this, mimeType .utf8().data(), canPlay.utf8().data());
667 733
668 return canPlay; 734 return canPlay;
669 } 735 }
670 736
671 void HTMLMediaElement::recordMetricsIfPausing()
672 {
673 // If not playing, then nothing to record.
674 // TODO(liberato): test metrics. this was m_paused.
675 if (m_paused)
676 return;
677
678 const bool bailout = isBailout();
679
680 // Record that play was paused. We don't care if it was autoplay,
681 // play(), or the user manually started it.
682 recordAutoplayMetric(AnyPlaybackPaused);
683 if (bailout)
684 recordAutoplayMetric(AnyPlaybackBailout);
685
686 // If this was a gestureless play, then record that separately.
687 // These cover attr and play() gestureless starts.
688 if (m_initialPlayWithoutUserGesture) {
689 m_initialPlayWithoutUserGesture = false;
690
691 recordAutoplayMetric(AutoplayPaused);
692
693 if (bailout)
694 recordAutoplayMetric(AutoplayBailout);
695 }
696 }
697
698 void HTMLMediaElement::load() 737 void HTMLMediaElement::load()
699 { 738 {
700 WTF_LOG(Media, "HTMLMediaElement::load(%p)", this); 739 WTF_LOG(Media, "HTMLMediaElement::load(%p)", this);
701 740
702 recordMetricsIfPausing(); 741 m_autoplayHelper->loadMethodCalled();
703
704 if (UserGestureIndicator::processingUserGesture() && m_userGestureRequiredFo rPlay) {
705 recordAutoplayMetric(AutoplayEnabledThroughLoad);
706 m_userGestureRequiredForPlay = false;
707 // While usergesture-initiated load()s technically count as autoplayed,
708 // they don't feel like such to the users and hence we don't want to
709 // count them for the purposes of metrics.
710 m_autoplayMediaCounted = true;
711 }
712 742
713 prepareForLoad(); 743 prepareForLoad();
714 loadInternal(); 744 loadInternal();
715 prepareToPlay(); 745 prepareToPlay();
716 } 746 }
717 747
718 void HTMLMediaElement::prepareForLoad() 748 void HTMLMediaElement::prepareForLoad()
719 { 749 {
720 WTF_LOG(Media, "HTMLMediaElement::prepareForLoad(%p)", this); 750 WTF_LOG(Media, "HTMLMediaElement::prepareForLoad(%p)", this);
721 751
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
925 955
926 LocalFrame* frame = document().frame(); 956 LocalFrame* frame = document().frame();
927 if (!frame) { 957 if (!frame) {
928 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError); 958 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError);
929 return; 959 return;
930 } 960 }
931 961
932 // The resource fetch algorithm 962 // The resource fetch algorithm
933 setNetworkState(NETWORK_LOADING); 963 setNetworkState(NETWORK_LOADING);
934 964
965 m_autoplayHelper->loadingStarted();
966
935 // Set m_currentSrc *before* changing to the cache url, the fact that we are loading from the app 967 // Set m_currentSrc *before* changing to the cache url, the fact that we are loading from the app
936 // cache is an internal detail not exposed through the media element API. 968 // cache is an internal detail not exposed through the media element API.
937 m_currentSrc = url; 969 m_currentSrc = url;
938 970
939 if (m_audioSourceNode) 971 if (m_audioSourceNode)
940 m_audioSourceNode->onCurrentSrcChanged(m_currentSrc); 972 m_audioSourceNode->onCurrentSrcChanged(m_currentSrc);
941 973
942 WTF_LOG(Media, "HTMLMediaElement::loadResource(%p) - m_currentSrc -> %s", th is, urlForLoggingMedia(m_currentSrc).utf8().data()); 974 WTF_LOG(Media, "HTMLMediaElement::loadResource(%p) - m_currentSrc -> %s", th is, urlForLoggingMedia(m_currentSrc).utf8().data());
943 975
944 startProgressEventTimer(); 976 startProgressEventTimer();
945 977
946 // Reset display mode to force a recalculation of what to show because we ar e resetting the player. 978 // Reset display mode to force a recalculation of what to show because we ar e resetting the player.
947 setDisplayMode(Unknown); 979 setDisplayMode(Unknown);
948 980
949 setPlayerPreload(); 981 setPlayerPreload();
950 982
951 if (fastHasAttribute(mutedAttr)) 983 if (fastHasAttribute(mutedAttr))
952 m_muted = true; 984 m_muted = true;
953 updateVolume(); 985 updateVolume();
954 986
955 ASSERT(!m_mediaSource); 987 ASSERT(!m_mediaSource);
956 988
957 bool attemptLoad = true; 989 bool attemptLoad = true;
958 990
959 if (url.protocolIs(mediaSourceBlobProtocol)) { 991 if (url.protocolIs(mediaSourceBlobProtocol)) {
960 if (isMediaStreamURL(url.getString())) { 992 if (isMediaStreamURL(url.getString())) {
961 m_userGestureRequiredForPlay = false; 993 m_autoplayHelper->removeUserGestureRequirement(GesturelessPlaybackEn abledByStream);
962 } else { 994 } else {
963 m_mediaSource = HTMLMediaSource::lookup(url.getString()); 995 m_mediaSource = HTMLMediaSource::lookup(url.getString());
964 996
965 if (m_mediaSource) { 997 if (m_mediaSource) {
966 if (!m_mediaSource->attachToElement(this)) { 998 if (!m_mediaSource->attachToElement(this)) {
967 // Forget our reference to the MediaSource, so we leave it a lone 999 // Forget our reference to the MediaSource, so we leave it a lone
968 // while processing remainder of load failure. 1000 // while processing remainder of load failure.
969 m_mediaSource = nullptr; 1001 m_mediaSource = nullptr;
970 attemptLoad = false; 1002 attemptLoad = false;
971 } 1003 }
(...skipping 568 matching lines...) Expand 10 before | Expand all | Expand 10 after
1540 if (oldState <= HAVE_CURRENT_DATA) { 1572 if (oldState <= HAVE_CURRENT_DATA) {
1541 scheduleEvent(EventTypeNames::canplay); 1573 scheduleEvent(EventTypeNames::canplay);
1542 if (isPotentiallyPlaying) 1574 if (isPotentiallyPlaying)
1543 scheduleNotifyPlaying(); 1575 scheduleNotifyPlaying();
1544 } 1576 }
1545 1577
1546 // Check for autoplay, and record metrics about it if needed. 1578 // Check for autoplay, and record metrics about it if needed.
1547 if (shouldAutoplay(RecordMetricsBehavior::DoRecord)) { 1579 if (shouldAutoplay(RecordMetricsBehavior::DoRecord)) {
1548 // If the autoplay experiment says that it's okay to play now, 1580 // If the autoplay experiment says that it's okay to play now,
1549 // then don't require a user gesture. 1581 // then don't require a user gesture.
1550 m_autoplayHelper.becameReadyToPlay(); 1582 m_autoplayHelper->becameReadyToPlay();
1551 1583
1552 if (!m_userGestureRequiredForPlay) { 1584 if (!m_userGestureRequiredForPlay) {
1553 m_paused = false; 1585 m_paused = false;
1554 invalidateCachedTime(); 1586 invalidateCachedTime();
1555 scheduleEvent(EventTypeNames::play); 1587 scheduleEvent(EventTypeNames::play);
1556 scheduleNotifyPlaying(); 1588 scheduleNotifyPlaying();
1557 m_autoplaying = false; 1589 m_autoplaying = false;
1558 } 1590 }
1559 } 1591 }
1560 1592
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1679 1711
1680 m_lastSeekTime = time; 1712 m_lastSeekTime = time;
1681 m_sentEndEvent = false; 1713 m_sentEndEvent = false;
1682 1714
1683 // 10 - Queue a task to fire a simple event named seeking at the element. 1715 // 10 - Queue a task to fire a simple event named seeking at the element.
1684 scheduleEvent(EventTypeNames::seeking); 1716 scheduleEvent(EventTypeNames::seeking);
1685 1717
1686 // 11 - Set the current playback position to the given new playback position . 1718 // 11 - Set the current playback position to the given new playback position .
1687 webMediaPlayer()->seek(time); 1719 webMediaPlayer()->seek(time);
1688 1720
1689 m_initialPlayWithoutUserGesture = false;
1690
1691 // 14-17 are handled, if necessary, when the engine signals a readystate cha nge or otherwise 1721 // 14-17 are handled, if necessary, when the engine signals a readystate cha nge or otherwise
1692 // satisfies seek completion and signals a time change. 1722 // satisfies seek completion and signals a time change.
1693 } 1723 }
1694 1724
1695 void HTMLMediaElement::finishSeek() 1725 void HTMLMediaElement::finishSeek()
1696 { 1726 {
1697 WTF_LOG(Media, "HTMLMediaElement::finishSeek(%p)", this); 1727 WTF_LOG(Media, "HTMLMediaElement::finishSeek(%p)", this);
1698 1728
1699 // 14 - Set the seeking IDL attribute to false. 1729 // 14 - Set the seeking IDL attribute to false.
1700 m_seeking = false; 1730 m_seeking = false;
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
1864 } 1894 }
1865 1895
1866 bool HTMLMediaElement::autoplay() const 1896 bool HTMLMediaElement::autoplay() const
1867 { 1897 {
1868 return fastHasAttribute(autoplayAttr); 1898 return fastHasAttribute(autoplayAttr);
1869 } 1899 }
1870 1900
1871 bool HTMLMediaElement::shouldAutoplay(const RecordMetricsBehavior recordMetrics) 1901 bool HTMLMediaElement::shouldAutoplay(const RecordMetricsBehavior recordMetrics)
1872 { 1902 {
1873 if (m_autoplaying && m_paused && autoplay()) { 1903 if (m_autoplaying && m_paused && autoplay()) {
1874 if (recordMetrics == RecordMetricsBehavior::DoRecord)
1875 autoplayMediaEncountered();
1876
1877 if (document().isSandboxed(SandboxAutomaticFeatures)) { 1904 if (document().isSandboxed(SandboxAutomaticFeatures)) {
1878 if (recordMetrics == RecordMetricsBehavior::DoRecord) 1905 if (recordMetrics == RecordMetricsBehavior::DoRecord)
1879 recordAutoplayMetric(AutoplayDisabledBySandbox); 1906 m_autoplayHelper->recordSandboxFailure();
1880 return false; 1907 return false;
1881 } 1908 }
1882 1909
1883 return true; 1910 return true;
1884 } 1911 }
1885 1912
1886 return false; 1913 return false;
1887 } 1914 }
1888 1915
1889 String HTMLMediaElement::preload() const 1916 String HTMLMediaElement::preload() const
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1969 ScriptPromise promise = resolver->promise(); 1996 ScriptPromise promise = resolver->promise();
1970 1997
1971 m_playResolvers.append(resolver); 1998 m_playResolvers.append(resolver);
1972 return promise; 1999 return promise;
1973 } 2000 }
1974 2001
1975 Nullable<ExceptionCode> HTMLMediaElement::play() 2002 Nullable<ExceptionCode> HTMLMediaElement::play()
1976 { 2003 {
1977 WTF_LOG(Media, "HTMLMediaElement::play(%p)", this); 2004 WTF_LOG(Media, "HTMLMediaElement::play(%p)", this);
1978 2005
1979 m_autoplayHelper.playMethodCalled(); 2006 m_autoplayHelper->playMethodCalled();
1980 2007
1981 if (!UserGestureIndicator::processingUserGesture()) { 2008 if (!UserGestureIndicator::processingUserGesture()) {
1982 autoplayMediaEncountered();
1983
1984 if (m_userGestureRequiredForPlay) { 2009 if (m_userGestureRequiredForPlay) {
1985 recordAutoplayMetric(PlayMethodFailed); 2010 recordAutoplayMetric(PlayMethodFailed);
1986 String message = ExceptionMessages::failedToExecute("play", "HTMLMed iaElement", "API can only be initiated by a user gesture."); 2011 String message = ExceptionMessages::failedToExecute("play", "HTMLMed iaElement", "API can only be initiated by a user gesture.");
1987 document().addConsoleMessage(ConsoleMessage::create(JSMessageSource, WarningMessageLevel, message)); 2012 document().addConsoleMessage(ConsoleMessage::create(JSMessageSource, WarningMessageLevel, message));
1988 return NotAllowedError; 2013 return NotAllowedError;
1989 } 2014 }
1990 } else { 2015 } else {
2016 // We ask the helper to remove the gesture requirement for us, so that
2017 // it can record the reason.
1991 Platform::current()->recordAction(UserMetricsAction("Media_Play_WithGest ure")); 2018 Platform::current()->recordAction(UserMetricsAction("Media_Play_WithGest ure"));
1992 if (m_userGestureRequiredForPlay) { 2019 m_autoplayHelper->removeUserGestureRequirement(GesturelessPlaybackEnable dByPlayMethod);
1993 if (m_autoplayMediaCounted)
1994 recordAutoplayMetric(AutoplayManualStart);
1995 m_userGestureRequiredForPlay = false;
1996 }
1997 } 2020 }
1998 2021
1999 if (m_error && m_error->code() == MediaError::MEDIA_ERR_SRC_NOT_SUPPORTED) 2022 if (m_error && m_error->code() == MediaError::MEDIA_ERR_SRC_NOT_SUPPORTED)
2000 return NotSupportedError; 2023 return NotSupportedError;
2001 2024
2002 playInternal(); 2025 playInternal();
2003 2026
2004 return nullptr; 2027 return nullptr;
2005 } 2028 }
2006 2029
(...skipping 28 matching lines...) Expand all
2035 scheduleNotifyPlaying(); 2058 scheduleNotifyPlaying();
2036 } else if (m_readyState >= HAVE_FUTURE_DATA) { 2059 } else if (m_readyState >= HAVE_FUTURE_DATA) {
2037 scheduleResolvePlayPromises(); 2060 scheduleResolvePlayPromises();
2038 } 2061 }
2039 2062
2040 m_autoplaying = false; 2063 m_autoplaying = false;
2041 2064
2042 updatePlayState(); 2065 updatePlayState();
2043 } 2066 }
2044 2067
2045 void HTMLMediaElement::autoplayMediaEncountered()
2046 {
2047 if (!m_autoplayMediaCounted) {
2048 m_autoplayMediaCounted = true;
2049 recordAutoplayMetric(AutoplayMediaFound);
2050
2051 if (!m_userGestureRequiredForPlay)
2052 m_initialPlayWithoutUserGesture = true;
2053 }
2054 }
2055
2056 bool HTMLMediaElement::isBailout() const
2057 {
2058 // We count the user as having bailed-out on the video if they watched
2059 // less than one minute and less than 50% of it.
2060 const double playedTime = currentTime();
2061 const double progress = playedTime / duration();
2062 return (playedTime < 60) && (progress < 0.5);
2063 }
2064
2065 void HTMLMediaElement::pause() 2068 void HTMLMediaElement::pause()
2066 { 2069 {
2067 WTF_LOG(Media, "HTMLMediaElement::pause(%p)", this); 2070 WTF_LOG(Media, "HTMLMediaElement::pause(%p)", this);
2068 2071
2069 // Only buffer aggressively on a user-initiated pause. Other types of pauses 2072 // Only buffer aggressively on a user-initiated pause. Other types of pauses
2070 // (which go directly to pauseInternal()) should not cause this behavior. 2073 // (which go directly to pauseInternal()) should not cause this behavior.
2071 if (webMediaPlayer() && UserGestureIndicator::processingUserGesture()) 2074 if (webMediaPlayer() && UserGestureIndicator::processingUserGesture())
2072 webMediaPlayer()->setBufferingStrategy(WebMediaPlayer::BufferingStrategy ::Aggressive); 2075 webMediaPlayer()->setBufferingStrategy(WebMediaPlayer::BufferingStrategy ::Aggressive);
2073 2076
2074 pauseInternal(); 2077 pauseInternal();
2075 } 2078 }
2076 2079
2077 void HTMLMediaElement::pauseInternal() 2080 void HTMLMediaElement::pauseInternal()
2078 { 2081 {
2079 WTF_LOG(Media, "HTMLMediaElement::pauseInternal(%p)", this); 2082 WTF_LOG(Media, "HTMLMediaElement::pauseInternal(%p)", this);
2080 2083
2081 if (m_networkState == NETWORK_EMPTY) 2084 if (m_networkState == NETWORK_EMPTY)
2082 scheduleDelayedAction(LoadMediaResource); 2085 scheduleDelayedAction(LoadMediaResource);
2083 2086
2084 m_autoplayHelper.pauseMethodCalled(); 2087 m_autoplayHelper->pauseMethodCalled();
2085 2088
2086 m_autoplaying = false; 2089 m_autoplaying = false;
2087 2090
2088 if (!m_paused) { 2091 if (!m_paused) {
2089 recordMetricsIfPausing();
2090
2091 m_paused = true; 2092 m_paused = true;
2092 scheduleTimeupdateEvent(false); 2093 scheduleTimeupdateEvent(false);
2093 scheduleEvent(EventTypeNames::pause); 2094 scheduleEvent(EventTypeNames::pause);
2094 scheduleRejectPlayPromises(AbortError); 2095 scheduleRejectPlayPromises(AbortError);
2095 } 2096 }
2096 2097
2097 updatePlayState(); 2098 updatePlayState();
2098 } 2099 }
2099 2100
2100 void HTMLMediaElement::requestRemotePlayback() 2101 void HTMLMediaElement::requestRemotePlayback()
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
2190 2191
2191 void HTMLMediaElement::setMuted(bool muted) 2192 void HTMLMediaElement::setMuted(bool muted)
2192 { 2193 {
2193 WTF_LOG(Media, "HTMLMediaElement::setMuted(%p, %s)", this, boolString(muted) ); 2194 WTF_LOG(Media, "HTMLMediaElement::setMuted(%p, %s)", this, boolString(muted) );
2194 2195
2195 if (m_muted == muted) 2196 if (m_muted == muted)
2196 return; 2197 return;
2197 2198
2198 m_muted = muted; 2199 m_muted = muted;
2199 2200
2200 m_autoplayHelper.mutedChanged(); 2201 m_autoplayHelper->mutedChanged();
2201 2202
2202 updateVolume(); 2203 updateVolume();
2203 2204
2204 if (muted) 2205 if (muted)
2205 Platform::current()->recordAction(UserMetricsAction("Media_Playback_Mute _On")); 2206 Platform::current()->recordAction(UserMetricsAction("Media_Playback_Mute _On"));
2206 else 2207 else
2207 Platform::current()->recordAction(UserMetricsAction("Media_Playback_Mute _Off")); 2208 Platform::current()->recordAction(UserMetricsAction("Media_Playback_Mute _Off"));
2208 2209
2209 scheduleEvent(EventTypeNames::volumechange); 2210 scheduleEvent(EventTypeNames::volumechange);
2210 } 2211 }
(...skipping 592 matching lines...) Expand 10 before | Expand all | Expand 10 after
2803 // If the media element has a loop attribute specified 2804 // If the media element has a loop attribute specified
2804 if (loop()) { 2805 if (loop()) {
2805 m_sentEndEvent = false; 2806 m_sentEndEvent = false;
2806 // then seek to the earliest possible position of the media resourc e and abort these steps. 2807 // then seek to the earliest possible position of the media resourc e and abort these steps.
2807 seek(0); 2808 seek(0);
2808 } else { 2809 } else {
2809 // If the media element has still ended playback, and the direction of playback is still 2810 // If the media element has still ended playback, and the direction of playback is still
2810 // forwards, and paused is false, 2811 // forwards, and paused is false,
2811 if (!m_paused) { 2812 if (!m_paused) {
2812 // changes paused to true and fires a simple event named pause a t the media element. 2813 // changes paused to true and fires a simple event named pause a t the media element.
2814 m_autoplayHelper->playbackEnded();
2813 m_paused = true; 2815 m_paused = true;
2814 scheduleEvent(EventTypeNames::pause); 2816 scheduleEvent(EventTypeNames::pause);
2815 } 2817 }
2816 // Queue a task to fire a simple event named ended at the media elem ent. 2818 // Queue a task to fire a simple event named ended at the media elem ent.
2817 if (!m_sentEndEvent) { 2819 if (!m_sentEndEvent) {
2818 m_sentEndEvent = true; 2820 m_sentEndEvent = true;
2819 scheduleEvent(EventTypeNames::ended); 2821 scheduleEvent(EventTypeNames::ended);
2820 } 2822 }
2821 recordMetricsIfPausing();
2822 Platform::current()->recordAction(UserMetricsAction("Media_Playback_ Ended")); 2823 Platform::current()->recordAction(UserMetricsAction("Media_Playback_ Ended"));
2823 } 2824 }
2824 } else { 2825 } else {
2825 m_sentEndEvent = false; 2826 m_sentEndEvent = false;
2826 } 2827 }
2827 2828
2828 updatePlayState(); 2829 updatePlayState();
2829 } 2830 }
2830 2831
2831 void HTMLMediaElement::durationChanged() 2832 void HTMLMediaElement::durationChanged()
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
3021 invalidateCachedTime(); 3022 invalidateCachedTime();
3022 3023
3023 if (!isPlaying) { 3024 if (!isPlaying) {
3024 // Set rate, muted before calling play in case they were set before the media engine was setup. 3025 // Set rate, muted before calling play in case they were set before the media engine was setup.
3025 // The media engine should just stash the rate and muted values sinc e it isn't already playing. 3026 // The media engine should just stash the rate and muted values sinc e it isn't already playing.
3026 webMediaPlayer()->setRate(playbackRate()); 3027 webMediaPlayer()->setRate(playbackRate());
3027 updateVolume(); 3028 updateVolume();
3028 webMediaPlayer()->play(); 3029 webMediaPlayer()->play();
3029 Platform::current()->recordAction( 3030 Platform::current()->recordAction(
3030 UserMetricsAction("Media_Playback_Started")); 3031 UserMetricsAction("Media_Playback_Started"));
3032 m_autoplayHelper->playbackStarted();
3031 } 3033 }
3032 3034
3033 if (mediaControls()) 3035 if (mediaControls())
3034 mediaControls()->playbackStarted(); 3036 mediaControls()->playbackStarted();
3035 startPlaybackProgressTimer(); 3037 startPlaybackProgressTimer();
3036 m_playing = true; 3038 m_playing = true;
3037 recordAutoplayMetric(AnyPlaybackStarted);
3038 3039
3039 } else { // Should not be playing right now 3040 } else { // Should not be playing right now
3040 if (isPlaying) { 3041 if (isPlaying) {
3041 webMediaPlayer()->pause(); 3042 webMediaPlayer()->pause();
3042 Platform::current()->recordAction(UserMetricsAction("Media_Paused")) ; 3043 Platform::current()->recordAction(UserMetricsAction("Media_Paused")) ;
3043 } 3044 }
3044 3045
3045 refreshCachedTime(); 3046 refreshCachedTime();
3046 3047
3047 m_playbackProgressTimer.stop(); 3048 m_playbackProgressTimer.stop();
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
3102 mediaControls()->refreshCastButtonVisibilityWithoutUpdate(); 3103 mediaControls()->refreshCastButtonVisibilityWithoutUpdate();
3103 3104
3104 if (layoutObject()) 3105 if (layoutObject())
3105 layoutObject()->setShouldDoFullPaintInvalidation(); 3106 layoutObject()->setShouldDoFullPaintInvalidation();
3106 } 3107 }
3107 3108
3108 void HTMLMediaElement::stop() 3109 void HTMLMediaElement::stop()
3109 { 3110 {
3110 WTF_LOG(Media, "HTMLMediaElement::stop(%p)", this); 3111 WTF_LOG(Media, "HTMLMediaElement::stop(%p)", this);
3111 3112
3112 recordMetricsIfPausing();
3113
3114 // Close the async event queue so that no events are enqueued. 3113 // Close the async event queue so that no events are enqueued.
3115 cancelPendingEventsAndCallbacks(); 3114 cancelPendingEventsAndCallbacks();
3116 m_asyncEventQueue->close(); 3115 m_asyncEventQueue->close();
3117 3116
3118 // Stop the playback without generating events 3117 // Stop the playback without generating events
3119 clearMediaPlayer(-1); 3118 clearMediaPlayer(-1);
3120 m_readyState = HAVE_NOTHING; 3119 m_readyState = HAVE_NOTHING;
3121 m_readyStateMaximum = HAVE_NOTHING; 3120 m_readyStateMaximum = HAVE_NOTHING;
3122 setNetworkState(NETWORK_EMPTY); 3121 setNetworkState(NETWORK_EMPTY);
3123 setShouldDelayLoadEvent(false); 3122 setShouldDelayLoadEvent(false);
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after
3578 visitor->trace(m_currentSourceNode); 3577 visitor->trace(m_currentSourceNode);
3579 visitor->trace(m_nextChildNodeToConsider); 3578 visitor->trace(m_nextChildNodeToConsider);
3580 visitor->trace(m_mediaSource); 3579 visitor->trace(m_mediaSource);
3581 visitor->trace(m_audioTracks); 3580 visitor->trace(m_audioTracks);
3582 visitor->trace(m_videoTracks); 3581 visitor->trace(m_videoTracks);
3583 visitor->trace(m_cueTimeline); 3582 visitor->trace(m_cueTimeline);
3584 visitor->trace(m_textTracks); 3583 visitor->trace(m_textTracks);
3585 visitor->trace(m_textTracksWhenResourceSelectionBegan); 3584 visitor->trace(m_textTracksWhenResourceSelectionBegan);
3586 visitor->trace(m_playResolvers); 3585 visitor->trace(m_playResolvers);
3587 visitor->trace(m_audioSourceProvider); 3586 visitor->trace(m_audioSourceProvider);
3587 visitor->trace(m_autoplayHelperClient);
3588 visitor->trace(m_autoplayHelper);
3588 visitor->template registerWeakMembers<HTMLMediaElement, &HTMLMediaElement::c learWeakMembers>(this); 3589 visitor->template registerWeakMembers<HTMLMediaElement, &HTMLMediaElement::c learWeakMembers>(this);
3589 visitor->trace(m_autoplayHelper);
3590 HeapSupplementable<HTMLMediaElement>::trace(visitor); 3590 HeapSupplementable<HTMLMediaElement>::trace(visitor);
3591 #endif 3591 #endif
3592 HTMLElement::trace(visitor); 3592 HTMLElement::trace(visitor);
3593 ActiveDOMObject::trace(visitor); 3593 ActiveDOMObject::trace(visitor);
3594 } 3594 }
3595 3595
3596 void HTMLMediaElement::createPlaceholderTracksIfNecessary() 3596 void HTMLMediaElement::createPlaceholderTracksIfNecessary()
3597 { 3597 {
3598 if (!RuntimeEnabledFeatures::audioVideoTracksEnabled()) 3598 if (!RuntimeEnabledFeatures::audioVideoTracksEnabled())
3599 return; 3599 return;
(...skipping 24 matching lines...) Expand all
3624 bool HTMLMediaElement::isUserGestureRequiredForPlay() const 3624 bool HTMLMediaElement::isUserGestureRequiredForPlay() const
3625 { 3625 {
3626 return m_userGestureRequiredForPlay; 3626 return m_userGestureRequiredForPlay;
3627 } 3627 }
3628 3628
3629 void HTMLMediaElement::removeUserGestureRequirement() 3629 void HTMLMediaElement::removeUserGestureRequirement()
3630 { 3630 {
3631 m_userGestureRequiredForPlay = false; 3631 m_userGestureRequiredForPlay = false;
3632 } 3632 }
3633 3633
3634 void HTMLMediaElement::setInitialPlayWithoutUserGestures(bool value)
3635 {
3636 m_initialPlayWithoutUserGesture = value;
3637 }
3638
3639 void HTMLMediaElement::setNetworkState(NetworkState state) 3634 void HTMLMediaElement::setNetworkState(NetworkState state)
3640 { 3635 {
3641 if (m_networkState != state) { 3636 if (m_networkState != state) {
3642 m_networkState = state; 3637 m_networkState = state;
3643 if (MediaControls* controls = mediaControls()) 3638 if (MediaControls* controls = mediaControls())
3644 controls->networkStateChanged(); 3639 controls->networkStateChanged();
3645 } 3640 }
3646 } 3641 }
3647 3642
3648 void HTMLMediaElement::notifyPositionMayHaveChanged(const IntRect& visibleRect) 3643 void HTMLMediaElement::notifyPositionMayHaveChanged(const IntRect& visibleRect)
3649 { 3644 {
3650 m_autoplayHelper.positionChanged(visibleRect); 3645 m_autoplayHelper->positionChanged(visibleRect);
3651 } 3646 }
3652 3647
3653 void HTMLMediaElement::updatePositionNotificationRegistration() 3648 void HTMLMediaElement::updatePositionNotificationRegistration()
3654 { 3649 {
3655 m_autoplayHelper.updatePositionNotificationRegistration(); 3650 m_autoplayHelper->updatePositionNotificationRegistration();
3656 } 3651 }
3657 3652
3658 // TODO(liberato): remove once autoplay gesture override experiment concludes. 3653 // TODO(liberato): remove once autoplay gesture override experiment concludes.
3659 void HTMLMediaElement::triggerAutoplayViewportCheckForTesting() 3654 void HTMLMediaElement::triggerAutoplayViewportCheckForTesting()
3660 { 3655 {
3661 m_autoplayHelper.triggerAutoplayViewportCheckForTesting(); 3656 if (FrameView* view = document().view())
3657 m_autoplayHelper->positionChanged(view->rootFrameToContents(view->comput eVisibleArea()));
3658 m_autoplayHelper->triggerAutoplayViewportCheckForTesting();
3662 } 3659 }
3663 3660
3664 void HTMLMediaElement::scheduleResolvePlayPromises() 3661 void HTMLMediaElement::scheduleResolvePlayPromises()
3665 { 3662 {
3666 // Per spec, if there are two tasks in the queue, the first task will remove 3663 // Per spec, if there are two tasks in the queue, the first task will remove
3667 // all the pending promises making the second task useless unless a promise 3664 // all the pending promises making the second task useless unless a promise
3668 // can be added between the first and second task being run which is not 3665 // can be added between the first and second task being run which is not
3669 // possible at the moment. 3666 // possible at the moment.
3670 if (m_playPromiseResolveTask->isPending()) 3667 if (m_playPromiseResolveTask->isPending())
3671 return; 3668 return;
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
3794 DEFINE_TRACE(HTMLMediaElement::AudioClientImpl) 3791 DEFINE_TRACE(HTMLMediaElement::AudioClientImpl)
3795 { 3792 {
3796 visitor->trace(m_client); 3793 visitor->trace(m_client);
3797 } 3794 }
3798 3795
3799 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) 3796 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl)
3800 { 3797 {
3801 visitor->trace(m_client); 3798 visitor->trace(m_client);
3802 } 3799 }
3803 3800
3801 HTMLMediaElement::AutoplayHelperClientImpl::~AutoplayHelperClientImpl()
3802 {
3803 }
3804
3805 bool HTMLMediaElement::AutoplayHelperClientImpl::isLegacyViewportType()
3806 {
3807 return m_element->document().viewportDescription().isLegacyViewportType();
3808 }
3809
3810 PageVisibilityState HTMLMediaElement::AutoplayHelperClientImpl::pageVisibilitySt ate() const
3811 {
3812 return m_element->document().pageVisibilityState();
3813 }
3814
3815 String HTMLMediaElement::AutoplayHelperClientImpl::autoplayExperimentMode() cons t
3816 {
3817 String mode;
3818 if (m_element->document().settings())
3819 mode = m_element->document().settings()->autoplayExperimentMode();
3820
3821 return mode;
3822 }
3823
3824 void HTMLMediaElement::AutoplayHelperClientImpl::setRequestPositionUpdates(bool request)
3825 {
3826 if (LayoutObject* layoutObject = m_element->layoutObject()) {
3827 LayoutMediaItem layoutMediaItem = LayoutMediaItem(toLayoutMedia(layoutOb ject));
3828 layoutMediaItem.setRequestPositionUpdates(request);
3829 }
3830 }
3831
3832 IntRect HTMLMediaElement::AutoplayHelperClientImpl::absoluteBoundingBoxRect() co nst
3833 {
3834 IntRect result;
3835 if (LayoutObject* object = m_element->layoutObject())
3836 result = object->absoluteBoundingBoxRect();
3837 return result;
3838 }
3839
3804 } // namespace blink 3840 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/html/HTMLMediaElement.h ('k') | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698