| 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 |