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

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

Issue 2051253002: Start autoplay muted videos with autoplay attribute when they are visible. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: cleanup and tests Created 4 years, 6 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 17 matching lines...) Expand all
28 #include "bindings/core/v8/ExceptionState.h" 28 #include "bindings/core/v8/ExceptionState.h"
29 #include "bindings/core/v8/ExceptionStatePlaceholder.h" 29 #include "bindings/core/v8/ExceptionStatePlaceholder.h"
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/DOMException.h" 36 #include "core/dom/DOMException.h"
37 #include "core/dom/ElementTraversal.h" 37 #include "core/dom/ElementTraversal.h"
38 #include "core/dom/ElementVisibilityObserver.h"
38 #include "core/dom/Fullscreen.h" 39 #include "core/dom/Fullscreen.h"
39 #include "core/dom/shadow/ShadowRoot.h" 40 #include "core/dom/shadow/ShadowRoot.h"
40 #include "core/events/Event.h" 41 #include "core/events/Event.h"
41 #include "core/frame/FrameView.h" 42 #include "core/frame/FrameView.h"
42 #include "core/frame/LocalFrame.h" 43 #include "core/frame/LocalFrame.h"
43 #include "core/frame/Settings.h" 44 #include "core/frame/Settings.h"
44 #include "core/frame/UseCounter.h" 45 #include "core/frame/UseCounter.h"
45 #include "core/frame/csp/ContentSecurityPolicy.h" 46 #include "core/frame/csp/ContentSecurityPolicy.h"
46 #include "core/html/HTMLMediaSource.h" 47 #include "core/html/HTMLMediaSource.h"
47 #include "core/html/HTMLSourceElement.h" 48 #include "core/html/HTMLSourceElement.h"
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 visitor->trace(m_element); 348 visitor->trace(m_element);
348 Client::trace(visitor); 349 Client::trace(visitor);
349 } 350 }
350 351
351 private: 352 private:
352 AutoplayHelperClientImpl(HTMLMediaElement* element) : m_element(element) {} 353 AutoplayHelperClientImpl(HTMLMediaElement* element) : m_element(element) {}
353 354
354 Member<HTMLMediaElement> m_element; 355 Member<HTMLMediaElement> m_element;
355 }; 356 };
356 357
357
358 void HTMLMediaElement::recordAutoplayMetric(AutoplayMetrics metric) 358 void HTMLMediaElement::recordAutoplayMetric(AutoplayMetrics metric)
359 { 359 {
360 DEFINE_STATIC_LOCAL(EnumerationHistogram, autoplayHistogram, ("Blink.MediaEl ement.Autoplay", NumberOfAutoplayMetrics)); 360 DEFINE_STATIC_LOCAL(EnumerationHistogram, autoplayHistogram, ("Blink.MediaEl ement.Autoplay", NumberOfAutoplayMetrics));
361 autoplayHistogram.count(metric); 361 autoplayHistogram.count(metric);
362 } 362 }
363 363
364 WebMimeRegistry::SupportsType HTMLMediaElement::supportsType(const ContentType& contentType) 364 WebMimeRegistry::SupportsType HTMLMediaElement::supportsType(const ContentType& contentType)
365 { 365 {
366 DEFINE_STATIC_LOCAL(const String, codecs, ("codecs")); 366 DEFINE_STATIC_LOCAL(const String, codecs, ("codecs"));
367 367
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 , m_inOverlayFullscreenVideo(false) 443 , m_inOverlayFullscreenVideo(false)
444 , m_audioTracks(AudioTrackList::create(*this)) 444 , m_audioTracks(AudioTrackList::create(*this))
445 , m_videoTracks(VideoTrackList::create(*this)) 445 , m_videoTracks(VideoTrackList::create(*this))
446 , m_textTracks(nullptr) 446 , m_textTracks(nullptr)
447 , m_playPromiseResolveTask(CancellableTaskFactory::create(this, &HTMLMediaEl ement::resolveScheduledPlayPromises)) 447 , m_playPromiseResolveTask(CancellableTaskFactory::create(this, &HTMLMediaEl ement::resolveScheduledPlayPromises))
448 , m_playPromiseRejectTask(CancellableTaskFactory::create(this, &HTMLMediaEle ment::rejectScheduledPlayPromises)) 448 , m_playPromiseRejectTask(CancellableTaskFactory::create(this, &HTMLMediaEle ment::rejectScheduledPlayPromises))
449 , m_audioSourceNode(nullptr) 449 , m_audioSourceNode(nullptr)
450 , m_autoplayHelperClient(AutoplayHelperClientImpl::create(this)) 450 , m_autoplayHelperClient(AutoplayHelperClientImpl::create(this))
451 , m_autoplayHelper(AutoplayExperimentHelper::create(m_autoplayHelperClient.g et())) 451 , m_autoplayHelper(AutoplayExperimentHelper::create(m_autoplayHelperClient.g et()))
452 , m_remotePlaybackClient(nullptr) 452 , m_remotePlaybackClient(nullptr)
453 , m_autoplayVisibilityObserver(nullptr)
453 { 454 {
454 ThreadState::current()->registerPreFinalizer(this); 455 ThreadState::current()->registerPreFinalizer(this);
455 456
456 DVLOG(MEDIA_LOG_LEVEL) << "HTMLMediaElement(" << (void*)this << ")"; 457 DVLOG(MEDIA_LOG_LEVEL) << "HTMLMediaElement(" << (void*)this << ")";
457 458
458 // If any experiment is enabled, then we want to enable a user gesture by 459 // If any experiment is enabled, then we want to enable a user gesture by
459 // default, otherwise the experiment does nothing. 460 // default, otherwise the experiment does nothing.
460 if ((document.settings() && document.settings()->mediaPlaybackRequiresUserGe sture()) 461 if ((document.settings() && document.settings()->mediaPlaybackRequiresUserGe sture())
461 || m_autoplayHelper->isExperimentEnabled()) { 462 || m_autoplayHelper->isExperimentEnabled()) {
462 m_lockedPendingUserGesture = true; 463 m_lockedPendingUserGesture = true;
(...skipping 1171 matching lines...) Expand 10 before | Expand all | Expand 10 after
1634 if (m_readyState == HAVE_ENOUGH_DATA && oldState < HAVE_ENOUGH_DATA && track sAreReady) { 1635 if (m_readyState == HAVE_ENOUGH_DATA && oldState < HAVE_ENOUGH_DATA && track sAreReady) {
1635 if (oldState <= HAVE_CURRENT_DATA) { 1636 if (oldState <= HAVE_CURRENT_DATA) {
1636 scheduleEvent(EventTypeNames::canplay); 1637 scheduleEvent(EventTypeNames::canplay);
1637 if (isPotentiallyPlaying) 1638 if (isPotentiallyPlaying)
1638 scheduleNotifyPlaying(); 1639 scheduleNotifyPlaying();
1639 } 1640 }
1640 1641
1641 // Check for autoplay, and record metrics about it if needed. 1642 // Check for autoplay, and record metrics about it if needed.
1642 if (shouldAutoplay(RecordMetricsBehavior::DoRecord)) { 1643 if (shouldAutoplay(RecordMetricsBehavior::DoRecord)) {
1643 recordAutoplaySourceMetric(AutoplaySourceAttribute); 1644 recordAutoplaySourceMetric(AutoplaySourceAttribute);
1645
1644 // If the autoplay experiment says that it's okay to play now, 1646 // If the autoplay experiment says that it's okay to play now,
1645 // then don't require a user gesture. 1647 // then don't require a user gesture.
1646 m_autoplayHelper->becameReadyToPlay(); 1648 m_autoplayHelper->becameReadyToPlay();
1647 1649
1648 if (!isGestureNeededForPlayback()) { 1650 if (!isGestureNeededForPlayback()) {
1649 m_paused = false; 1651 if (muted() && RuntimeEnabledFeatures::autoplayMutedVideosEnable d()) {
1650 invalidateCachedTime(); 1652 m_autoplayVisibilityObserver = new ElementVisibilityObserver (this, WTF::bind<bool>(&HTMLMediaElement::onVisibilityChangedForAutoplay, this)) ;
1651 scheduleEvent(EventTypeNames::play); 1653 m_autoplayVisibilityObserver->start();
1652 scheduleNotifyPlaying(); 1654 } else {
1653 m_autoplaying = false; 1655 m_paused = false;
1656 invalidateCachedTime();
1657 scheduleEvent(EventTypeNames::play);
1658 scheduleNotifyPlaying();
1659 m_autoplaying = false;
1660 }
1654 } 1661 }
1655 } 1662 }
1656 1663
1657 scheduleEvent(EventTypeNames::canplaythrough); 1664 scheduleEvent(EventTypeNames::canplaythrough);
1658 1665
1659 shouldUpdateDisplayState = true; 1666 shouldUpdateDisplayState = true;
1660 } 1667 }
1661 1668
1662 if (shouldUpdateDisplayState) { 1669 if (shouldUpdateDisplayState) {
1663 updateDisplayState(); 1670 updateDisplayState();
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after
2115 2122
2116 playInternal(); 2123 playInternal();
2117 2124
2118 return nullptr; 2125 return nullptr;
2119 } 2126 }
2120 2127
2121 void HTMLMediaElement::playInternal() 2128 void HTMLMediaElement::playInternal()
2122 { 2129 {
2123 DVLOG(MEDIA_LOG_LEVEL) << "playInternal(" << (void*)this << ")"; 2130 DVLOG(MEDIA_LOG_LEVEL) << "playInternal(" << (void*)this << ")";
2124 2131
2132 // Playing is about to start from script, no need to wait for visibility.
2133 if (m_autoplayVisibilityObserver) {
2134 m_autoplayVisibilityObserver->stop();
2135 m_autoplayVisibilityObserver = nullptr;
2136 }
2137
2125 // Always return the buffering strategy to normal when not paused, 2138 // Always return the buffering strategy to normal when not paused,
2126 // regardless of the cause. (In contrast with aggressive buffering which is 2139 // regardless of the cause. (In contrast with aggressive buffering which is
2127 // only enabled by pause(), not pauseInternal().) 2140 // only enabled by pause(), not pauseInternal().)
2128 if (webMediaPlayer()) 2141 if (webMediaPlayer())
2129 webMediaPlayer()->setBufferingStrategy(WebMediaPlayer::BufferingStrategy ::Normal); 2142 webMediaPlayer()->setBufferingStrategy(WebMediaPlayer::BufferingStrategy ::Normal);
2130 2143
2131 // 4.8.10.9. Playing the media resource 2144 // 4.8.10.9. Playing the media resource
2132 if (m_networkState == NETWORK_EMPTY) 2145 if (m_networkState == NETWORK_EMPTY)
2133 invokeResourceSelectionAlgorithm(); 2146 invokeResourceSelectionAlgorithm();
2134 2147
(...skipping 1500 matching lines...) Expand 10 before | Expand all | Expand 10 after
3635 visitor->trace(m_cueTimeline); 3648 visitor->trace(m_cueTimeline);
3636 visitor->trace(m_textTracks); 3649 visitor->trace(m_textTracks);
3637 visitor->trace(m_textTracksWhenResourceSelectionBegan); 3650 visitor->trace(m_textTracksWhenResourceSelectionBegan);
3638 visitor->trace(m_playPromiseResolvers); 3651 visitor->trace(m_playPromiseResolvers);
3639 visitor->trace(m_playPromiseResolveList); 3652 visitor->trace(m_playPromiseResolveList);
3640 visitor->trace(m_playPromiseRejectList); 3653 visitor->trace(m_playPromiseRejectList);
3641 visitor->trace(m_audioSourceProvider); 3654 visitor->trace(m_audioSourceProvider);
3642 visitor->trace(m_autoplayHelperClient); 3655 visitor->trace(m_autoplayHelperClient);
3643 visitor->trace(m_autoplayHelper); 3656 visitor->trace(m_autoplayHelper);
3644 visitor->trace(m_srcObject); 3657 visitor->trace(m_srcObject);
3658 visitor->trace(m_autoplayVisibilityObserver);
3645 visitor->template registerWeakMembers<HTMLMediaElement, &HTMLMediaElement::c learWeakMembers>(this); 3659 visitor->template registerWeakMembers<HTMLMediaElement, &HTMLMediaElement::c learWeakMembers>(this);
3646 Supplementable<HTMLMediaElement>::trace(visitor); 3660 Supplementable<HTMLMediaElement>::trace(visitor);
3647 HTMLElement::trace(visitor); 3661 HTMLElement::trace(visitor);
3648 ActiveDOMObject::trace(visitor); 3662 ActiveDOMObject::trace(visitor);
3649 } 3663 }
3650 3664
3651 DEFINE_TRACE_WRAPPERS(HTMLMediaElement) 3665 DEFINE_TRACE_WRAPPERS(HTMLMediaElement)
3652 { 3666 {
3653 visitor->traceWrappers(m_videoTracks); 3667 visitor->traceWrappers(m_videoTracks);
3654 visitor->traceWrappers(m_audioTracks); 3668 visitor->traceWrappers(m_audioTracks);
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
3852 3866
3853 if (isHTMLVideoElement()) { 3867 if (isHTMLVideoElement()) {
3854 videoHistogram.count(source); 3868 videoHistogram.count(source);
3855 if (muted()) 3869 if (muted())
3856 mutedVideoHistogram.count(source); 3870 mutedVideoHistogram.count(source);
3857 } else { 3871 } else {
3858 audioHistogram.count(source); 3872 audioHistogram.count(source);
3859 } 3873 }
3860 } 3874 }
3861 3875
3876 void HTMLMediaElement::onVisibilityChangedForAutoplay(bool isVisible)
3877 {
3878 if (!isVisible)
3879 return;
3880
3881 playInternal();
3882
3883 // The observation should have been stopped by the call to playInternal
3884 DCHECK(!m_autoplayVisibilityObserver);
3885 }
3886
3862 void HTMLMediaElement::clearWeakMembers(Visitor* visitor) 3887 void HTMLMediaElement::clearWeakMembers(Visitor* visitor)
3863 { 3888 {
3864 if (!ThreadHeap::isHeapObjectAlive(m_audioSourceNode)) { 3889 if (!ThreadHeap::isHeapObjectAlive(m_audioSourceNode)) {
3865 getAudioSourceProvider().setClient(nullptr); 3890 getAudioSourceProvider().setClient(nullptr);
3866 m_audioSourceNode = nullptr; 3891 m_audioSourceNode = nullptr;
3867 } 3892 }
3868 } 3893 }
3869 3894
3870 void HTMLMediaElement::AudioSourceProviderImpl::wrap(WebAudioSourceProvider* pro vider) 3895 void HTMLMediaElement::AudioSourceProviderImpl::wrap(WebAudioSourceProvider* pro vider)
3871 { 3896 {
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
3969 3994
3970 IntRect HTMLMediaElement::AutoplayHelperClientImpl::absoluteBoundingBoxRect() co nst 3995 IntRect HTMLMediaElement::AutoplayHelperClientImpl::absoluteBoundingBoxRect() co nst
3971 { 3996 {
3972 IntRect result; 3997 IntRect result;
3973 if (LayoutObject* object = m_element->layoutObject()) 3998 if (LayoutObject* object = m_element->layoutObject())
3974 result = object->absoluteBoundingBoxRect(); 3999 result = object->absoluteBoundingBoxRect();
3975 return result; 4000 return result;
3976 } 4001 }
3977 4002
3978 } // namespace blink 4003 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698