OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "modules/screen_orientation/ScreenOrientationControllerImpl.h" | 5 #include "modules/screen_orientation/ScreenOrientationControllerImpl.h" |
6 | 6 |
| 7 #include <memory> |
| 8 #include <utility> |
7 #include "core/dom/Document.h" | 9 #include "core/dom/Document.h" |
8 #include "core/dom/TaskRunnerHelper.h" | 10 #include "core/dom/TaskRunnerHelper.h" |
9 #include "core/events/Event.h" | 11 #include "core/events/Event.h" |
10 #include "core/frame/FrameHost.h" | 12 #include "core/frame/FrameHost.h" |
11 #include "core/frame/FrameView.h" | 13 #include "core/frame/FrameView.h" |
12 #include "core/frame/LocalFrame.h" | 14 #include "core/frame/LocalFrame.h" |
13 #include "core/page/ChromeClient.h" | 15 #include "core/page/ChromeClient.h" |
14 #include "core/page/Page.h" | 16 #include "core/page/Page.h" |
15 #include "modules/screen_orientation/ScreenOrientation.h" | 17 #include "modules/screen_orientation/ScreenOrientation.h" |
16 #include "platform/LayoutTestSupport.h" | 18 #include "platform/LayoutTestSupport.h" |
17 #include "platform/ScopedOrientationChangeIndicator.h" | 19 #include "platform/ScopedOrientationChangeIndicator.h" |
| 20 #include "public/platform/InterfaceProvider.h" |
18 #include "public/platform/WebScreenInfo.h" | 21 #include "public/platform/WebScreenInfo.h" |
19 #include "public/platform/modules/screen_orientation/WebScreenOrientationClient.
h" | 22 #include "wtf/Functional.h" |
20 #include <memory> | |
21 #include <utility> | |
22 | 23 |
23 namespace blink { | 24 namespace blink { |
24 | 25 |
| 26 using device::mojom::blink::ScreenOrientationLockResult; |
| 27 |
25 ScreenOrientationControllerImpl::~ScreenOrientationControllerImpl() = default; | 28 ScreenOrientationControllerImpl::~ScreenOrientationControllerImpl() = default; |
26 | 29 |
27 void ScreenOrientationControllerImpl::provideTo( | 30 void ScreenOrientationControllerImpl::provideTo(LocalFrame& frame) { |
28 LocalFrame& frame, | |
29 WebScreenOrientationClient* client) { | |
30 ScreenOrientationController::provideTo( | 31 ScreenOrientationController::provideTo( |
31 frame, new ScreenOrientationControllerImpl(frame, client)); | 32 frame, new ScreenOrientationControllerImpl(frame)); |
32 } | 33 } |
33 | 34 |
34 ScreenOrientationControllerImpl* ScreenOrientationControllerImpl::from( | 35 ScreenOrientationControllerImpl* ScreenOrientationControllerImpl::from( |
35 LocalFrame& frame) { | 36 LocalFrame& frame) { |
36 return static_cast<ScreenOrientationControllerImpl*>( | 37 return static_cast<ScreenOrientationControllerImpl*>( |
37 ScreenOrientationController::from(frame)); | 38 ScreenOrientationController::from(frame)); |
38 } | 39 } |
39 | 40 |
40 ScreenOrientationControllerImpl::ScreenOrientationControllerImpl( | 41 ScreenOrientationControllerImpl::ScreenOrientationControllerImpl( |
41 LocalFrame& frame, | 42 LocalFrame& frame) |
42 WebScreenOrientationClient* client) | |
43 : ScreenOrientationController(frame), | 43 : ScreenOrientationController(frame), |
44 ContextLifecycleObserver(frame.document()), | 44 ContextLifecycleObserver(frame.document()), |
45 PageVisibilityObserver(frame.page()), | 45 PageVisibilityObserver(frame.page()), |
46 m_client(client), | |
47 m_dispatchEventTimer( | 46 m_dispatchEventTimer( |
48 TaskRunnerHelper::get(TaskType::MiscPlatformAPI, &frame), | 47 TaskRunnerHelper::get(TaskType::MiscPlatformAPI, &frame), |
49 this, | 48 this, |
50 &ScreenOrientationControllerImpl::dispatchEventTimerFired) {} | 49 &ScreenOrientationControllerImpl::dispatchEventTimerFired) { |
| 50 frame.interfaceProvider()->getInterface( |
| 51 mojo::MakeRequest(&m_remoteScreenOrientation)); |
| 52 } |
51 | 53 |
52 // Compute the screen orientation using the orientation angle and the screen | 54 // Compute the screen orientation using the orientation angle and the screen |
53 // width / height. | 55 // width / height. |
54 WebScreenOrientationType ScreenOrientationControllerImpl::computeOrientation( | 56 WebScreenOrientationType ScreenOrientationControllerImpl::computeOrientation( |
55 const IntRect& rect, | 57 const IntRect& rect, |
56 uint16_t rotation) { | 58 uint16_t rotation) { |
57 // Bypass orientation detection in layout tests to get consistent results. | 59 // Bypass orientation detection in layout tests to get consistent results. |
58 // FIXME: The screen dimension should be fixed when running the layout tests | 60 // FIXME: The screen dimension should be fixed when running the layout tests |
59 // to avoid such issues. | 61 // to avoid such issues. |
60 if (LayoutTestSupport::isRunningLayoutTest()) | 62 if (LayoutTestSupport::isRunningLayoutTest()) |
(...skipping 30 matching lines...) Expand all Loading... |
91 if (orientationType == WebScreenOrientationUndefined) { | 93 if (orientationType == WebScreenOrientationUndefined) { |
92 // The embedder could not provide us with an orientation, deduce it | 94 // The embedder could not provide us with an orientation, deduce it |
93 // ourselves. | 95 // ourselves. |
94 orientationType = computeOrientation(chromeClient.screenInfo().rect, | 96 orientationType = computeOrientation(chromeClient.screenInfo().rect, |
95 screenInfo.orientationAngle); | 97 screenInfo.orientationAngle); |
96 } | 98 } |
97 DCHECK(orientationType != WebScreenOrientationUndefined); | 99 DCHECK(orientationType != WebScreenOrientationUndefined); |
98 | 100 |
99 m_orientation->setType(orientationType); | 101 m_orientation->setType(orientationType); |
100 m_orientation->setAngle(screenInfo.orientationAngle); | 102 m_orientation->setAngle(screenInfo.orientationAngle); |
| 103 |
| 104 for (auto iter = m_waitCallbacks.begin(); iter != m_waitCallbacks.end();) { |
| 105 if (lockMatchesCurrentOrientation(iter->second)) { |
| 106 iter->first->onSuccess(); |
| 107 m_waitCallbacks.erase(iter); |
| 108 } else { |
| 109 ++iter; |
| 110 } |
| 111 } |
101 } | 112 } |
102 | 113 |
103 bool ScreenOrientationControllerImpl::isActive() const { | 114 bool ScreenOrientationControllerImpl::isActive() const { |
104 return m_orientation && m_client; | 115 return m_orientation && m_remoteScreenOrientation; |
105 } | 116 } |
106 | 117 |
107 bool ScreenOrientationControllerImpl::isVisible() const { | 118 bool ScreenOrientationControllerImpl::isVisible() const { |
108 return page() && page()->isPageVisible(); | 119 return page() && page()->isPageVisible(); |
109 } | 120 } |
110 | 121 |
111 bool ScreenOrientationControllerImpl::isActiveAndVisible() const { | 122 bool ScreenOrientationControllerImpl::isActiveAndVisible() const { |
112 return isActive() && isVisible(); | 123 return isActive() && isVisible(); |
113 } | 124 } |
114 | 125 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
167 } | 178 } |
168 | 179 |
169 void ScreenOrientationControllerImpl::setOrientation( | 180 void ScreenOrientationControllerImpl::setOrientation( |
170 ScreenOrientation* orientation) { | 181 ScreenOrientation* orientation) { |
171 m_orientation = orientation; | 182 m_orientation = orientation; |
172 if (m_orientation) | 183 if (m_orientation) |
173 updateOrientation(); | 184 updateOrientation(); |
174 notifyAccurateListen(); | 185 notifyAccurateListen(); |
175 } | 186 } |
176 | 187 |
| 188 void ScreenOrientationControllerImpl::onLockOrientationResult( |
| 189 WebLockOrientationCallback* callback, |
| 190 ScreenOrientationLockResult result, |
| 191 WebScreenOrientationLockType lock) { |
| 192 // Lock type natual has been converted to other concrete values in browser |
| 193 // side. |
| 194 DCHECK(lock != WebScreenOrientationLockNatural); |
| 195 // This lock request has already been cancelled by another new lock or unlock |
| 196 // request. |
| 197 if (!m_pendingLockCallback || m_pendingLockCallback.get() != callback) |
| 198 return; |
| 199 |
| 200 switch (result) { |
| 201 case ScreenOrientationLockResult::SCREEN_ORIENTATION_LOCK_RESULT_SUCCESS: |
| 202 if (lockMatchesCurrentOrientation(lock)) { |
| 203 m_pendingLockCallback->onSuccess(); |
| 204 } else { |
| 205 // Wait until next updateOrientation(). |
| 206 m_waitCallbacks.insert( |
| 207 std::make_pair(std::move(m_pendingLockCallback), lock)); |
| 208 } |
| 209 break; |
| 210 case ScreenOrientationLockResult:: |
| 211 SCREEN_ORIENTATION_LOCK_RESULT_ERROR_NOT_AVAILABLE: |
| 212 m_pendingLockCallback->onError( |
| 213 blink::WebLockOrientationErrorNotAvailable); |
| 214 break; |
| 215 case ScreenOrientationLockResult:: |
| 216 SCREEN_ORIENTATION_LOCK_RESULT_ERROR_FULLSCREEN_REQUIRED: |
| 217 m_pendingLockCallback->onError( |
| 218 blink::WebLockOrientationErrorFullscreenRequired); |
| 219 break; |
| 220 case ScreenOrientationLockResult:: |
| 221 SCREEN_ORIENTATION_LOCK_RESULT_ERROR_CANCELED: |
| 222 m_pendingLockCallback->onError(blink::WebLockOrientationErrorCanceled); |
| 223 break; |
| 224 default: |
| 225 NOTREACHED(); |
| 226 break; |
| 227 } |
| 228 m_pendingLockCallback = nullptr; |
| 229 } |
| 230 |
| 231 void ScreenOrientationControllerImpl::cancelPendingLock() { |
| 232 if (!m_pendingLockCallback) |
| 233 return; |
| 234 m_pendingLockCallback->onError(blink::WebLockOrientationErrorCanceled); |
| 235 m_pendingLockCallback = nullptr; |
| 236 } |
| 237 |
| 238 bool ScreenOrientationControllerImpl::lockMatchesCurrentOrientation( |
| 239 WebScreenOrientationLockType lock) { |
| 240 switch (lock) { |
| 241 case WebScreenOrientationLockPortraitPrimary: |
| 242 return m_orientation->getType() == WebScreenOrientationPortraitPrimary; |
| 243 case WebScreenOrientationLockPortraitSecondary: |
| 244 return m_orientation->getType() == WebScreenOrientationPortraitSecondary; |
| 245 case WebScreenOrientationLockLandscapePrimary: |
| 246 return m_orientation->getType() == WebScreenOrientationLandscapePrimary; |
| 247 case WebScreenOrientationLockLandscapeSecondary: |
| 248 return m_orientation->getType() == WebScreenOrientationLandscapeSecondary; |
| 249 case WebScreenOrientationLockLandscape: |
| 250 return m_orientation->getType() == WebScreenOrientationLandscapePrimary || |
| 251 m_orientation->getType() == WebScreenOrientationLandscapeSecondary; |
| 252 case WebScreenOrientationLockPortrait: |
| 253 return m_orientation->getType() == WebScreenOrientationPortraitPrimary || |
| 254 m_orientation->getType() == WebScreenOrientationPortraitSecondary; |
| 255 case WebScreenOrientationLockAny: |
| 256 return true; |
| 257 case WebScreenOrientationLockNatural: |
| 258 case WebScreenOrientationLockDefault: |
| 259 NOTREACHED(); |
| 260 return false; |
| 261 } |
| 262 |
| 263 NOTREACHED(); |
| 264 return false; |
| 265 } |
| 266 |
177 void ScreenOrientationControllerImpl::lock( | 267 void ScreenOrientationControllerImpl::lock( |
178 WebScreenOrientationLockType orientation, | 268 WebScreenOrientationLockType orientation, |
179 std::unique_ptr<WebLockOrientationCallback> callback) { | 269 std::unique_ptr<WebLockOrientationCallback> callback) { |
180 // When detached, the client is no longer valid. | 270 cancelPendingLock(); |
181 if (!m_client) | 271 // When detached, the remote screen orientation is no longer valid. |
| 272 if (!m_remoteScreenOrientation) |
182 return; | 273 return; |
183 m_client->lockOrientation(orientation, std::move(callback)); | 274 m_remoteScreenOrientation->LockOrientation( |
184 m_activeLock = true; | 275 orientation, |
| 276 convertToBaseCallback( |
| 277 WTF::bind(&ScreenOrientationControllerImpl::onLockOrientationResult, |
| 278 wrapPersistent(this), WTF::unretained(callback.get())))); |
| 279 m_pendingLockCallback = std::move(callback); |
185 } | 280 } |
186 | 281 |
187 void ScreenOrientationControllerImpl::unlock() { | 282 void ScreenOrientationControllerImpl::unlock() { |
188 // When detached, the client is no longer valid. | 283 cancelPendingLock(); |
189 if (!m_client) | 284 // When detached, the remote screen orientation is no longer valid. |
| 285 if (!m_remoteScreenOrientation) |
190 return; | 286 return; |
191 m_client->unlockOrientation(); | 287 m_remoteScreenOrientation->UnlockOrientation(); |
192 m_activeLock = false; | |
193 } | 288 } |
194 | 289 |
195 bool ScreenOrientationControllerImpl::maybeHasActiveLock() const { | 290 bool ScreenOrientationControllerImpl::maybeHasActiveLock() const { |
196 return m_activeLock; | 291 return !!m_pendingLockCallback; |
197 } | 292 } |
198 | 293 |
199 void ScreenOrientationControllerImpl::dispatchEventTimerFired(TimerBase*) { | 294 void ScreenOrientationControllerImpl::dispatchEventTimerFired(TimerBase*) { |
200 if (!m_orientation) | 295 if (!m_orientation) |
201 return; | 296 return; |
202 | 297 |
203 ScopedOrientationChangeIndicator orientationChangeIndicator; | 298 ScopedOrientationChangeIndicator orientationChangeIndicator; |
204 m_orientation->dispatchEvent(Event::create(EventTypeNames::change)); | 299 m_orientation->dispatchEvent(Event::create(EventTypeNames::change)); |
205 } | 300 } |
206 | 301 |
207 void ScreenOrientationControllerImpl::contextDestroyed(ExecutionContext*) { | 302 void ScreenOrientationControllerImpl::contextDestroyed(ExecutionContext*) { |
208 if (m_startedAccurateListen) { | 303 if (m_startedAccurateListen) { |
209 m_client->stopAccurateListen(); | 304 m_remoteScreenOrientation->StopAccurateListen(); |
210 m_startedAccurateListen = false; | 305 m_startedAccurateListen = false; |
211 } | 306 } |
212 m_client = nullptr; | 307 m_remoteScreenOrientation = nullptr; |
213 m_activeLock = false; | 308 m_pendingLockCallback = nullptr; |
214 } | 309 } |
215 | 310 |
216 void ScreenOrientationControllerImpl::notifyAccurateListen() { | 311 void ScreenOrientationControllerImpl::notifyAccurateListen() { |
217 if (m_orientation && page()->isPageVisible()) { | 312 if (m_orientation && page()->isPageVisible()) { |
218 // Timing to start accurate listening. | 313 // Timing to start accurate listening. |
219 if (!m_startedAccurateListen) { | 314 if (!m_startedAccurateListen) { |
220 m_client->startAccurateListen(); | 315 m_remoteScreenOrientation->StartAccurateListen(); |
221 m_startedAccurateListen = true; | 316 m_startedAccurateListen = true; |
222 } | 317 } |
223 } else { | 318 } else { |
224 // Timing to stop accurate listening. | 319 // Timing to stop accurate listening. |
225 if (m_startedAccurateListen) { | 320 if (m_startedAccurateListen) { |
226 m_client->stopAccurateListen(); | 321 m_remoteScreenOrientation->StopAccurateListen(); |
227 m_startedAccurateListen = false; | 322 m_startedAccurateListen = false; |
228 } | 323 } |
229 } | 324 } |
230 } | 325 } |
231 | 326 |
232 DEFINE_TRACE(ScreenOrientationControllerImpl) { | 327 DEFINE_TRACE(ScreenOrientationControllerImpl) { |
233 visitor->trace(m_orientation); | 328 visitor->trace(m_orientation); |
234 ContextLifecycleObserver::trace(visitor); | 329 ContextLifecycleObserver::trace(visitor); |
235 Supplement<LocalFrame>::trace(visitor); | 330 Supplement<LocalFrame>::trace(visitor); |
236 PageVisibilityObserver::trace(visitor); | 331 PageVisibilityObserver::trace(visitor); |
237 } | 332 } |
238 | 333 |
239 } // namespace blink | 334 } // namespace blink |
OLD | NEW |