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

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

Issue 2696893002: [Blink>Media] Add heuristic for dominant video detection for Android (Closed)
Patch Set: nits Created 3 years, 10 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/html/MediaCustomControlsFullscreenDetector.cpp
diff --git a/third_party/WebKit/Source/core/html/MediaCustomControlsFullscreenDetector.cpp b/third_party/WebKit/Source/core/html/MediaCustomControlsFullscreenDetector.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..841fb64472b7914e86007c01ba0ff24f2ab8e0e8
--- /dev/null
+++ b/third_party/WebKit/Source/core/html/MediaCustomControlsFullscreenDetector.cpp
@@ -0,0 +1,158 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/html/MediaCustomControlsFullscreenDetector.h"
+
+#include "core/dom/Fullscreen.h"
+#include "core/dom/TaskRunnerHelper.h"
+#include "core/events/Event.h"
+#include "core/html/HTMLVideoElement.h"
+#include "core/layout/IntersectionGeometry.h"
+
+namespace blink {
+
+namespace {
+
+constexpr double kCheckFullscreenIntervalSeconds = 1.0f;
+constexpr float kMostlyFillViewportThresholdOfOccupationProportion = 0.85f;
+constexpr float kMostlyFillViewportThresholdOfVisibleProportion = 0.75f;
+
+} // anonymous namespace
+
+MediaCustomControlsFullscreenDetector::MediaCustomControlsFullscreenDetector(
+ HTMLVideoElement& video)
+ : EventListener(CPPEventListenerType),
+ m_videoElement(video),
+ m_checkViewportIntersectionTimer(
+ TaskRunnerHelper::get(TaskType::Unthrottled, &video.document()),
+ this,
+ &MediaCustomControlsFullscreenDetector::
+ onCheckViewportIntersectionTimerFired) {
+ videoElement().addEventListener(EventTypeNames::DOMNodeInsertedIntoDocument,
+ this, false);
+ videoElement().addEventListener(EventTypeNames::DOMNodeRemovedFromDocument,
+ this, false);
+
+ videoElement().addEventListener(EventTypeNames::loadedmetadata, this, true);
+}
+
+bool MediaCustomControlsFullscreenDetector::operator==(
+ const EventListener& other) const {
+ return this == &other;
+}
+
+void MediaCustomControlsFullscreenDetector::attach() {
+ videoElement().document().addEventListener(
+ EventTypeNames::webkitfullscreenchange, this, true);
+ videoElement().document().addEventListener(EventTypeNames::fullscreenchange,
+ this, true);
+}
+
+void MediaCustomControlsFullscreenDetector::detach() {
+ videoElement().document().removeEventListener(
+ EventTypeNames::webkitfullscreenchange, this, true);
+ videoElement().document().removeEventListener(
+ EventTypeNames::fullscreenchange, this, true);
+}
+
+bool MediaCustomControlsFullscreenDetector::computeIsDominantVideoForTests(
+ const IntRect& targetRect,
+ const IntRect& rootRect,
+ const IntRect& intersectionRect) {
+ if (targetRect.isEmpty() || rootRect.isEmpty())
+ return false;
+
+ const float xOccupationProportion =
+ 1.0f * intersectionRect.width() / rootRect.width();
+ const float yOccupationProportion =
+ 1.0f * intersectionRect.height() / rootRect.height();
+
+ // If the viewport is mostly occupied by the video, return true.
+ if (std::min(xOccupationProportion, yOccupationProportion) >=
+ kMostlyFillViewportThresholdOfOccupationProportion) {
+ return true;
+ }
+
+ // If neither of the dimensions of the viewport is mostly occupied by the
+ // video, return false.
+ if (std::max(xOccupationProportion, yOccupationProportion) <
+ kMostlyFillViewportThresholdOfOccupationProportion) {
+ return false;
+ }
+
+ // If the video is mostly visible in the indominant dimension, return true.
+ // Otherwise return false.
+ if (xOccupationProportion > yOccupationProportion) {
+ return targetRect.height() *
+ kMostlyFillViewportThresholdOfVisibleProportion <
+ intersectionRect.height();
+ }
+ return targetRect.width() * kMostlyFillViewportThresholdOfVisibleProportion <
+ intersectionRect.width();
+}
+
+void MediaCustomControlsFullscreenDetector::handleEvent(
+ ExecutionContext* context,
+ Event* event) {
+ DCHECK(event->type() == EventTypeNames::DOMNodeInsertedIntoDocument ||
+ event->type() == EventTypeNames::DOMNodeRemovedFromDocument ||
+ event->type() == EventTypeNames::loadedmetadata ||
+ event->type() == EventTypeNames::webkitfullscreenchange ||
+ event->type() == EventTypeNames::fullscreenchange);
+
+ // Don't early return when the video is inserted into/removed from the
+ // document, as the document might already be in fullscreen.
+ if (event->type() == EventTypeNames::DOMNodeInsertedIntoDocument) {
+ attach();
+ } else if (event->type() == EventTypeNames::DOMNodeRemovedFromDocument) {
+ detach();
+ }
+
+ // Video is not loaded yet.
+ if (videoElement().getReadyState() < HTMLMediaElement::kHaveMetadata)
+ return;
+
+ if (!videoElement().isConnected() || !isVideoOrParentFullscreen()) {
+ m_checkViewportIntersectionTimer.stop();
+
+ if (videoElement().webMediaPlayer())
+ videoElement().webMediaPlayer()->setIsEffectivelyFullscreen(false);
+
+ return;
+ }
+
+ m_checkViewportIntersectionTimer.startOneShot(kCheckFullscreenIntervalSeconds,
+ BLINK_FROM_HERE);
+}
+
+void MediaCustomControlsFullscreenDetector::
+ onCheckViewportIntersectionTimerFired(TimerBase*) {
+ DCHECK(isVideoOrParentFullscreen());
+ IntersectionGeometry geometry(nullptr, videoElement(), Vector<Length>(),
+ true);
+ geometry.computeGeometry();
+
+ bool isDominant = computeIsDominantVideoForTests(
+ geometry.targetIntRect(), geometry.rootIntRect(),
+ geometry.intersectionIntRect());
+
+ if (videoElement().webMediaPlayer())
+ videoElement().webMediaPlayer()->setIsEffectivelyFullscreen(isDominant);
+}
+
+bool MediaCustomControlsFullscreenDetector::isVideoOrParentFullscreen() {
+ Element* fullscreenElement =
+ Fullscreen::currentFullScreenElementFrom(videoElement().document());
+ if (!fullscreenElement)
+ return false;
+
+ return fullscreenElement->contains(&videoElement());
+}
+
+DEFINE_TRACE(MediaCustomControlsFullscreenDetector) {
+ EventListener::trace(visitor);
+ visitor->trace(m_videoElement);
+}
+
+} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698