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
45 namespace blink {
46
create(WebViewImpl * webViewImpl)47 PassOwnPtrWillBeRawPtr<FullscreenController> FullscreenController::create(WebViewImpl* webViewImpl)
48 {
49 return adoptPtrWillBeNoop(new FullscreenController(webViewImpl));
50 }
51
FullscreenController(WebViewImpl * webViewImpl)52 FullscreenController::FullscreenController(WebViewImpl* webViewImpl)
53 : m_webViewImpl(webViewImpl)
54 , m_exitFullscreenPageScaleFactor(0)
55 , m_isCancelingFullScreen(false)
56 {
57 }
58
didEnterFullScreen()59 void 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
didExitFullScreen()97 void 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
enterFullScreenForElement(Element * element)130 void 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
exitFullScreenForElement(Element * element)152 void 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
trace(Visitor * visitor)161 void FullscreenController::trace(Visitor* visitor)
162 {
163 visitor->trace(m_provisionalFullScreenElement);
164 visitor->trace(m_fullScreenFrame);
165 }
166
167 } // namespace blink
168
169