1/* 2 * Copyright (C) 2013 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31#include "config.h" 32#include "web/FullscreenController.h" 33 34#include "core/dom/Document.h" 35#include "core/dom/Fullscreen.h" 36#include "core/frame/LocalFrame.h" 37#include "core/html/HTMLMediaElement.h" 38#include "platform/LayoutTestSupport.h" 39#include "platform/RuntimeEnabledFeatures.h" 40#include "public/web/WebFrame.h" 41#include "public/web/WebViewClient.h" 42#include "web/WebSettingsImpl.h" 43#include "web/WebViewImpl.h" 44 45namespace blink { 46 47PassOwnPtrWillBeRawPtr<FullscreenController> FullscreenController::create(WebViewImpl* webViewImpl) 48{ 49 return adoptPtrWillBeNoop(new FullscreenController(webViewImpl)); 50} 51 52FullscreenController::FullscreenController(WebViewImpl* webViewImpl) 53 : m_webViewImpl(webViewImpl) 54 , m_exitFullscreenPageScaleFactor(0) 55 , m_isCancelingFullScreen(false) 56{ 57} 58 59void FullscreenController::didEnterFullScreen() 60{ 61 if (!m_provisionalFullScreenElement) 62 return; 63 64 RefPtrWillBeRawPtr<Element> element = m_provisionalFullScreenElement.release(); 65 Document& document = element->document(); 66 m_fullScreenFrame = document.frame(); 67 68 if (!m_fullScreenFrame) 69 return; 70 71 if (!m_exitFullscreenPageScaleFactor) { 72 m_exitFullscreenPageScaleFactor = m_webViewImpl->pageScaleFactor(); 73 m_exitFullscreenScrollOffset = m_webViewImpl->mainFrame()->scrollOffset(); 74 m_exitFullscreenPinchViewportOffset = m_webViewImpl->pinchViewportOffset(); 75 m_webViewImpl->setPageScaleFactor(1.0f); 76 m_webViewImpl->setMainFrameScrollOffset(IntPoint()); 77 m_webViewImpl->setPinchViewportOffset(FloatPoint()); 78 } 79 80 Fullscreen::from(document).didEnterFullScreenForElement(element.get()); 81 ASSERT(Fullscreen::currentFullScreenElementFrom(document) == element); 82 83 if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled()) { 84 if (isHTMLMediaElement(element)) { 85 HTMLMediaElement* mediaElement = toHTMLMediaElement(element); 86 if (mediaElement->webMediaPlayer() && mediaElement->webMediaPlayer()->canEnterFullscreen() 87 // FIXME: There is no embedder-side handling in layout test mode. 88 && !LayoutTestSupport::isRunningLayoutTest()) { 89 mediaElement->webMediaPlayer()->enterFullscreen(); 90 } 91 if (m_webViewImpl->layerTreeView()) 92 m_webViewImpl->layerTreeView()->setHasTransparentBackground(true); 93 } 94 } 95} 96 97void FullscreenController::didExitFullScreen() 98{ 99 if (!m_fullScreenFrame) 100 return; 101 102 if (Document* document = m_fullScreenFrame->document()) { 103 if (Fullscreen* fullscreen = Fullscreen::fromIfExists(*document)) { 104 if (fullscreen->webkitCurrentFullScreenElement()) { 105 // When the client exits from full screen we have to call fullyExitFullscreen to notify 106 // the document. While doing that, suppress notifications back to the client. 107 m_isCancelingFullScreen = true; 108 Fullscreen::fullyExitFullscreen(*document); 109 m_isCancelingFullScreen = false; 110 111 if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled() && m_webViewImpl->layerTreeView()) 112 m_webViewImpl->layerTreeView()->setHasTransparentBackground(m_webViewImpl->isTransparent()); 113 114 if (m_exitFullscreenPageScaleFactor) { 115 m_webViewImpl->setPageScaleFactor(m_exitFullscreenPageScaleFactor); 116 m_webViewImpl->setMainFrameScrollOffset(IntPoint(m_exitFullscreenScrollOffset)); 117 m_webViewImpl->setPinchViewportOffset(m_exitFullscreenPinchViewportOffset); 118 m_exitFullscreenPageScaleFactor = 0; 119 m_exitFullscreenScrollOffset = IntSize(); 120 } 121 122 fullscreen->didExitFullScreenForElement(0); 123 } 124 } 125 } 126 127 m_fullScreenFrame.clear(); 128} 129 130void FullscreenController::enterFullScreenForElement(Element* element) 131{ 132 // We are already transitioning to fullscreen for a different element. 133 if (m_provisionalFullScreenElement) { 134 m_provisionalFullScreenElement = element; 135 return; 136 } 137 138 // We are already in fullscreen mode. 139 if (m_fullScreenFrame) { 140 m_provisionalFullScreenElement = element; 141 didEnterFullScreen(); 142 return; 143 } 144 145 // We need to transition to fullscreen mode. 146 if (WebViewClient* client = m_webViewImpl->client()) { 147 if (client->enterFullScreen()) 148 m_provisionalFullScreenElement = element; 149 } 150} 151 152void FullscreenController::exitFullScreenForElement(Element* element) 153{ 154 // The client is exiting full screen, so don't send a notification. 155 if (m_isCancelingFullScreen) 156 return; 157 if (WebViewClient* client = m_webViewImpl->client()) 158 client->exitFullScreen(); 159} 160 161void FullscreenController::trace(Visitor* visitor) 162{ 163 visitor->trace(m_provisionalFullScreenElement); 164 visitor->trace(m_fullScreenFrame); 165} 166 167} // namespace blink 168 169