| /* |
| * Copyright (C) 2013 Google Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are |
| * met: |
| * |
| * * Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * * Redistributions in binary form must reproduce the above |
| * copyright notice, this list of conditions and the following disclaimer |
| * in the documentation and/or other materials provided with the |
| * distribution. |
| * * Neither the name of Google Inc. nor the names of its |
| * contributors may be used to endorse or promote products derived from |
| * this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #include "config.h" |
| #include "FullscreenController.h" |
| |
| #include "RuntimeEnabledFeatures.h" |
| #include "WebFrame.h" |
| #include "WebViewClient.h" |
| #include "WebViewImpl.h" |
| #include "core/dom/Document.h" |
| #include "core/dom/FullscreenElementStack.h" |
| #include "core/html/HTMLMediaElement.h" |
| #include "core/frame/Frame.h" |
| #include "platform/LayoutTestSupport.h" |
| |
| using namespace WebCore; |
| |
| namespace blink { |
| |
| PassOwnPtr<FullscreenController> FullscreenController::create(WebViewImpl* webViewImpl) |
| { |
| return adoptPtr(new FullscreenController(webViewImpl)); |
| } |
| |
| FullscreenController::FullscreenController(WebViewImpl* webViewImpl) |
| : m_webViewImpl(webViewImpl) |
| , m_exitFullscreenPageScaleFactor(0) |
| , m_isCancelingFullScreen(false) |
| { |
| } |
| |
| void FullscreenController::willEnterFullScreen() |
| { |
| if (!m_provisionalFullScreenElement) |
| return; |
| |
| // Ensure that this element's document is still attached. |
| Document& doc = m_provisionalFullScreenElement->document(); |
| if (doc.frame()) { |
| FullscreenElementStack::from(&doc)->webkitWillEnterFullScreenForElement(m_provisionalFullScreenElement.get()); |
| m_fullScreenFrame = doc.frame(); |
| } |
| m_provisionalFullScreenElement.clear(); |
| } |
| |
| void FullscreenController::didEnterFullScreen() |
| { |
| if (!m_fullScreenFrame) |
| return; |
| |
| if (Document* doc = m_fullScreenFrame->document()) { |
| if (FullscreenElementStack::isFullScreen(doc)) { |
| if (!m_exitFullscreenPageScaleFactor) { |
| m_exitFullscreenPageScaleFactor = m_webViewImpl->pageScaleFactor(); |
| m_exitFullscreenScrollOffset = m_webViewImpl->mainFrame()->scrollOffset(); |
| m_webViewImpl->setPageScaleFactorPreservingScrollOffset(1.0f); |
| } |
| |
| FullscreenElementStack::from(doc)->webkitDidEnterFullScreenForElement(0); |
| if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled()) { |
| Element* element = FullscreenElementStack::currentFullScreenElementFrom(doc); |
| ASSERT(element); |
| if (element->isMediaElement() && m_webViewImpl->layerTreeView()) |
| m_webViewImpl->layerTreeView()->setHasTransparentBackground(true); |
| } |
| } |
| } |
| } |
| |
| void FullscreenController::willExitFullScreen() |
| { |
| if (!m_fullScreenFrame) |
| return; |
| |
| if (Document* doc = m_fullScreenFrame->document()) { |
| FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(doc); |
| if (!fullscreen) |
| return; |
| if (fullscreen->isFullScreen(doc)) { |
| // When the client exits from full screen we have to call webkitCancelFullScreen to |
| // notify the document. While doing that, suppress notifications back to the client. |
| m_isCancelingFullScreen = true; |
| fullscreen->webkitCancelFullScreen(); |
| m_isCancelingFullScreen = false; |
| fullscreen->webkitWillExitFullScreenForElement(0); |
| if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled() && m_webViewImpl->layerTreeView()) |
| m_webViewImpl->layerTreeView()->setHasTransparentBackground(m_webViewImpl->isTransparent()); |
| } |
| } |
| } |
| |
| void FullscreenController::didExitFullScreen() |
| { |
| if (!m_fullScreenFrame) |
| return; |
| |
| if (Document* doc = m_fullScreenFrame->document()) { |
| if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(doc)) { |
| if (fullscreen->webkitIsFullScreen()) { |
| if (m_exitFullscreenPageScaleFactor) { |
| m_webViewImpl->setPageScaleFactor(m_exitFullscreenPageScaleFactor, |
| WebPoint(m_exitFullscreenScrollOffset.width(), m_exitFullscreenScrollOffset.height())); |
| m_exitFullscreenPageScaleFactor = 0; |
| m_exitFullscreenScrollOffset = IntSize(); |
| } |
| |
| fullscreen->webkitDidExitFullScreenForElement(0); |
| } |
| } |
| } |
| |
| m_fullScreenFrame.clear(); |
| } |
| |
| void FullscreenController::enterFullScreenForElement(WebCore::Element* element) |
| { |
| // We are already transitioning to fullscreen for a different element. |
| if (m_provisionalFullScreenElement) { |
| m_provisionalFullScreenElement = element; |
| return; |
| } |
| |
| // We are already in fullscreen mode. |
| if (m_fullScreenFrame) { |
| m_provisionalFullScreenElement = element; |
| willEnterFullScreen(); |
| didEnterFullScreen(); |
| return; |
| } |
| |
| if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled() |
| && element && element->isMediaElement() |
| // FIXME: There is no embedder-side handling in layout test mode. |
| && !isRunningLayoutTest()) { |
| HTMLMediaElement* mediaElement = toHTMLMediaElement(element); |
| if (mediaElement->player() && mediaElement->player()->canShowFullscreenOverlay()) { |
| mediaElement->player()->showFullscreenOverlay(); |
| m_provisionalFullScreenElement = element; |
| return; |
| } |
| } |
| |
| // We need to transition to fullscreen mode. |
| if (WebViewClient* client = m_webViewImpl->client()) { |
| if (client->enterFullScreen()) |
| m_provisionalFullScreenElement = element; |
| } |
| } |
| |
| void FullscreenController::exitFullScreenForElement(WebCore::Element* element) |
| { |
| // The client is exiting full screen, so don't send a notification. |
| if (m_isCancelingFullScreen) |
| return; |
| if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled() |
| && element && element->isMediaElement() |
| // FIXME: There is no embedder-side handling in layout test mode. |
| && !isRunningLayoutTest()) { |
| HTMLMediaElement* mediaElement = toHTMLMediaElement(element); |
| if (mediaElement->player()) |
| mediaElement->player()->hideFullscreenOverlay(); |
| return; |
| } |
| if (WebViewClient* client = m_webViewImpl->client()) |
| client->exitFullScreen(); |
| } |
| |
| } |
| |