Scroll to make the video element visible when exiting fullscreen.
[WebKit-https.git] / Source / WebKit2 / UIProcess / ios / WebVideoFullscreenManagerProxy.mm
1 /*
2  * Copyright (C) 2014 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
26 #import "config.h"
27 #import "WebVideoFullscreenManagerProxy.h"
28
29 #if PLATFORM(IOS)
30
31 #import "RemoteLayerTreeDrawingAreaProxy.h"
32 #import "UIKitSPI.h"
33 #import "WebPageProxy.h"
34 #import "WebProcessProxy.h"
35 #import "WebVideoFullscreenManagerMessages.h"
36 #import "WebVideoFullscreenManagerProxyMessages.h"
37 #import <QuartzCore/CoreAnimation.h>
38 #import <WebCore/TimeRanges.h>
39 #import <WebKitSystemInterface.h>
40
41 using namespace WebCore;
42
43 namespace WebKit {
44
45 #if __IPHONE_OS_VERSION_MIN_REQUIRED > 80200
46
47 PassRefPtr<WebVideoFullscreenManagerProxy> WebVideoFullscreenManagerProxy::create(WebPageProxy& page)
48 {
49     return adoptRef(new WebVideoFullscreenManagerProxy(page));
50 }
51
52 WebVideoFullscreenManagerProxy::WebVideoFullscreenManagerProxy(WebPageProxy& page)
53     : m_page(&page)
54 {
55     m_page->process().addMessageReceiver(Messages::WebVideoFullscreenManagerProxy::messageReceiverName(), m_page->pageID(), *this);
56     setWebVideoFullscreenModel(this);
57     setWebVideoFullscreenChangeObserver(this);
58 }
59
60 WebVideoFullscreenManagerProxy::~WebVideoFullscreenManagerProxy()
61 {
62     if (!m_page)
63         return;
64     invalidate();
65 }
66
67 void WebVideoFullscreenManagerProxy::invalidate()
68 {
69     WebVideoFullscreenInterfaceAVKit::invalidate();
70
71     m_page->process().removeMessageReceiver(Messages::WebVideoFullscreenManagerProxy::messageReceiverName(), m_page->pageID());
72     m_page = nullptr;
73
74     [m_layerHost removeFromSuperlayer];
75     m_layerHost.clear();
76 }
77
78 void WebVideoFullscreenManagerProxy::setupFullscreenWithID(uint32_t videoLayerID, const WebCore::IntRect& initialRect, float hostingDeviceScaleFactor, HTMLMediaElement::VideoFullscreenMode videoFullscreenMode, bool allowOptimizedFullscreen)
79 {
80     ASSERT(videoLayerID);
81     m_layerHost = WKMakeRenderLayer(videoLayerID);
82     if (hostingDeviceScaleFactor != 1) {
83         // Invert the scale transform added in the WebProcess to fix <rdar://problem/18316542>.
84         float inverseScale = 1 / hostingDeviceScaleFactor;
85         [m_layerHost setTransform:CATransform3DMakeScale(inverseScale, inverseScale, 1)];
86     }
87
88     UIView *parentView = downcast<RemoteLayerTreeDrawingAreaProxy>(*m_page->drawingArea()).remoteLayerTreeHost().rootLayer();
89     setupFullscreen(*m_layerHost.get(), initialRect, parentView, videoFullscreenMode, allowOptimizedFullscreen);
90 }
91     
92 void WebVideoFullscreenManagerProxy::fullscreenModeChanged(HTMLMediaElement::VideoFullscreenMode mode)
93 {
94     m_page->send(Messages::WebVideoFullscreenManager::fullscreenModeChanged(mode), m_page->pageID());
95 }
96     
97 void WebVideoFullscreenManagerProxy::setSeekableRangesVector(const Vector<std::pair<double, double>>& ranges)
98 {
99     RefPtr<TimeRanges> timeRanges = TimeRanges::create();
100     for (const auto& range : ranges)
101     {
102         ASSERT(isfinite(range.first));
103         ASSERT(isfinite(range.second));
104         ASSERT(range.second >= range.first);
105         timeRanges->add(range.first, range.second);
106     }
107
108     setSeekableRanges(*timeRanges);
109 }
110
111 void WebVideoFullscreenManagerProxy::setExternalPlaybackProperties(bool enabled, uint32_t targetType, String localizedDeviceName)
112 {
113     WebVideoFullscreenInterface::ExternalPlaybackTargetType type = static_cast<WebVideoFullscreenInterface::ExternalPlaybackTargetType>(targetType);
114     
115     ASSERT(type == WebVideoFullscreenInterface::TargetTypeAirPlay || type == WebVideoFullscreenInterface::TargetTypeTVOut || type == WebVideoFullscreenInterface::TargetTypeNone);
116     
117     setExternalPlayback(enabled, type, localizedDeviceName);
118 }
119     
120 void WebVideoFullscreenManagerProxy::fullscreenMayReturnToInline()
121 {
122     bool isViewVisible = m_page->isViewVisible();
123     m_page->send(Messages::WebVideoFullscreenManager::FullscreenMayReturnToInline(isViewVisible), m_page->pageID());
124 }
125     
126 void WebVideoFullscreenManagerProxy::preparedToReturnToInline(bool visible, const WebCore::IntRect& inlineRect)
127 {
128     m_page->fullscreenMayReturnToInline();
129     WebVideoFullscreenInterfaceAVKit::preparedToReturnToInline(visible, inlineRect);
130 }
131
132 void WebVideoFullscreenManagerProxy::requestExitFullscreen()
133 {
134     m_page->send(Messages::WebVideoFullscreenManager::RequestExitFullscreen(), m_page->pageID());
135 }
136
137 void WebVideoFullscreenManagerProxy::didExitFullscreen()
138 {
139     m_page->send(Messages::WebVideoFullscreenManager::DidExitFullscreen(), m_page->pageID());
140     m_page->didExitFullscreen();
141 }
142     
143 void WebVideoFullscreenManagerProxy::didCleanupFullscreen()
144 {
145     [CATransaction flush];
146     [m_layerHost removeFromSuperlayer];
147     m_layerHost.clear();
148     m_page->send(Messages::WebVideoFullscreenManager::DidCleanupFullscreen(), m_page->pageID());
149 }
150
151 void WebVideoFullscreenManagerProxy::didSetupFullscreen()
152 {
153     m_page->send(Messages::WebVideoFullscreenManager::DidSetupFullscreen(), m_page->pageID());
154 }
155
156 void WebVideoFullscreenManagerProxy::didEnterFullscreen()
157 {
158     m_page->send(Messages::WebVideoFullscreenManager::DidEnterFullscreen(), m_page->pageID());
159     m_page->didEnterFullscreen();
160 }
161
162 void WebVideoFullscreenManagerProxy::play()
163 {
164     m_page->send(Messages::WebVideoFullscreenManager::Play(), m_page->pageID());
165 }
166     
167 void WebVideoFullscreenManagerProxy::pause()
168 {
169     m_page->send(Messages::WebVideoFullscreenManager::Pause(), m_page->pageID());
170 }
171     
172 void WebVideoFullscreenManagerProxy::togglePlayState()
173 {
174     m_page->send(Messages::WebVideoFullscreenManager::TogglePlayState(), m_page->pageID());
175 }
176     
177 void WebVideoFullscreenManagerProxy::beginScrubbing()
178 {
179     m_page->send(Messages::WebVideoFullscreenManager::BeginScrubbing(), m_page->pageID());
180 }
181
182 void WebVideoFullscreenManagerProxy::endScrubbing()
183 {
184     m_page->send(Messages::WebVideoFullscreenManager::EndScrubbing(), m_page->pageID());
185 }
186
187 void WebVideoFullscreenManagerProxy::seekToTime(double time)
188 {
189     m_page->send(Messages::WebVideoFullscreenManager::SeekToTime(time), m_page->pageID());
190 }
191
192 void WebVideoFullscreenManagerProxy::fastSeek(double time)
193 {
194     m_page->send(Messages::WebVideoFullscreenManager::FastSeek(time), m_page->pageID());
195 }
196
197 void WebVideoFullscreenManagerProxy::beginScanningForward()
198 {
199     m_page->send(Messages::WebVideoFullscreenManager::BeginScanningForward(), m_page->pageID());
200 }
201
202 void WebVideoFullscreenManagerProxy::beginScanningBackward()
203 {
204     m_page->send(Messages::WebVideoFullscreenManager::BeginScanningBackward(), m_page->pageID());
205 }
206
207 void WebVideoFullscreenManagerProxy::endScanning()
208 {
209     m_page->send(Messages::WebVideoFullscreenManager::EndScanning(), m_page->pageID());
210 }
211
212 void WebVideoFullscreenManagerProxy::setVideoLayerFrame(WebCore::FloatRect frame)
213 {
214     IPC::Attachment fencePort([UIWindow _synchronizeDrawingAcrossProcesses], MACH_MSG_TYPE_MOVE_SEND);
215     m_page->send(Messages::WebVideoFullscreenManager::SetVideoLayerFrameFenced(frame, fencePort), m_page->pageID());
216 }
217
218 void WebVideoFullscreenManagerProxy::setVideoLayerGravity(WebCore::WebVideoFullscreenModel::VideoGravity gravity)
219 {
220     m_page->send(Messages::WebVideoFullscreenManager::SetVideoLayerGravityEnum((unsigned)gravity), m_page->pageID());
221 }
222     
223 void WebVideoFullscreenManagerProxy::selectAudioMediaOption(uint64_t index)
224 {
225     m_page->send(Messages::WebVideoFullscreenManager::SelectAudioMediaOption(index), m_page->pageID());
226 }
227     
228 void WebVideoFullscreenManagerProxy::selectLegibleMediaOption(uint64_t index)
229 {
230     m_page->send(Messages::WebVideoFullscreenManager::SelectLegibleMediaOption(index), m_page->pageID());
231 }
232 #endif
233
234 } // namespace WebKit
235
236 #endif // PLATFORM(IOS)