Chromium Code Reviews| 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..2c82edd0912895758b903fe160849176d4ace39d |
| --- /dev/null |
| +++ b/third_party/WebKit/Source/core/html/MediaCustomControlsFullscreenDetector.cpp |
| @@ -0,0 +1,129 @@ |
| +// 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/DocumentFullscreen.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().document().addEventListener( |
| + EventTypeNames::webkitfullscreenchange, this, true); |
| + videoElement().document().addEventListener(EventTypeNames::fullscreenchange, |
| + this, true); |
| +} |
| + |
| +bool MediaCustomControlsFullscreenDetector::operator==( |
| + const EventListener& other) const { |
| + return this == &other; |
| +} |
| + |
| +void MediaCustomControlsFullscreenDetector::didMoveToNewDocument( |
| + Document& oldDocument) { |
| + oldDocument.removeEventListener(EventTypeNames::webkitfullscreenchange, this, |
| + true); |
| + oldDocument.removeEventListener(EventTypeNames::fullscreenchange, this, true); |
|
mlamouri (slow - plz ping)
2017/02/21 21:58:28
We should call addEventListener on the new documen
Zhiqiang Zhang (Slow)
2017/02/22 12:29:18
Done.
|
| +} |
| + |
| +bool MediaCustomControlsFullscreenDetector::computeIsDominantVideo( |
| + bool isVideoOrParentFullscreen, |
| + const IntRect& targetRect, |
| + const IntRect& rootRect, |
| + const IntRect& intersectionRect) { |
| + if (!isVideoOrParentFullscreen) |
| + return false; |
|
mlamouri (slow - plz ping)
2017/02/21 21:58:28
Can this happen? We should be fullscreen, right?
Zhiqiang Zhang (Slow)
2017/02/22 12:29:18
Done, removed this parameter as we should be in fu
|
| + |
| + 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::fullscreenchange || |
| + event->type() == EventTypeNames::webkitfullscreenchange); |
| + if (!isVideoOrParentFullscreen()) { |
| + if (videoElement().webMediaPlayer()) { |
| + videoElement().webMediaPlayer()->becameDominantVisibleContentInFullscreen( |
| + false); |
|
mlamouri (slow - plz ping)
2017/02/21 21:58:28
We should probably cancel the timer too so we guar
Zhiqiang Zhang (Slow)
2017/02/22 12:29:18
Done.
|
| + } |
| + return; |
| + } |
| + |
| + m_checkViewportIntersectionTimer.startOneShot(kCheckFullscreenIntervalSeconds, |
| + BLINK_FROM_HERE); |
| +} |
| + |
| +void MediaCustomControlsFullscreenDetector:: |
| + onCheckViewportIntersectionTimerFired(TimerBase*) { |
| + IntersectionGeometry geometry(nullptr, videoElement(), Vector<Length>(), |
| + true); |
| + geometry.computeGeometry(); |
| + |
| + bool isDominant = computeIsDominantVideo( |
| + isVideoOrParentFullscreen(), geometry.targetIntRect(), |
| + geometry.rootIntRect(), geometry.intersectionIntRect()); |
| + |
| + if (videoElement().webMediaPlayer()) { |
| + videoElement().webMediaPlayer()->becameDominantVisibleContentInFullscreen( |
| + isDominant); |
|
mlamouri (slow - plz ping)
2017/02/21 21:58:28
What happens if the video goes fullscreen before p
Zhiqiang Zhang (Slow)
2017/02/22 12:29:18
Now I also listen to loadedmetadata. When any even
|
| + } |
| +} |
| + |
| +bool MediaCustomControlsFullscreenDetector::isVideoOrParentFullscreen() { |
| + return DocumentFullscreen::fullscreenElement(videoElement().document()); |
| +} |
| + |
| +DEFINE_TRACE(MediaCustomControlsFullscreenDetector) { |
| + EventListener::trace(visitor); |
| + visitor->trace(m_videoElement); |
| +} |
| + |
| +} // namespace blink |