4cadc053dc1abd5d4e31ff0adb8895e20e0c5ef6
[WebKit-https.git] / Source / WebKit / WebProcess / FullScreen / WebFullScreenManager.cpp
1 /*
2  * Copyright (C) 2011 Apple 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
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 #include "config.h"
26 #include "WebFullScreenManager.h"
27
28 #if ENABLE(FULLSCREEN_API)
29
30 #include "Connection.h"
31 #include "WebCoreArgumentCoders.h"
32 #include "WebFrame.h"
33 #include "WebFullScreenManagerProxyMessages.h"
34 #include "WebPage.h"
35 #include <WebCore/Color.h>
36 #include <WebCore/Element.h>
37 #include <WebCore/Frame.h>
38 #include <WebCore/FrameView.h>
39 #include <WebCore/HTMLVideoElement.h>
40 #include <WebCore/Page.h>
41 #include <WebCore/RenderLayer.h>
42 #include <WebCore/RenderLayerBacking.h>
43 #include <WebCore/RenderObject.h>
44 #include <WebCore/RenderView.h>
45 #include <WebCore/Settings.h>
46 #include <WebCore/TypedElementDescendantIterator.h>
47
48 #if PLATFORM(IOS) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
49 #include "PlaybackSessionManager.h"
50 #endif
51
52 namespace WebKit {
53 using namespace WebCore;
54
55 static IntRect screenRectOfContents(Element* element)
56 {
57     ASSERT(element);
58     if (element->renderer() && element->renderer()->hasLayer() && element->renderer()->enclosingLayer()->isComposited()) {
59         FloatQuad contentsBox = static_cast<FloatRect>(element->renderer()->enclosingLayer()->backing()->contentsBox());
60         contentsBox = element->renderer()->localToAbsoluteQuad(contentsBox);
61         return element->renderer()->view().frameView().contentsToScreen(contentsBox.enclosingBoundingBox());
62     }
63
64     return element->screenRect();
65 }
66
67 Ref<WebFullScreenManager> WebFullScreenManager::create(WebPage* page)
68 {
69     return adoptRef(*new WebFullScreenManager(page));
70 }
71
72 WebFullScreenManager::WebFullScreenManager(WebPage* page)
73     : m_topContentInset(0)
74     , m_page(page)
75 {
76 }
77     
78 WebFullScreenManager::~WebFullScreenManager()
79 {
80 }
81
82 WebCore::Element* WebFullScreenManager::element() 
83
84     return m_element.get(); 
85 }
86
87 void WebFullScreenManager::videoControlsManagerDidChange()
88 {
89 #if PLATFORM(IOS) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
90     auto* currentPlaybackControlsElement = m_page->playbackSessionManager().currentPlaybackControlsElement();
91     if (!m_element || !is<HTMLVideoElement>(currentPlaybackControlsElement)) {
92         setPIPStandbyElement(nullptr);
93         return;
94     }
95
96     setPIPStandbyElement(downcast<HTMLVideoElement>(currentPlaybackControlsElement));
97 #endif
98 }
99
100 void WebFullScreenManager::setPIPStandbyElement(WebCore::HTMLVideoElement* pipStandbyElement)
101 {
102 #if ENABLE(VIDEO)
103     if (pipStandbyElement == m_pipStandbyElement)
104         return;
105
106     if (m_pipStandbyElement)
107         m_pipStandbyElement->setVideoFullscreenStandby(false);
108
109     m_pipStandbyElement = pipStandbyElement;
110
111     if (m_pipStandbyElement)
112         m_pipStandbyElement->setVideoFullscreenStandby(true);
113 #endif
114 }
115
116 void WebFullScreenManager::didReceiveMessage(IPC::Connection& connection, IPC::Decoder& decoder)
117 {
118     didReceiveWebFullScreenManagerMessage(connection, decoder);
119 }
120
121 bool WebFullScreenManager::supportsFullScreen(bool withKeyboard)
122 {
123     if (!m_page->corePage()->settings().fullScreenEnabled())
124         return false;
125
126     return m_page->injectedBundleFullScreenClient().supportsFullScreen(m_page.get(), withKeyboard);
127 }
128
129 void WebFullScreenManager::enterFullScreenForElement(WebCore::Element* element)
130 {
131     ASSERT(element);
132     m_element = element;
133     m_initialFrame = screenRectOfContents(m_element.get());
134     m_page->injectedBundleFullScreenClient().enterFullScreenForElement(m_page.get(), element);
135 }
136
137 void WebFullScreenManager::exitFullScreenForElement(WebCore::Element* element)
138 {
139     m_page->injectedBundleFullScreenClient().exitFullScreenForElement(m_page.get(), element);
140 }
141
142 void WebFullScreenManager::willEnterFullScreen()
143 {
144     ASSERT(m_element);
145     m_element->document().webkitWillEnterFullScreenForElement(m_element.get());
146 #if !PLATFORM(IOS)
147     m_page->hidePageBanners();
148 #endif
149     m_element->document().updateLayout();
150     m_page->forceRepaintWithoutCallback();
151     m_finalFrame = screenRectOfContents(m_element.get());
152     m_page->injectedBundleFullScreenClient().beganEnterFullScreen(m_page.get(), m_initialFrame, m_finalFrame);
153 }
154
155 void WebFullScreenManager::didEnterFullScreen()
156 {
157     ASSERT(m_element);
158     m_element->document().webkitDidEnterFullScreenForElement(m_element.get());
159
160 #if PLATFORM(IOS) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
161     auto* currentPlaybackControlsElement = m_page->playbackSessionManager().currentPlaybackControlsElement();
162     setPIPStandbyElement(is<HTMLVideoElement>(currentPlaybackControlsElement) ? downcast<HTMLVideoElement>(currentPlaybackControlsElement) : nullptr);
163 #endif
164 }
165
166 void WebFullScreenManager::willExitFullScreen()
167 {
168     ASSERT(m_element);
169
170 #if ENABLE(VIDEO)
171     setPIPStandbyElement(nullptr);
172 #endif
173
174     m_finalFrame = screenRectOfContents(m_element.get());
175     m_element->document().webkitWillExitFullScreenForElement(m_element.get());
176 #if !PLATFORM(IOS)
177     m_page->showPageBanners();
178 #endif
179     m_page->injectedBundleFullScreenClient().beganExitFullScreen(m_page.get(), m_finalFrame, m_initialFrame);
180 }
181
182 void WebFullScreenManager::didExitFullScreen()
183 {
184     ASSERT(m_element);
185     setFullscreenInsets(FloatBoxExtent());
186     setFullscreenAutoHideDuration(0_s);
187     m_element->document().webkitDidExitFullScreenForElement(m_element.get());
188 }
189
190 void WebFullScreenManager::setAnimatingFullScreen(bool animating)
191 {
192     ASSERT(m_element);
193     m_element->document().setAnimatingFullScreen(animating);
194 }
195
196 void WebFullScreenManager::requestExitFullScreen()
197 {
198     ASSERT(m_element);
199     m_element->document().webkitCancelFullScreen();
200 }
201
202 void WebFullScreenManager::close()
203 {
204     m_page->injectedBundleFullScreenClient().closeFullScreen(m_page.get());
205 }
206
207 void WebFullScreenManager::saveScrollPosition()
208 {
209     m_scrollPosition = m_page->corePage()->mainFrame().view()->scrollPosition();
210 }
211
212 void WebFullScreenManager::restoreScrollPosition()
213 {
214     m_page->corePage()->mainFrame().view()->setScrollPosition(m_scrollPosition);
215 }
216
217 void WebFullScreenManager::setFullscreenInsets(const WebCore::FloatBoxExtent& insets)
218 {
219     m_page->corePage()->setFullscreenInsets(insets);
220 }
221
222 void WebFullScreenManager::setFullscreenAutoHideDuration(Seconds duration)
223 {
224     m_page->corePage()->setFullscreenAutoHideDuration(duration);
225 }
226
227 void WebFullScreenManager::setFullscreenControlsHidden(bool hidden)
228 {
229     m_page->corePage()->setFullscreenControlsHidden(hidden);
230 }
231
232 } // namespace WebKit
233
234 #endif // ENABLE(FULLSCREEN_API)