Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(74)

Side by Side Diff: third_party/WebKit/Source/web/FullscreenController.cpp

Issue 2495423004: Convert FullscreenController to use WebCallbacks (Closed)
Patch Set: public/WebFullscreenCallbacks->core/FullscreenCallbacks Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 14 matching lines...) Expand all
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 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. 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 30
31 #include "web/FullscreenController.h" 31 #include "web/FullscreenController.h"
32 32
33 #include "core/dom/Document.h" 33 #include "core/dom/Document.h"
34 #include "core/dom/Fullscreen.h" 34 #include "core/dom/Fullscreen.h"
35 #include "core/dom/FullscreenCallbacks.h"
35 #include "core/frame/FrameView.h" 36 #include "core/frame/FrameView.h"
36 #include "core/frame/LocalFrame.h" 37 #include "core/frame/LocalFrame.h"
37 #include "core/frame/PageScaleConstraintsSet.h" 38 #include "core/frame/PageScaleConstraintsSet.h"
38 #include "core/html/HTMLVideoElement.h" 39 #include "core/html/HTMLVideoElement.h"
39 #include "core/layout/LayoutFullScreen.h" 40 #include "core/layout/LayoutFullScreen.h"
40 #include "platform/RuntimeEnabledFeatures.h"
41 #include "public/platform/WebLayerTreeView.h" 41 #include "public/platform/WebLayerTreeView.h"
42 #include "public/web/WebFrameClient.h" 42 #include "public/web/WebFrameClient.h"
43 #include "web/WebLocalFrameImpl.h" 43 #include "web/WebLocalFrameImpl.h"
44 #include "web/WebSettingsImpl.h"
45 #include "web/WebViewImpl.h" 44 #include "web/WebViewImpl.h"
46 45
47 namespace blink { 46 namespace blink {
48 47
49 FullscreenController* FullscreenController::create(WebViewImpl* webViewImpl) { 48 std::unique_ptr<FullscreenController> FullscreenController::create(
50 return new FullscreenController(webViewImpl); 49 WebViewImpl* webViewImpl) {
50 return wrapUnique(new FullscreenController(webViewImpl));
51 } 51 }
52 52
53 FullscreenController::FullscreenController(WebViewImpl* webViewImpl) 53 FullscreenController::FullscreenController(WebViewImpl* webViewImpl)
54 : m_webViewImpl(webViewImpl), 54 : m_webViewImpl(webViewImpl) {}
55 m_haveEnteredFullscreen(false),
56 m_exitFullscreenPageScaleFactor(0),
57 m_needsScrollAndScaleRestore(false),
58 m_isCancelingFullscreen(false) {}
59 55
60 void FullscreenController::didEnterFullscreen() { 56 void FullscreenController::didEnterFullscreen() {
61 if (!m_provisionalFullscreenElement) 57 // Browser::EnterFullscreenModeForTab can enter fullscreen without going
58 // through Fullscreen::requestFullscreen, in which case there will be no
59 // fullscreen element. Do nothing.
60 if (m_state != State::kEnteringFullscreen)
62 return; 61 return;
63 62
64 Element* element = m_provisionalFullscreenElement.release(); 63 updatePageScaleConstraints(false);
65 Document& document = element->document(); 64 m_webViewImpl->setPageScaleFactor(1.0f);
66 m_fullscreenFrame = document.frame(); 65 if (m_webViewImpl->mainFrame()->isWebLocalFrame())
66 m_webViewImpl->mainFrame()->setScrollOffset(WebSize());
67 m_webViewImpl->setVisualViewportOffset(FloatPoint());
67 68
68 if (!m_fullscreenFrame) 69 DCHECK(!m_callbacksList.isEmpty());
69 return; 70 CallbacksList callbacksList;
71 callbacksList.swap(m_callbacksList);
72 for (auto& callbacks : callbacksList)
73 callbacks->onSuccess();
70 74
71 if (!m_haveEnteredFullscreen) { 75 m_state = State::kFullscreen;
72 updatePageScaleConstraints(false);
73 m_webViewImpl->setPageScaleFactor(1.0f);
74 if (m_webViewImpl->mainFrame()->isWebLocalFrame())
75 m_webViewImpl->mainFrame()->setScrollOffset(WebSize());
76 m_webViewImpl->setVisualViewportOffset(FloatPoint());
77 m_haveEnteredFullscreen = true;
78 }
79
80 Fullscreen::from(document).didEnterFullscreenForElement(element);
81 DCHECK_EQ(Fullscreen::currentFullScreenElementFrom(document), element);
82 } 76 }
83 77
84 void FullscreenController::didExitFullscreen() { 78 void FullscreenController::didExitFullscreen() {
85 if (!m_fullscreenFrame) 79 // The browser process can exit fullscreen at any time, e.g. if the user
80 // presses Esc. After Browser::EnterFullscreenModeForTab,
81 // Browser::ExitFullscreenModeForTab will make it seem like we exit when not
82 // even in fullscreen. Do nothing.
83 if (m_state == State::kInitial)
86 return; 84 return;
87 85
88 if (m_haveEnteredFullscreen) 86 updatePageScaleConstraints(true);
89 updatePageScaleConstraints(true);
90 87
91 if (Document* document = m_fullscreenFrame->document()) { 88 // If we were transitioning into fullscreen, invoke the error callbacks.
92 if (Fullscreen* fullscreen = Fullscreen::fromIfExists(*document)) { 89 if (m_state == State::kEnteringFullscreen) {
93 Element* element = fullscreen->currentFullScreenElement(); 90 DCHECK(!m_callbacksList.isEmpty());
94 if (element) { 91 CallbacksList callbacksList;
95 // When the client exits from full screen we have to call 92 callbacksList.swap(m_callbacksList);
96 // fullyExitFullscreen to notify the document. While doing that, 93 for (auto& callbacks : callbacksList)
esprehn 2016/12/01 20:26:12 Can we just move all of this logic down into core
foolip 2016/12/01 23:05:01 All of FullscreenController? In order to handle fu
97 // suppress notifications back to the client. 94 callbacks->onError();
98 m_isCancelingFullscreen = true; 95 } else {
99 Fullscreen::fullyExitFullscreen(*document); 96 DCHECK(m_callbacksList.isEmpty());
100 m_isCancelingFullscreen = false; 97 }
101 98
102 // We need to wait until style and layout are updated in order 99 // Set m_state so that any calls to enterFullscreen() or exitFullscreen() from
103 // to propertly restore scroll offsets since content may not be 100 // within Fullscreen::didExitFullscreen do nothing.
104 // overflowing in the same way until they do. 101 m_state = State::kExitingFullscreen;
105 if (m_haveEnteredFullscreen)
106 m_needsScrollAndScaleRestore = true;
107 102
103 // Notify all local frames that we have exited fullscreen.
104 // TODO(foolip): This should only need to notify the topmost local roots. That
105 // doesn't currently work because Fullscreen::m_currentFullScreenElement isn't
106 // set for the topmost document when an iframe goes fullscreen, but can be
107 // done once m_currentFullScreenElement is gone and all state is in the
108 // fullscreen element stack. https://crbug.com/402421
109 for (Frame* frame = m_webViewImpl->page()->mainFrame(); frame;
110 frame = frame->tree().traverseNext()) {
111 if (!frame->isLocalFrame())
112 continue;
113 if (Document* document = toLocalFrame(frame)->document()) {
114 if (Fullscreen* fullscreen = Fullscreen::fromIfExists(*document))
108 fullscreen->didExitFullscreen(); 115 fullscreen->didExitFullscreen();
109 }
110 } 116 }
111 } 117 }
112 118
113 m_haveEnteredFullscreen = false; 119 // We need to wait until style and layout are updated in order to properly
114 m_fullscreenFrame.clear(); 120 // restore scroll offsets since content may not be overflowing in the same way
121 // until they are.
122 m_state = State::kNeedsScrollAndScaleRestore;
115 } 123 }
116 124
117 void FullscreenController::enterFullscreenForElement(Element* element) { 125 namespace {
118 // We are already transitioning to fullscreen for a different element. 126
119 if (m_provisionalFullscreenElement) { 127 WebFrameClient& webFrameClient(LocalFrame& frame) {
120 m_provisionalFullscreenElement = element; 128 WebLocalFrameImpl* webFrame = WebLocalFrameImpl::fromFrame(frame);
129 DCHECK(webFrame);
130 DCHECK(webFrame->client());
131 return *webFrame->client();
132 }
133
134 } // anonymous namespace
135
136 void FullscreenController::enterFullscreen(
137 LocalFrame& frame,
138 std::unique_ptr<FullscreenCallbacks> callbacks) {
139 // If already in fullscreen, synchronously invoke the success callback.
140 if (m_state == State::kFullscreen) {
141 DCHECK(m_callbacksList.isEmpty());
142 callbacks->onSuccess();
121 return; 143 return;
122 } 144 }
123 145
124 // We are already in fullscreen mode. 146 // While exiting fullscreen, reject any attempt to enter.
125 if (m_fullscreenFrame) { 147 if (m_state == State::kExitingFullscreen) {
126 m_provisionalFullscreenElement = element; 148 callbacks->onError();
127 didEnterFullscreen();
128 return; 149 return;
129 } 150 }
130 151
131 // We need to store these values here rather than didEnterFullscreen since 152 // We need to store these values here rather than didEnterFullscreen since
132 // by the time the latter is called, a Resize has already occured, clamping 153 // by the time the latter is called, a Resize has already occured, clamping
133 // the scroll offset. Don't save values if we're still waiting to restore 154 // the scroll offset. Don't save values if we're still waiting to restore
134 // a previous set. This can happen if we exit and quickly reenter fullscreen 155 // a previous set. This can happen if we exit and quickly reenter fullscreen
135 // without performing a layout. 156 // without performing a layout.
136 if (!m_haveEnteredFullscreen && !m_needsScrollAndScaleRestore) { 157 if (m_state == State::kInitial) {
137 m_exitFullscreenPageScaleFactor = m_webViewImpl->pageScaleFactor(); 158 m_initialPageScaleFactor = m_webViewImpl->pageScaleFactor();
138 m_exitFullscreenScrollOffset = 159 m_initialScrollOffset = m_webViewImpl->mainFrame()->isWebLocalFrame()
139 m_webViewImpl->mainFrame()->isWebLocalFrame() 160 ? m_webViewImpl->mainFrame()->scrollOffset()
140 ? m_webViewImpl->mainFrame()->scrollOffset() 161 : WebSize();
141 : WebSize(); 162 m_initialVisualViewportOffset = m_webViewImpl->visualViewportOffset();
142 m_exitFullscreenVisualViewportOffset =
143 m_webViewImpl->visualViewportOffset();
144 } 163 }
145 164
146 // We need to transition to fullscreen mode. 165 m_callbacksList.append(std::move(callbacks));
147 WebLocalFrameImpl* frame = 166
148 WebLocalFrameImpl::fromFrame(element->document().frame()); 167 // If already entering fullscreen, just wait.
149 if (frame && frame->client()) { 168 if (m_state == State::kEnteringFullscreen)
150 if (!Fullscreen::from(element->document()).forCrossProcessDescendant()) 169 return;
151 frame->client()->enterFullscreen(); 170
152 m_provisionalFullscreenElement = element; 171 DCHECK(m_state == State::kInitial ||
153 } 172 m_state == State::kNeedsScrollAndScaleRestore);
173 webFrameClient(frame).enterFullscreen();
174
175 m_state = State::kEnteringFullscreen;
154 } 176 }
155 177
156 void FullscreenController::exitFullscreen(LocalFrame* frame) { 178 void FullscreenController::exitFullscreen(LocalFrame& frame) {
157 DCHECK(frame); 179 // If not in fullscreen, ignore any attempt to exit. In particular, for
158 180 // State::kEnteringFullscreen, allow the transition into fullscreen to
159 // The client is exiting full screen, so don't send a notification. 181 // complete. Note that the browser process is ultimately in control and can
160 if (m_isCancelingFullscreen) 182 // still (indirecitly) call didExitFullscreen() at any time to exit.
183 if (m_state != State::kFullscreen)
161 return; 184 return;
162 185
163 WebLocalFrameImpl* webFrame = WebLocalFrameImpl::fromFrame(frame); 186 webFrameClient(frame).exitFullscreen();
164 if (webFrame && webFrame->client()) 187
165 webFrame->client()->exitFullscreen(); 188 m_state = State::kExitingFullscreen;
166 } 189 }
167 190
168 void FullscreenController::fullscreenElementChanged(Element* fromElement, 191 void FullscreenController::fullscreenElementChanged(Element* fromElement,
169 Element* toElement) { 192 Element* toElement) {
170 DCHECK_NE(fromElement, toElement); 193 DCHECK_NE(fromElement, toElement);
171 194
172 if (toElement) { 195 if (toElement) {
173 DCHECK(Fullscreen::isCurrentFullScreenElement(*toElement)); 196 DCHECK(Fullscreen::isCurrentFullScreenElement(*toElement));
174 197
175 if (isHTMLVideoElement(*toElement)) { 198 if (isHTMLVideoElement(*toElement)) {
(...skipping 19 matching lines...) Expand all
195 m_webViewImpl->isTransparent()); 218 m_webViewImpl->isTransparent());
196 } 219 }
197 220
198 HTMLVideoElement& videoElement = toHTMLVideoElement(*fromElement); 221 HTMLVideoElement& videoElement = toHTMLVideoElement(*fromElement);
199 videoElement.didExitFullscreen(); 222 videoElement.didExitFullscreen();
200 } 223 }
201 } 224 }
202 } 225 }
203 226
204 void FullscreenController::updateSize() { 227 void FullscreenController::updateSize() {
205 if (!isFullscreen()) 228 DCHECK(m_webViewImpl->page());
229
230 if (m_state != State::kFullscreen)
206 return; 231 return;
207 232
208 updatePageScaleConstraints(false); 233 updatePageScaleConstraints(false);
209 234
210 LayoutFullScreen* layoutObject = 235 // Traverse all local frames and notify the LayoutFullScreen object, if any.
211 Fullscreen::from(*m_fullscreenFrame->document()).fullScreenLayoutObject(); 236 for (Frame* frame = m_webViewImpl->page()->mainFrame(); frame;
212 if (layoutObject) 237 frame = frame->tree().traverseNext()) {
213 layoutObject->updateStyle(); 238 if (!frame->isLocalFrame())
239 continue;
240 if (Document* document = toLocalFrame(frame)->document()) {
241 if (Fullscreen* fullscreen = Fullscreen::fromIfExists(*document)) {
242 if (LayoutFullScreen* layoutObject =
243 fullscreen->fullScreenLayoutObject())
244 layoutObject->updateStyle();
245 }
246 }
247 }
214 } 248 }
215 249
216 void FullscreenController::didUpdateLayout() { 250 void FullscreenController::didUpdateLayout() {
217 if (!m_needsScrollAndScaleRestore) 251 if (m_state != State::kNeedsScrollAndScaleRestore)
218 return; 252 return;
219 253
220 // If we re-entered fullscreen before we could restore the scroll and scale 254 m_webViewImpl->setPageScaleFactor(m_initialPageScaleFactor);
221 // don't try restoring them yet. 255 if (m_webViewImpl->mainFrame()->isWebLocalFrame())
222 if (isFullscreen()) 256 m_webViewImpl->mainFrame()->setScrollOffset(WebSize(m_initialScrollOffset));
223 return; 257 m_webViewImpl->setVisualViewportOffset(m_initialVisualViewportOffset);
224 258
225 m_webViewImpl->setPageScaleFactor(m_exitFullscreenPageScaleFactor); 259 m_state = State::kInitial;
226 if (m_webViewImpl->mainFrame()->isWebLocalFrame())
227 m_webViewImpl->mainFrame()->setScrollOffset(
228 WebSize(m_exitFullscreenScrollOffset));
229 m_webViewImpl->setVisualViewportOffset(m_exitFullscreenVisualViewportOffset);
230 m_needsScrollAndScaleRestore = false;
231 } 260 }
232 261
233 void FullscreenController::updatePageScaleConstraints(bool removeConstraints) { 262 void FullscreenController::updatePageScaleConstraints(bool removeConstraints) {
234 PageScaleConstraints fullscreenConstraints; 263 PageScaleConstraints fullscreenConstraints;
235 if (!removeConstraints) { 264 if (!removeConstraints) {
236 fullscreenConstraints = PageScaleConstraints(1.0, 1.0, 1.0); 265 fullscreenConstraints = PageScaleConstraints(1.0, 1.0, 1.0);
237 fullscreenConstraints.layoutSize = FloatSize(m_webViewImpl->size()); 266 fullscreenConstraints.layoutSize = FloatSize(m_webViewImpl->size());
238 } 267 }
239 m_webViewImpl->pageScaleConstraintsSet().setFullscreenConstraints( 268 m_webViewImpl->pageScaleConstraintsSet().setFullscreenConstraints(
240 fullscreenConstraints); 269 fullscreenConstraints);
241 m_webViewImpl->pageScaleConstraintsSet().computeFinalConstraints(); 270 m_webViewImpl->pageScaleConstraintsSet().computeFinalConstraints();
242 271
243 // Although we called computedFinalConstraints() above, the "final" 272 // Although we called computedFinalConstraints() above, the "final"
244 // constraints are not actually final. They are still subject to scale factor 273 // constraints are not actually final. They are still subject to scale factor
245 // clamping by contents size. Normally they should be dirtied due to 274 // clamping by contents size. Normally they should be dirtied due to
246 // contents size mutation after layout, however the contents size is not 275 // contents size mutation after layout, however the contents size is not
247 // guaranteed to mutate, and the scale factor may remain unclamped. Just 276 // guaranteed to mutate, and the scale factor may remain unclamped. Just
248 // fire the event again to ensure the final constraints pick up the latest 277 // fire the event again to ensure the final constraints pick up the latest
249 // contents size. 278 // contents size.
250 m_webViewImpl->didChangeContentsSize(); 279 m_webViewImpl->didChangeContentsSize();
251 if (m_webViewImpl->mainFrameImpl() && 280 if (m_webViewImpl->mainFrameImpl() &&
252 m_webViewImpl->mainFrameImpl()->frameView()) 281 m_webViewImpl->mainFrameImpl()->frameView())
253 m_webViewImpl->mainFrameImpl()->frameView()->setNeedsLayout(); 282 m_webViewImpl->mainFrameImpl()->frameView()->setNeedsLayout();
254 283
255 m_webViewImpl->updateMainFrameLayoutSize(); 284 m_webViewImpl->updateMainFrameLayoutSize();
256 } 285 }
257 286
258 DEFINE_TRACE(FullscreenController) {
259 visitor->trace(m_provisionalFullscreenElement);
260 visitor->trace(m_fullscreenFrame);
261 }
262
263 } // namespace blink 287 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698