| Index: third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
|
| diff --git a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
|
| index 56ad755a6e9c9743151d0a62dc99d5335758bdd9..aaf03db5be9e5ea3562ed00fb8260bb4e1f17110 100644
|
| --- a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
|
| +++ b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
|
| @@ -464,8 +464,7 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName,
|
| m_autoplayHelper(
|
| AutoplayExperimentHelper::create(m_autoplayHelperClient.get())),
|
| m_autoplayUmaHelper(AutoplayUmaHelper::create(this)),
|
| - m_remotePlaybackClient(nullptr),
|
| - m_autoplayVisibilityObserver(nullptr) {
|
| + m_remotePlaybackClient(nullptr) {
|
| ThreadState::current()->registerPreFinalizer(this);
|
|
|
| BLINK_MEDIA_LOG << "HTMLMediaElement(" << (void*)this << ")";
|
| @@ -482,6 +481,11 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName,
|
| addElementToDocumentMap(this, &document);
|
|
|
| UseCounter::count(document, UseCounter::HTMLMediaElement);
|
| +
|
| + m_viewportIntersectionObserver = new ViewportIntersectionObserver(
|
| + this, WTF::bind(&HTMLMediaElement::onVideoViewportIntersectionChanged,
|
| + wrapWeakPersistent(this)));
|
| + m_viewportIntersectionObserver->start();
|
| }
|
|
|
| HTMLMediaElement::~HTMLMediaElement() {
|
| @@ -497,6 +501,8 @@ HTMLMediaElement::~HTMLMediaElement() {
|
| void HTMLMediaElement::dispose() {
|
| closeMediaSource();
|
|
|
| + m_viewportIntersectionObserver->stop();
|
| +
|
| // Destroying the player may cause a resource load to be canceled,
|
| // which could result in LocalDOMWindow::dispatchWindowLoadEvent() being
|
| // called via ResourceFetch::didLoadResource(), then
|
| @@ -1723,16 +1729,7 @@ void HTMLMediaElement::setReadyState(ReadyState state) {
|
| if (!isGestureNeededForPlayback()) {
|
| if (isHTMLVideoElement() && muted() &&
|
| RuntimeEnabledFeatures::autoplayMutedVideosEnabled()) {
|
| - // We might end up in a situation where the previous
|
| - // observer didn't had time to fire yet. We can avoid
|
| - // creating a new one in this case.
|
| - if (!m_autoplayVisibilityObserver) {
|
| - m_autoplayVisibilityObserver = new ElementVisibilityObserver(
|
| - this,
|
| - WTF::bind(&HTMLMediaElement::onVisibilityChangedForAutoplay,
|
| - wrapWeakPersistent(this)));
|
| - m_autoplayVisibilityObserver->start();
|
| - }
|
| + m_shouldAutoplayWhenVisible = true;
|
| } else {
|
| m_paused = false;
|
| invalidateCachedTime();
|
| @@ -2355,7 +2352,7 @@ void HTMLMediaElement::setMuted(bool muted) {
|
|
|
| bool wasAutoplayingMuted =
|
| !paused() && m_muted && isLockedPendingUserGesture();
|
| - bool wasPendingAutoplayMuted = m_autoplayVisibilityObserver && paused() &&
|
| + bool wasPendingAutoplayMuted = m_shouldAutoplayWhenVisible && paused() &&
|
| m_muted && isLockedPendingUserGesture();
|
|
|
| if (UserGestureIndicator::processingUserGesture())
|
| @@ -2382,11 +2379,9 @@ void HTMLMediaElement::setMuted(bool muted) {
|
| }
|
|
|
| // If an element was a candidate for autoplay muted but not visible, it will
|
| - // have a visibility observer ready to start its playback.
|
| - if (wasPendingAutoplayMuted) {
|
| - m_autoplayVisibilityObserver->stop();
|
| - m_autoplayVisibilityObserver = nullptr;
|
| - }
|
| + // start its playback once becomes visible.
|
| + if (wasPendingAutoplayMuted)
|
| + m_shouldAutoplayWhenVisible = false;
|
| }
|
|
|
| void HTMLMediaElement::updateVolume() {
|
| @@ -3742,7 +3737,7 @@ DEFINE_TRACE(HTMLMediaElement) {
|
| visitor->trace(m_autoplayHelper);
|
| visitor->trace(m_autoplayUmaHelper);
|
| visitor->trace(m_srcObject);
|
| - visitor->trace(m_autoplayVisibilityObserver);
|
| + visitor->trace(m_viewportIntersectionObserver);
|
| visitor->template registerWeakMembers<HTMLMediaElement,
|
| &HTMLMediaElement::clearWeakMembers>(
|
| this);
|
| @@ -3968,8 +3963,20 @@ EnumerationHistogram& HTMLMediaElement::showControlsHistogram() const {
|
| return histogram;
|
| }
|
|
|
| -void HTMLMediaElement::onVisibilityChangedForAutoplay(bool isVisible) {
|
| - if (!isVisible)
|
| +void HTMLMediaElement::onVideoViewportIntersectionChanged(
|
| + const WebRect& rootRect,
|
| + const WebRect& intersectRect) {
|
| + WebMediaPlayer::ViewportIntersectionInfo info;
|
| + info.rootRect = rootRect;
|
| + info.intersectRect = intersectRect;
|
| + if (m_webMediaPlayer)
|
| + m_webMediaPlayer->videoViewportIntersectionChanged(info);
|
| + m_viewportIntersectInfo = info;
|
| +
|
| + bool isVisible = !intersectRect.isEmpty();
|
| + m_autoplayUmaHelper->visibilityMaybeChangedforMutedVideo(isVisible);
|
| +
|
| + if (!isVisible || !m_shouldAutoplayWhenVisible)
|
| return;
|
|
|
| if (shouldAutoplay()) {
|
| @@ -3981,13 +3988,7 @@ void HTMLMediaElement::onVisibilityChangedForAutoplay(bool isVisible) {
|
|
|
| updatePlayState();
|
| }
|
| -
|
| - // TODO(zqzhang): There's still flaky leak if onVisibilityChangedForAutoplay()
|
| - // is never called. The leak comes from either ElementVisibilityObserver or
|
| - // IntersectionObserver. Should keep an eye on it. See
|
| - // https://crbug.com/627539
|
| - m_autoplayVisibilityObserver->stop();
|
| - m_autoplayVisibilityObserver = nullptr;
|
| + m_shouldAutoplayWhenVisible = false;
|
| }
|
|
|
| void HTMLMediaElement::clearWeakMembers(Visitor* visitor) {
|
|
|