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

Unified Diff: third_party/WebKit/Source/core/html/HTMLMediaElement.cpp

Issue 2475643004: Monitor the intersection of video and viewport. (Closed)
Patch Set: Fix trybots failure. Created 4 years, 1 month 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 side-by-side diff with in-line comments
Download patch
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 a1f0ce6a74d593703d34135af4a59c9ecdc1652e..7635bbc7dd57b7840e07e2efcd27b6937a248ef8 100644
--- a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
@@ -463,8 +463,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 << ")";
@@ -487,6 +486,11 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName,
addElementToDocumentMap(this, &document);
UseCounter::count(document, UseCounter::HTMLMediaElement);
+
+ m_viewportIntersectionObserver = new ElementViewportIntersectionObserver(
+ this, WTF::bind(&HTMLMediaElement::onVideoViewportIntersectionChanged,
+ wrapWeakPersistent(this)));
+ m_viewportIntersectionObserver->start();
}
HTMLMediaElement::~HTMLMediaElement() {
@@ -502,6 +506,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
@@ -1742,16 +1748,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;
scheduleEvent(EventTypeNames::play);
@@ -2446,7 +2443,7 @@ void HTMLMediaElement::setMuted(bool muted) {
return;
bool wasAutoplayingMuted = isAutoplayingMuted();
- bool wasPendingAutoplayMuted = m_autoplayVisibilityObserver && paused() &&
+ bool wasPendingAutoplayMuted = m_shouldAutoplayWhenVisible && paused() &&
m_muted && isLockedPendingUserGesture();
if (UserGestureIndicator::processingUserGesture())
@@ -2476,11 +2473,9 @@ void HTMLMediaElement::setMuted(bool muted) {
webMediaPlayer()->setVolume(effectiveMediaVolume());
// 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;
}
double HTMLMediaElement::effectiveMediaVolume() const {
@@ -3840,7 +3835,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);
@@ -4064,8 +4059,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_currentViewportIntersection = info;
+
+ bool isVisible = !intersectRect.isEmpty();
+ m_autoplayUmaHelper->visibilityMaybeChangedforMutedVideo(isVisible);
+
+ if (!isVisible || !m_shouldAutoplayWhenVisible)
return;
if (shouldAutoplay()) {
@@ -4076,13 +4083,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) {
« no previous file with comments | « third_party/WebKit/Source/core/html/HTMLMediaElement.h ('k') | third_party/WebKit/Source/web/FrameLoaderClientImpl.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698