[Mac] tag the video layers with descriptive name to aid debugging
[WebKit-https.git] / Source / WebKit2 / WebProcess / ios / WebVideoFullscreenManager.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 #include "config.h"
26 #include "WebVideoFullscreenManager.h"
27
28 #if PLATFORM(IOS)
29
30 #include "WebCoreArgumentCoders.h"
31 #include "WebPage.h"
32 #include "WebProcess.h"
33 #include "WebVideoFullscreenManagerMessages.h"
34 #include "WebVideoFullscreenManagerProxyMessages.h"
35 #include <QuartzCore/CoreAnimation.h>
36 #include <WebCore/Event.h>
37 #include <WebCore/EventNames.h>
38 #include <WebCore/FrameView.h>
39 #include <WebCore/HTMLVideoElement.h>
40 #include <WebCore/PlatformCALayer.h>
41 #include <WebCore/RenderLayer.h>
42 #include <WebCore/RenderLayerBacking.h>
43 #include <WebCore/RenderView.h>
44 #include <WebCore/Settings.h>
45 #include <WebCore/TimeRanges.h>
46 #include <WebCore/WebCoreThreadRun.h>
47
48 using namespace WebCore;
49
50 namespace WebKit {
51
52 static IntRect screenRectForNode(Node* node)
53 {
54     if (!node || !node->isElementNode())
55         return IntRect();
56
57     return toElement(node)->screenRect();
58 }
59
60 PassRefPtr<WebVideoFullscreenManager> WebVideoFullscreenManager::create(PassRefPtr<WebPage> page)
61 {
62     return adoptRef(new WebVideoFullscreenManager(page));
63 }
64
65 WebVideoFullscreenManager::WebVideoFullscreenManager(PassRefPtr<WebPage> page)
66     : m_page(page.get())
67     , m_isAnimating(false)
68     , m_targetIsFullscreen(false)
69     , m_isFullscreen(false)
70 {
71     setWebVideoFullscreenInterface(this);
72     WebProcess::shared().addMessageReceiver(Messages::WebVideoFullscreenManager::messageReceiverName(), page->pageID(), *this);
73 }
74
75 WebVideoFullscreenManager::~WebVideoFullscreenManager()
76 {
77     WebProcess::shared().removeMessageReceiver(Messages::WebVideoFullscreenManager::messageReceiverName(), m_page->pageID());
78 }
79
80 bool WebVideoFullscreenManager::supportsFullscreen(const Node* node) const
81 {
82     return Settings::avKitEnabled() && isHTMLVideoElement(node);
83 }
84
85 void WebVideoFullscreenManager::enterFullscreenForNode(Node* node)
86 {
87     ASSERT(node);
88     m_node = node;
89     m_targetIsFullscreen = true;
90
91     if (m_isAnimating)
92         return;
93
94     m_isAnimating = true;
95     setMediaElement(toHTMLMediaElement(node));
96
97     PlatformLayer* videoLayer = [CALayer layer];
98 #ifndef NDEBUG
99     [videoLayer setName:@"Web video fullscreen manager layer"];
100 #endif
101     m_layerHostingContext = LayerHostingContext::createForExternalHostingProcess();
102     m_layerHostingContext->setRootLayer(videoLayer);
103     setVideoFullscreenLayer(videoLayer);
104
105     m_page->send(Messages::WebVideoFullscreenManagerProxy::EnterFullscreenWithID(m_layerHostingContext->contextID(), screenRectForNode(node)), m_page->pageID());
106 }
107
108 void WebVideoFullscreenManager::exitFullscreenForNode(Node* node)
109 {
110     m_node.clear();
111     m_targetIsFullscreen = false;
112
113     if (m_isAnimating)
114         return;
115
116     m_isAnimating = true;
117     m_page->send(Messages::WebVideoFullscreenManagerProxy::ExitFullscreen(screenRectForNode(node)), m_page->pageID());
118 }
119
120 void WebVideoFullscreenManager::setDuration(double duration)
121 {
122     m_page->send(Messages::WebVideoFullscreenManagerProxy::SetDuration(duration), m_page->pageID());
123 }
124
125 void WebVideoFullscreenManager::setCurrentTime(double currentTime, double anchorTime)
126 {
127     m_page->send(Messages::WebVideoFullscreenManagerProxy::SetCurrentTime(currentTime, anchorTime), m_page->pageID());
128 }
129
130 void WebVideoFullscreenManager::setRate(bool isPlaying, float playbackRate)
131 {
132     m_page->send(Messages::WebVideoFullscreenManagerProxy::SetRate(isPlaying, playbackRate), m_page->pageID());
133 }
134
135 void WebVideoFullscreenManager::setVideoDimensions(bool hasVideo, float width, float height)
136 {
137     m_page->send(Messages::WebVideoFullscreenManagerProxy::SetVideoDimensions(hasVideo, width, height), m_page->pageID());
138 }
139     
140 void WebVideoFullscreenManager::setSeekableRanges(const WebCore::TimeRanges& timeRanges)
141 {
142     Vector<std::pair<double, double>> rangesVector;
143     
144     for (unsigned i = 0; i < timeRanges.length(); i++) {
145         ExceptionCode exceptionCode;
146         double start = timeRanges.start(i, exceptionCode);
147         double end = timeRanges.end(i, exceptionCode);
148         rangesVector.append(std::pair<double,double>(start, end));
149     }
150
151     m_page->send(Messages::WebVideoFullscreenManagerProxy::SetSeekableRangesVector(std::move(rangesVector)), m_page->pageID());
152 }
153
154 void WebVideoFullscreenManager::setAudioMediaSelectionOptions(const Vector<String>& options, uint64_t selectedIndex)
155 {
156     m_page->send(Messages::WebVideoFullscreenManagerProxy::SetAudioMediaSelectionOptions(options, selectedIndex), m_page->pageID());
157 }
158
159 void WebVideoFullscreenManager::setLegibleMediaSelectionOptions(const Vector<String>& options, uint64_t selectedIndex)
160 {
161     m_page->send(Messages::WebVideoFullscreenManagerProxy::SetLegibleMediaSelectionOptions(options, selectedIndex), m_page->pageID());
162 }
163     
164 void WebVideoFullscreenManager::didEnterFullscreen()
165 {
166     m_isAnimating = false;
167     m_isFullscreen = false;
168
169     if (m_targetIsFullscreen)
170         return;
171
172     // exit fullscreen now if it was previously requested during an animation.
173     __block RefPtr<WebVideoFullscreenModelMediaElement> protect(this);
174     WebThreadRun(^ {
175         exitFullscreenForNode(m_node.get());
176         protect.clear();
177     });
178 }
179
180 void WebVideoFullscreenManager::didExitFullscreen()
181 {
182     m_isAnimating = false;
183     m_isFullscreen = false;
184
185     m_layerHostingContext->setRootLayer(nullptr);
186     m_layerHostingContext = nullptr;
187     setVideoFullscreenLayer(nullptr);
188
189     setMediaElement(nullptr);
190
191     if (!m_targetIsFullscreen)
192         return;
193
194     // enter fullscreen now if it was previously requested during an animation.
195     __block RefPtr<WebVideoFullscreenModelMediaElement> protect(this);
196     WebThreadRun(^ {
197         enterFullscreenForNode(m_node.get());
198         protect.clear();
199     });
200 }
201     
202 void WebVideoFullscreenManager::setVideoLayerGravityEnum(unsigned gravity)
203 {
204     setVideoLayerGravity((WebVideoFullscreenModel::VideoGravity)gravity);
205 }
206
207 } // namespace WebKit
208
209 #endif // PLATFORM(IOS)