| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "MediaControlsOrientationLockDelegate.h" |
| 6 |
| 7 #include "core/events/Event.h" |
| 8 #include "core/frame/ScreenOrientationController.h" |
| 9 #include "core/html/HTMLVideoElement.h" |
| 10 #include "core/page/ChromeClient.h" |
| 11 #include "public/platform/WebScreenInfo.h" |
| 12 #include "public/platform/modules/screen_orientation/WebLockOrientationCallback.
h" |
| 13 |
| 14 namespace blink { |
| 15 |
| 16 namespace { |
| 17 |
| 18 // WebLockOrientationCallback implementation that will not react to a success |
| 19 // nor a failure. |
| 20 class DummyScreenOrientationCallback : public WebLockOrientationCallback { |
| 21 public: |
| 22 void onSuccess() override {} |
| 23 void onError(WebLockOrientationError) override {} |
| 24 }; |
| 25 |
| 26 } // anonymous namespace |
| 27 |
| 28 MediaControlsOrientationLockDelegate::MediaControlsOrientationLockDelegate( |
| 29 HTMLVideoElement& video) |
| 30 : EventListener(CPPEventListenerType), m_videoElement(video) { |
| 31 document().addEventListener(EventTypeNames::fullscreenchange, this, true); |
| 32 videoElement().addEventListener(EventTypeNames::webkitfullscreenchange, this, |
| 33 true); |
| 34 videoElement().addEventListener(EventTypeNames::loadedmetadata, this, true); |
| 35 } |
| 36 |
| 37 bool MediaControlsOrientationLockDelegate::operator==( |
| 38 const EventListener& other) const { |
| 39 return this == &other; |
| 40 } |
| 41 |
| 42 void MediaControlsOrientationLockDelegate::maybeLockOrientation() { |
| 43 DCHECK(m_state != State::MaybeLockedFullscreen); |
| 44 |
| 45 if (videoElement().getReadyState() == HTMLMediaElement::kHaveNothing) { |
| 46 m_state = State::PendingMetadata; |
| 47 return; |
| 48 } |
| 49 |
| 50 m_state = State::MaybeLockedFullscreen; |
| 51 |
| 52 if (!document().frame()) |
| 53 return; |
| 54 |
| 55 auto controller = ScreenOrientationController::from(*document().frame()); |
| 56 if (controller->maybeHasActiveLock()) |
| 57 return; |
| 58 |
| 59 controller->lock(computeOrientationLock(), |
| 60 WTF::wrapUnique(new DummyScreenOrientationCallback)); |
| 61 m_shouldUnlockOrientation = true; |
| 62 } |
| 63 |
| 64 void MediaControlsOrientationLockDelegate::maybeUnlockOrientation() { |
| 65 DCHECK(m_state != State::PendingFullscreen); |
| 66 |
| 67 m_state = State::PendingFullscreen; |
| 68 |
| 69 if (!m_shouldUnlockOrientation) |
| 70 return; |
| 71 |
| 72 ScreenOrientationController::from(*document().frame())->unlock(); |
| 73 m_shouldUnlockOrientation = false; |
| 74 } |
| 75 |
| 76 HTMLVideoElement& MediaControlsOrientationLockDelegate::videoElement() const { |
| 77 return *m_videoElement; |
| 78 } |
| 79 |
| 80 Document& MediaControlsOrientationLockDelegate::document() const { |
| 81 return videoElement().document(); |
| 82 } |
| 83 |
| 84 void MediaControlsOrientationLockDelegate::handleEvent( |
| 85 ExecutionContext* executionContext, |
| 86 Event* event) { |
| 87 if (event->type() == EventTypeNames::fullscreenchange || |
| 88 event->type() == EventTypeNames::webkitfullscreenchange) { |
| 89 if (videoElement().isFullscreen()) { |
| 90 if (m_state == State::PendingFullscreen) |
| 91 maybeLockOrientation(); |
| 92 } else { |
| 93 if (m_state != State::PendingFullscreen) |
| 94 maybeUnlockOrientation(); |
| 95 } |
| 96 |
| 97 return; |
| 98 } |
| 99 |
| 100 if (event->type() == EventTypeNames::loadedmetadata) { |
| 101 if (m_state == State::PendingMetadata) |
| 102 maybeLockOrientation(); |
| 103 |
| 104 return; |
| 105 } |
| 106 |
| 107 NOTREACHED(); |
| 108 } |
| 109 |
| 110 WebScreenOrientationLockType |
| 111 MediaControlsOrientationLockDelegate::computeOrientationLock() const { |
| 112 DCHECK(videoElement().getReadyState() != HTMLMediaElement::kHaveNothing); |
| 113 |
| 114 const unsigned width = videoElement().videoWidth(); |
| 115 const unsigned height = videoElement().videoHeight(); |
| 116 |
| 117 if (width > height) |
| 118 return WebScreenOrientationLockLandscape; |
| 119 |
| 120 if (height > width) |
| 121 return WebScreenOrientationLockPortrait; |
| 122 |
| 123 // For square videos, try to lock to the current screen orientation for |
| 124 // consistency. Use WebScreenOrientationLockLandscape as a fallback value. |
| 125 // TODO(mlamouri): we could improve this by having direct access to |
| 126 // `window.screen.orientation.type`. |
| 127 Frame* frame = document().frame(); |
| 128 if (!frame) |
| 129 return WebScreenOrientationLockLandscape; |
| 130 |
| 131 switch (frame->chromeClient().screenInfo().orientationType) { |
| 132 case WebScreenOrientationPortraitPrimary: |
| 133 case WebScreenOrientationPortraitSecondary: |
| 134 return WebScreenOrientationLockPortrait; |
| 135 case WebScreenOrientationLandscapePrimary: |
| 136 case WebScreenOrientationLandscapeSecondary: |
| 137 return WebScreenOrientationLockLandscape; |
| 138 case WebScreenOrientationUndefined: |
| 139 return WebScreenOrientationLockLandscape; |
| 140 } |
| 141 |
| 142 NOTREACHED(); |
| 143 return WebScreenOrientationLockLandscape; |
| 144 } |
| 145 |
| 146 DEFINE_TRACE(MediaControlsOrientationLockDelegate) { |
| 147 EventListener::trace(visitor); |
| 148 visitor->trace(m_videoElement); |
| 149 } |
| 150 |
| 151 } // namespace blink |
| OLD | NEW |