Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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/media_controls/MediaControlsRotateToFullscreenDelegate.h" | 5 #include "modules/media_controls/MediaControlsRotateToFullscreenDelegate.h" |
| 6 | 6 |
| 7 #include "core/HTMLNames.h" | 7 #include "core/HTMLNames.h" |
| 8 #include "core/css/CSSStyleDeclaration.h" | 8 #include "core/css/CSSStyleDeclaration.h" |
| 9 #include "core/dom/Document.h" | 9 #include "core/dom/Document.h" |
| 10 #include "core/dom/DocumentUserGestureToken.h" | 10 #include "core/dom/DocumentUserGestureToken.h" |
| 11 #include "core/dom/Fullscreen.h" | 11 #include "core/dom/Fullscreen.h" |
| 12 #include "core/frame/FrameView.h" | 12 #include "core/frame/FrameView.h" |
| 13 #include "core/frame/LocalDOMWindow.h" | 13 #include "core/frame/LocalDOMWindow.h" |
| 14 #include "core/frame/Settings.h" | 14 #include "core/frame/Settings.h" |
| 15 #include "core/html/HTMLAudioElement.h" | 15 #include "core/html/HTMLAudioElement.h" |
| 16 #include "core/html/HTMLVideoElement.h" | 16 #include "core/html/HTMLVideoElement.h" |
| 17 #include "core/loader/EmptyClients.h" | 17 #include "core/loader/EmptyClients.h" |
| 18 #include "core/testing/DummyPageHolder.h" | 18 #include "core/testing/DummyPageHolder.h" |
| 19 #include "modules/media_controls/MediaControlsImpl.h" | 19 #include "modules/media_controls/MediaControlsImpl.h" |
| 20 #include "modules/screen_orientation/ScreenOrientationControllerImpl.h" | |
| 20 #include "platform/UserGestureIndicator.h" | 21 #include "platform/UserGestureIndicator.h" |
| 21 #include "platform/testing/EmptyWebMediaPlayer.h" | 22 #include "platform/testing/EmptyWebMediaPlayer.h" |
| 22 #include "platform/testing/UnitTestHelpers.h" | 23 #include "platform/testing/UnitTestHelpers.h" |
| 23 #include "platform/wtf/text/AtomicString.h" | 24 #include "platform/wtf/text/AtomicString.h" |
| 24 #include "public/platform/WebSize.h" | 25 #include "public/platform/WebSize.h" |
| 26 #include "public/platform/modules/screen_orientation/WebScreenOrientationClient. h" | |
| 25 #include "public/platform/modules/screen_orientation/WebScreenOrientationType.h" | 27 #include "public/platform/modules/screen_orientation/WebScreenOrientationType.h" |
| 26 #include "testing/gmock/include/gmock/gmock.h" | 28 #include "testing/gmock/include/gmock/gmock.h" |
| 27 #include "testing/gtest/include/gtest/gtest.h" | 29 #include "testing/gtest/include/gtest/gtest.h" |
| 28 | 30 |
| 31 using ::testing::AtLeast; | |
| 29 using ::testing::Return; | 32 using ::testing::Return; |
| 30 | 33 |
| 31 namespace blink { | 34 namespace blink { |
| 32 | 35 |
| 33 using namespace HTMLNames; | 36 using namespace HTMLNames; |
| 34 | 37 |
| 35 namespace { | 38 namespace { |
| 36 | 39 |
| 40 class FakeWebScreenOrientationClient : public WebScreenOrientationClient { | |
| 41 public: | |
| 42 // WebScreenOrientationClient overrides: | |
| 43 void LockOrientation(WebScreenOrientationLockType, | |
| 44 std::unique_ptr<WebLockOrientationCallback>) override {} | |
| 45 void UnlockOrientation() override {} | |
| 46 }; | |
| 47 | |
| 37 class MockVideoWebMediaPlayer : public EmptyWebMediaPlayer { | 48 class MockVideoWebMediaPlayer : public EmptyWebMediaPlayer { |
| 38 public: | 49 public: |
| 39 // ChromeClient overrides: | 50 // ChromeClient overrides: |
| 40 bool HasVideo() const override { return true; } | 51 bool HasVideo() const override { return true; } |
| 41 | 52 |
| 42 MOCK_CONST_METHOD0(NaturalSize, WebSize()); | 53 MOCK_CONST_METHOD0(NaturalSize, WebSize()); |
| 43 }; | 54 }; |
| 44 | 55 |
| 45 class MockChromeClient : public EmptyChromeClient { | 56 class MockChromeClient : public EmptyChromeClient { |
| 46 public: | 57 public: |
| 47 // ChromeClient overrides: | 58 // ChromeClient overrides: |
| 59 void InstallSupplements(LocalFrame& frame) override { | |
| 60 EmptyChromeClient::InstallSupplements(frame); | |
| 61 ScreenOrientationControllerImpl::ProvideTo(frame, | |
| 62 &web_screen_orientation_client); | |
| 63 } | |
| 48 void EnterFullscreen(LocalFrame& frame) override { | 64 void EnterFullscreen(LocalFrame& frame) override { |
| 49 Fullscreen::From(*frame.GetDocument()).DidEnterFullscreen(); | 65 Fullscreen::From(*frame.GetDocument()).DidEnterFullscreen(); |
| 50 } | 66 } |
| 51 void ExitFullscreen(LocalFrame& frame) override { | 67 void ExitFullscreen(LocalFrame& frame) override { |
| 52 Fullscreen::From(*frame.GetDocument()).DidExitFullscreen(); | 68 Fullscreen::From(*frame.GetDocument()).DidExitFullscreen(); |
| 53 } | 69 } |
| 54 | 70 |
| 55 MOCK_CONST_METHOD0(GetScreenInfo, WebScreenInfo()); | 71 MOCK_CONST_METHOD0(GetScreenInfo, WebScreenInfo()); |
| 72 | |
| 73 private: | |
| 74 FakeWebScreenOrientationClient web_screen_orientation_client; | |
|
mlamouri (slow - plz ping)
2017/05/24 17:03:41
style: you are missing a _
johnme
2017/05/24 17:17:42
Done.
| |
| 56 }; | 75 }; |
| 57 | 76 |
| 58 class StubLocalFrameClient : public EmptyLocalFrameClient { | 77 class StubLocalFrameClient : public EmptyLocalFrameClient { |
| 59 public: | 78 public: |
| 60 static StubLocalFrameClient* Create() { return new StubLocalFrameClient; } | 79 static StubLocalFrameClient* Create() { return new StubLocalFrameClient; } |
| 61 | 80 |
| 62 std::unique_ptr<WebMediaPlayer> CreateWebMediaPlayer( | 81 std::unique_ptr<WebMediaPlayer> CreateWebMediaPlayer( |
| 63 HTMLMediaElement&, | 82 HTMLMediaElement&, |
| 64 const WebMediaPlayerSource&, | 83 const WebMediaPlayerSource&, |
| 65 WebMediaPlayerClient*) override { | 84 WebMediaPlayerClient*) override { |
| 66 return WTF::MakeUnique<MockVideoWebMediaPlayer>(); | 85 return WTF::MakeUnique<MockVideoWebMediaPlayer>(); |
| 67 } | 86 } |
| 68 }; | 87 }; |
| 69 | 88 |
| 70 } // anonymous namespace | 89 } // anonymous namespace |
| 71 | 90 |
| 72 class MediaControlsRotateToFullscreenDelegateTest : public ::testing::Test { | 91 class MediaControlsRotateToFullscreenDelegateTest : public ::testing::Test { |
| 73 protected: | 92 protected: |
| 74 using SimpleOrientation = | 93 using SimpleOrientation = |
| 75 MediaControlsRotateToFullscreenDelegate::SimpleOrientation; | 94 MediaControlsRotateToFullscreenDelegate::SimpleOrientation; |
| 76 | 95 |
| 77 void SetUp() override { | 96 void SetUp() override { |
| 78 previous_video_rotate_to_fullscreen_value_ = | 97 previous_video_rotate_to_fullscreen_value_ = |
| 79 RuntimeEnabledFeatures::videoRotateToFullscreenEnabled(); | 98 RuntimeEnabledFeatures::videoRotateToFullscreenEnabled(); |
| 99 previous_video_fullscreen_orientation_lock_value_ = | |
| 100 RuntimeEnabledFeatures::videoFullscreenOrientationLockEnabled(); | |
| 80 RuntimeEnabledFeatures::setVideoRotateToFullscreenEnabled(true); | 101 RuntimeEnabledFeatures::setVideoRotateToFullscreenEnabled(true); |
| 102 RuntimeEnabledFeatures::setVideoFullscreenOrientationLockEnabled(true); | |
| 81 | 103 |
| 82 chrome_client_ = new MockChromeClient(); | 104 chrome_client_ = new MockChromeClient(); |
| 83 | 105 |
| 84 Page::PageClients clients; | 106 Page::PageClients clients; |
| 85 FillWithEmptyClients(clients); | 107 FillWithEmptyClients(clients); |
| 86 clients.chrome_client = chrome_client_.Get(); | 108 clients.chrome_client = chrome_client_.Get(); |
| 87 | 109 |
| 88 page_holder_ = DummyPageHolder::Create(IntSize(800, 600), &clients, | 110 page_holder_ = DummyPageHolder::Create(IntSize(800, 600), &clients, |
| 89 StubLocalFrameClient::Create()); | 111 StubLocalFrameClient::Create()); |
| 90 | 112 |
| 91 video_ = HTMLVideoElement::Create(GetDocument()); | 113 video_ = HTMLVideoElement::Create(GetDocument()); |
| 92 GetVideo().setAttribute(controlsAttr, g_empty_atom); | 114 GetVideo().setAttribute(controlsAttr, g_empty_atom); |
| 93 // Most tests should call GetDocument().body()->AppendChild(&GetVideo()); | 115 // Most tests should call GetDocument().body()->AppendChild(&GetVideo()); |
| 94 // This is not done automatically, so that tests control timing of `Attach`. | 116 // This is not done automatically, so that tests control timing of `Attach`. |
| 95 } | 117 } |
| 96 | 118 |
| 97 void TearDown() override { | 119 void TearDown() override { |
| 98 RuntimeEnabledFeatures::setVideoRotateToFullscreenEnabled( | 120 RuntimeEnabledFeatures::setVideoRotateToFullscreenEnabled( |
| 99 previous_video_rotate_to_fullscreen_value_); | 121 previous_video_rotate_to_fullscreen_value_); |
| 122 RuntimeEnabledFeatures::setVideoFullscreenOrientationLockEnabled( | |
| 123 previous_video_fullscreen_orientation_lock_value_); | |
| 100 } | 124 } |
| 101 | 125 |
| 102 static bool HasDelegate(const MediaControls& media_controls) { | 126 static bool HasDelegate(const MediaControls& media_controls) { |
| 103 return !!static_cast<const MediaControlsImpl*>(&media_controls) | 127 return !!static_cast<const MediaControlsImpl*>(&media_controls) |
| 104 ->rotate_to_fullscreen_delegate_; | 128 ->rotate_to_fullscreen_delegate_; |
| 105 } | 129 } |
| 106 | 130 |
| 107 static bool HasOrientationLockDelegate(const MediaControls& media_controls) { | |
| 108 return !!static_cast<const MediaControlsImpl*>(&media_controls) | |
| 109 ->orientation_lock_delegate_; | |
| 110 } | |
| 111 | |
| 112 void SimulateVideoReadyState(HTMLMediaElement::ReadyState state) { | 131 void SimulateVideoReadyState(HTMLMediaElement::ReadyState state) { |
| 113 GetVideo().SetReadyState(state); | 132 GetVideo().SetReadyState(state); |
| 114 } | 133 } |
| 115 | 134 |
| 116 SimpleOrientation ObservedScreenOrientation() const { | 135 SimpleOrientation ObservedScreenOrientation() const { |
| 117 return GetMediaControls() | 136 return GetMediaControls() |
| 118 .rotate_to_fullscreen_delegate_->current_screen_orientation_; | 137 .rotate_to_fullscreen_delegate_->current_screen_orientation_; |
| 119 } | 138 } |
| 120 | 139 |
| 121 SimpleOrientation ComputeVideoOrientation() const { | 140 SimpleOrientation ComputeVideoOrientation() const { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 163 MediaControlsImpl& GetMediaControls() const { | 182 MediaControlsImpl& GetMediaControls() const { |
| 164 return *static_cast<MediaControlsImpl*>(GetVideo().GetMediaControls()); | 183 return *static_cast<MediaControlsImpl*>(GetVideo().GetMediaControls()); |
| 165 } | 184 } |
| 166 MockVideoWebMediaPlayer& GetWebMediaPlayer() const { | 185 MockVideoWebMediaPlayer& GetWebMediaPlayer() const { |
| 167 return *static_cast<MockVideoWebMediaPlayer*>( | 186 return *static_cast<MockVideoWebMediaPlayer*>( |
| 168 GetVideo().GetWebMediaPlayer()); | 187 GetVideo().GetWebMediaPlayer()); |
| 169 } | 188 } |
| 170 | 189 |
| 171 private: | 190 private: |
| 172 bool previous_video_rotate_to_fullscreen_value_; | 191 bool previous_video_rotate_to_fullscreen_value_; |
| 192 bool previous_video_fullscreen_orientation_lock_value_; | |
| 173 Persistent<MockChromeClient> chrome_client_; | 193 Persistent<MockChromeClient> chrome_client_; |
| 174 std::unique_ptr<DummyPageHolder> page_holder_; | 194 std::unique_ptr<DummyPageHolder> page_holder_; |
| 175 Persistent<HTMLVideoElement> video_; | 195 Persistent<HTMLVideoElement> video_; |
| 176 }; | 196 }; |
| 177 | 197 |
| 178 void MediaControlsRotateToFullscreenDelegateTest::InitScreenAndVideo( | 198 void MediaControlsRotateToFullscreenDelegateTest::InitScreenAndVideo( |
| 179 WebScreenOrientationType initial_screen_orientation, | 199 WebScreenOrientationType initial_screen_orientation, |
| 180 WebSize video_size) { | 200 WebSize video_size) { |
| 181 // Set initial screen orientation (called by `Attach` during `AppendChild`). | 201 // Set initial screen orientation (called by `Attach` during `AppendChild`). |
| 182 WebScreenInfo screen_info; | 202 WebScreenInfo screen_info; |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 203 GetVideo().Play(); | 223 GetVideo().Play(); |
| 204 } | 224 } |
| 205 testing::RunPendingTasks(); | 225 testing::RunPendingTasks(); |
| 206 } | 226 } |
| 207 | 227 |
| 208 void MediaControlsRotateToFullscreenDelegateTest::RotateTo( | 228 void MediaControlsRotateToFullscreenDelegateTest::RotateTo( |
| 209 WebScreenOrientationType new_screen_orientation) { | 229 WebScreenOrientationType new_screen_orientation) { |
| 210 WebScreenInfo screen_info; | 230 WebScreenInfo screen_info; |
| 211 screen_info.orientation_type = new_screen_orientation; | 231 screen_info.orientation_type = new_screen_orientation; |
| 212 EXPECT_CALL(GetChromeClient(), GetScreenInfo()) | 232 EXPECT_CALL(GetChromeClient(), GetScreenInfo()) |
| 213 .Times(1) | 233 .Times(AtLeast(1)) |
| 214 .WillOnce(Return(screen_info)); | 234 .WillRepeatedly(Return(screen_info)); |
| 215 DispatchEvent(GetWindow(), EventTypeNames::orientationchange); | 235 DispatchEvent(GetWindow(), EventTypeNames::orientationchange); |
| 216 testing::RunPendingTasks(); | 236 testing::RunPendingTasks(); |
| 217 } | 237 } |
| 218 | 238 |
| 219 TEST_F(MediaControlsRotateToFullscreenDelegateTest, DelegateRequiresFlag) { | 239 TEST_F(MediaControlsRotateToFullscreenDelegateTest, DelegateRequiresFlag) { |
| 220 // SetUp turns the flag on by default. | 240 // SetUp turns the flag on by default. |
| 221 GetDocument().body()->AppendChild(&GetVideo()); | 241 GetDocument().body()->AppendChild(&GetVideo()); |
| 222 EXPECT_TRUE(HasDelegate(GetMediaControls())); | 242 EXPECT_TRUE(HasDelegate(GetMediaControls())); |
| 223 | 243 |
| 224 // No delegate when flag is off. | 244 // No delegate when flag is off. |
| 225 RuntimeEnabledFeatures::setVideoRotateToFullscreenEnabled(false); | 245 RuntimeEnabledFeatures::setVideoRotateToFullscreenEnabled(false); |
| 226 HTMLVideoElement* video = HTMLVideoElement::Create(GetDocument()); | 246 HTMLVideoElement* video = HTMLVideoElement::Create(GetDocument()); |
| 227 GetDocument().body()->AppendChild(video); | 247 GetDocument().body()->AppendChild(video); |
| 228 EXPECT_FALSE(HasDelegate(*video->GetMediaControls())); | 248 EXPECT_FALSE(HasDelegate(*video->GetMediaControls())); |
| 229 } | 249 } |
| 230 | 250 |
| 231 TEST_F(MediaControlsRotateToFullscreenDelegateTest, DelegateRequiresVideo) { | 251 TEST_F(MediaControlsRotateToFullscreenDelegateTest, DelegateRequiresVideo) { |
| 232 HTMLAudioElement* audio = HTMLAudioElement::Create(GetDocument()); | 252 HTMLAudioElement* audio = HTMLAudioElement::Create(GetDocument()); |
| 233 GetDocument().body()->AppendChild(audio); | 253 GetDocument().body()->AppendChild(audio); |
| 234 EXPECT_FALSE(HasDelegate(*audio->GetMediaControls())); | 254 EXPECT_FALSE(HasDelegate(*audio->GetMediaControls())); |
| 235 } | 255 } |
| 236 | 256 |
| 237 TEST_F(MediaControlsRotateToFullscreenDelegateTest, | |
| 238 OrientationLockIsMutuallyExclusive) { | |
| 239 // Rotate to fullscreen and fullscreen orientation lock are currently | |
| 240 // incompatible, so if both are enabled only one should be active. | |
| 241 RuntimeEnabledFeatures::setVideoRotateToFullscreenEnabled(true); | |
| 242 RuntimeEnabledFeatures::setVideoFullscreenOrientationLockEnabled(true); | |
| 243 HTMLVideoElement* video = HTMLVideoElement::Create(GetDocument()); | |
| 244 GetDocument().body()->AppendChild(video); | |
| 245 EXPECT_TRUE(HasDelegate(*video->GetMediaControls())); | |
| 246 EXPECT_FALSE(HasOrientationLockDelegate(*video->GetMediaControls())); | |
| 247 } | |
| 248 | |
| 249 TEST_F(MediaControlsRotateToFullscreenDelegateTest, ComputeVideoOrientation) { | 257 TEST_F(MediaControlsRotateToFullscreenDelegateTest, ComputeVideoOrientation) { |
| 250 // Set up the WebMediaPlayer instance. | 258 // Set up the WebMediaPlayer instance. |
| 251 GetDocument().body()->AppendChild(&GetVideo()); | 259 GetDocument().body()->AppendChild(&GetVideo()); |
| 252 GetVideo().SetSrc("https://example.com"); | 260 GetVideo().SetSrc("https://example.com"); |
| 253 testing::RunPendingTasks(); | 261 testing::RunPendingTasks(); |
| 254 | 262 |
| 255 // Each `ComputeVideoOrientation` calls `NaturalSize` twice, except the first | 263 // Each `ComputeVideoOrientation` calls `NaturalSize` twice, except the first |
| 256 // one where the video is not yet ready. | 264 // one where the video is not yet ready. |
| 257 EXPECT_CALL(GetWebMediaPlayer(), NaturalSize()) | 265 EXPECT_CALL(GetWebMediaPlayer(), NaturalSize()) |
| 258 .Times(12) | 266 .Times(12) |
| (...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 654 | 662 |
| 655 // Rotate screen to portrait. | 663 // Rotate screen to portrait. |
| 656 RotateTo(kWebScreenOrientationPortraitPrimary); | 664 RotateTo(kWebScreenOrientationPortraitPrimary); |
| 657 | 665 |
| 658 // Should not exit fullscreen, since video was not the fullscreen element. | 666 // Should not exit fullscreen, since video was not the fullscreen element. |
| 659 EXPECT_TRUE(Fullscreen::IsCurrentFullScreenElement(*GetDocument().body())); | 667 EXPECT_TRUE(Fullscreen::IsCurrentFullScreenElement(*GetDocument().body())); |
| 660 EXPECT_FALSE(GetVideo().IsFullscreen()); | 668 EXPECT_FALSE(GetVideo().IsFullscreen()); |
| 661 } | 669 } |
| 662 | 670 |
| 663 } // namespace blink | 671 } // namespace blink |
| OLD | NEW |