Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "core/html/shadow/MediaControls.h" | 5 #include "core/html/shadow/MediaControls.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 #include <memory> | 8 #include <memory> |
| 9 #include "core/HTMLNames.h" | 9 #include "core/HTMLNames.h" |
| 10 #include "core/css/StylePropertySet.h" | 10 #include "core/css/StylePropertySet.h" |
| 11 #include "core/dom/Document.h" | 11 #include "core/dom/Document.h" |
| 12 #include "core/dom/ElementTraversal.h" | 12 #include "core/dom/ElementTraversal.h" |
| 13 #include "core/dom/StyleEngine.h" | 13 #include "core/dom/StyleEngine.h" |
| 14 #include "core/frame/Settings.h" | 14 #include "core/frame/Settings.h" |
| 15 #include "core/html/HTMLVideoElement.h" | 15 #include "core/html/HTMLVideoElement.h" |
| 16 #include "core/html/shadow/MediaControlElementTypes.h" | 16 #include "core/html/shadow/MediaControlElementTypes.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 "platform/heap/Handle.h" | 19 #include "platform/heap/Handle.h" |
| 20 #include "platform/testing/EmptyWebMediaPlayer.h" | 20 #include "platform/testing/EmptyWebMediaPlayer.h" |
| 21 #include "platform/testing/HistogramTester.h" | 21 #include "platform/testing/HistogramTester.h" |
| 22 #include "platform/testing/TestingPlatformSupport.h" | |
| 22 #include "platform/testing/UnitTestHelpers.h" | 23 #include "platform/testing/UnitTestHelpers.h" |
| 23 #include "public/platform/WebSize.h" | 24 #include "public/platform/WebSize.h" |
| 24 #include "public/platform/modules/remoteplayback/WebRemotePlaybackAvailability.h " | 25 #include "public/platform/modules/remoteplayback/WebRemotePlaybackAvailability.h " |
| 25 #include "public/platform/modules/remoteplayback/WebRemotePlaybackClient.h" | 26 #include "public/platform/modules/remoteplayback/WebRemotePlaybackClient.h" |
| 26 #include "testing/gtest/include/gtest/gtest.h" | 27 #include "testing/gtest/include/gtest/gtest.h" |
| 27 | 28 |
| 28 namespace blink { | 29 namespace blink { |
| 29 | 30 |
| 30 namespace { | 31 namespace { |
| 31 | 32 |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 114 enum DownloadActionMetrics { | 115 enum DownloadActionMetrics { |
| 115 Shown = 0, | 116 Shown = 0, |
| 116 Clicked, | 117 Clicked, |
| 117 Count // Keep last. | 118 Count // Keep last. |
| 118 }; | 119 }; |
| 119 | 120 |
| 120 } // namespace | 121 } // namespace |
| 121 | 122 |
| 122 class MediaControlsTest : public ::testing::Test { | 123 class MediaControlsTest : public ::testing::Test { |
| 123 protected: | 124 protected: |
| 124 virtual void SetUp() { | 125 virtual void SetUp() { initializePage(); } |
| 126 | |
| 127 void initializePage() { | |
| 125 m_pageHolder = DummyPageHolder::create(IntSize(800, 600), nullptr, | 128 m_pageHolder = DummyPageHolder::create(IntSize(800, 600), nullptr, |
| 126 StubLocalFrameClient::create()); | 129 StubLocalFrameClient::create()); |
| 127 Document& document = this->document(); | 130 Document& document = this->document(); |
| 128 | 131 |
| 129 document.write("<video>"); | 132 document.write("<video>"); |
| 130 HTMLVideoElement& video = | 133 HTMLVideoElement& video = |
| 131 toHTMLVideoElement(*document.querySelector("video")); | 134 toHTMLVideoElement(*document.querySelector("video")); |
| 132 m_mediaControls = video.mediaControls(); | 135 m_mediaControls = video.mediaControls(); |
| 133 | 136 |
| 134 // If scripts are not enabled, controls will always be shown. | 137 // If scripts are not enabled, controls will always be shown. |
| 135 m_pageHolder->frame().settings()->setScriptEnabled(true); | 138 m_pageHolder->frame().settings()->setScriptEnabled(true); |
| 136 } | 139 } |
| 137 | 140 |
| 138 void simulateRouteAvailabe() { | 141 void simulateRouteAvailable() { |
| 139 m_mediaControls->mediaElement().remoteRouteAvailabilityChanged( | 142 m_mediaControls->mediaElement().remoteRouteAvailabilityChanged( |
| 140 WebRemotePlaybackAvailability::DeviceAvailable); | 143 WebRemotePlaybackAvailability::DeviceAvailable); |
| 141 } | 144 } |
| 142 | 145 |
| 143 void ensureSizing() { | 146 void ensureSizing() { |
| 144 // Fire the size-change callback to ensure that the controls have | 147 // Fire the size-change callback to ensure that the controls have |
| 145 // been properly notified of the video size. | 148 // been properly notified of the video size. |
| 146 m_mediaControls->notifyElementSizeChanged( | 149 m_mediaControls->notifyElementSizeChanged( |
| 147 m_mediaControls->mediaElement().getBoundingClientRect()); | 150 m_mediaControls->mediaElement().getBoundingClientRect()); |
| 148 } | 151 } |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 235 ensureSizing(); | 238 ensureSizing(); |
| 236 mediaControls().mediaElement().setBooleanAttribute(HTMLNames::controlsAttr, | 239 mediaControls().mediaElement().setBooleanAttribute(HTMLNames::controlsAttr, |
| 237 true); | 240 true); |
| 238 | 241 |
| 239 Element* castButton = getElementByShadowPseudoId( | 242 Element* castButton = getElementByShadowPseudoId( |
| 240 mediaControls(), "-internal-media-controls-cast-button"); | 243 mediaControls(), "-internal-media-controls-cast-button"); |
| 241 ASSERT_NE(nullptr, castButton); | 244 ASSERT_NE(nullptr, castButton); |
| 242 | 245 |
| 243 ASSERT_FALSE(isElementVisible(*castButton)); | 246 ASSERT_FALSE(isElementVisible(*castButton)); |
| 244 | 247 |
| 245 simulateRouteAvailabe(); | 248 simulateRouteAvailable(); |
| 246 ASSERT_TRUE(isElementVisible(*castButton)); | 249 ASSERT_TRUE(isElementVisible(*castButton)); |
| 247 } | 250 } |
| 248 | 251 |
| 249 TEST_F(MediaControlsTest, CastButtonDisableRemotePlaybackAttr) { | 252 TEST_F(MediaControlsTest, CastButtonDisableRemotePlaybackAttr) { |
| 250 ensureSizing(); | 253 ensureSizing(); |
| 251 mediaControls().mediaElement().setBooleanAttribute(HTMLNames::controlsAttr, | 254 mediaControls().mediaElement().setBooleanAttribute(HTMLNames::controlsAttr, |
| 252 true); | 255 true); |
| 253 | 256 |
| 254 Element* castButton = getElementByShadowPseudoId( | 257 Element* castButton = getElementByShadowPseudoId( |
| 255 mediaControls(), "-internal-media-controls-cast-button"); | 258 mediaControls(), "-internal-media-controls-cast-button"); |
| 256 ASSERT_NE(nullptr, castButton); | 259 ASSERT_NE(nullptr, castButton); |
| 257 | 260 |
| 258 ASSERT_FALSE(isElementVisible(*castButton)); | 261 ASSERT_FALSE(isElementVisible(*castButton)); |
| 259 simulateRouteAvailabe(); | 262 simulateRouteAvailable(); |
| 260 ASSERT_TRUE(isElementVisible(*castButton)); | 263 ASSERT_TRUE(isElementVisible(*castButton)); |
| 261 | 264 |
| 262 mediaControls().mediaElement().setBooleanAttribute( | 265 mediaControls().mediaElement().setBooleanAttribute( |
| 263 HTMLNames::disableremoteplaybackAttr, true); | 266 HTMLNames::disableremoteplaybackAttr, true); |
| 264 ASSERT_FALSE(isElementVisible(*castButton)); | 267 ASSERT_FALSE(isElementVisible(*castButton)); |
| 265 | 268 |
| 266 mediaControls().mediaElement().setBooleanAttribute( | 269 mediaControls().mediaElement().setBooleanAttribute( |
| 267 HTMLNames::disableremoteplaybackAttr, false); | 270 HTMLNames::disableremoteplaybackAttr, false); |
| 268 ASSERT_TRUE(isElementVisible(*castButton)); | 271 ASSERT_TRUE(isElementVisible(*castButton)); |
| 269 } | 272 } |
| 270 | 273 |
| 271 TEST_F(MediaControlsTest, CastOverlayDefault) { | 274 TEST_F(MediaControlsTest, CastOverlayDefault) { |
| 272 Element* castOverlayButton = getElementByShadowPseudoId( | 275 Element* castOverlayButton = getElementByShadowPseudoId( |
| 273 mediaControls(), "-internal-media-controls-overlay-cast-button"); | 276 mediaControls(), "-internal-media-controls-overlay-cast-button"); |
| 274 ASSERT_NE(nullptr, castOverlayButton); | 277 ASSERT_NE(nullptr, castOverlayButton); |
| 275 | 278 |
| 276 simulateRouteAvailabe(); | 279 simulateRouteAvailable(); |
| 277 ASSERT_TRUE(isElementVisible(*castOverlayButton)); | 280 ASSERT_TRUE(isElementVisible(*castOverlayButton)); |
| 278 } | 281 } |
| 279 | 282 |
| 280 TEST_F(MediaControlsTest, CastOverlayDisableRemotePlaybackAttr) { | 283 TEST_F(MediaControlsTest, CastOverlayDisableRemotePlaybackAttr) { |
| 281 Element* castOverlayButton = getElementByShadowPseudoId( | 284 Element* castOverlayButton = getElementByShadowPseudoId( |
| 282 mediaControls(), "-internal-media-controls-overlay-cast-button"); | 285 mediaControls(), "-internal-media-controls-overlay-cast-button"); |
| 283 ASSERT_NE(nullptr, castOverlayButton); | 286 ASSERT_NE(nullptr, castOverlayButton); |
| 284 | 287 |
| 285 ASSERT_FALSE(isElementVisible(*castOverlayButton)); | 288 ASSERT_FALSE(isElementVisible(*castOverlayButton)); |
| 286 simulateRouteAvailabe(); | 289 simulateRouteAvailable(); |
| 287 ASSERT_TRUE(isElementVisible(*castOverlayButton)); | 290 ASSERT_TRUE(isElementVisible(*castOverlayButton)); |
| 288 | 291 |
| 289 mediaControls().mediaElement().setBooleanAttribute( | 292 mediaControls().mediaElement().setBooleanAttribute( |
| 290 HTMLNames::disableremoteplaybackAttr, true); | 293 HTMLNames::disableremoteplaybackAttr, true); |
| 291 ASSERT_FALSE(isElementVisible(*castOverlayButton)); | 294 ASSERT_FALSE(isElementVisible(*castOverlayButton)); |
| 292 | 295 |
| 293 mediaControls().mediaElement().setBooleanAttribute( | 296 mediaControls().mediaElement().setBooleanAttribute( |
| 294 HTMLNames::disableremoteplaybackAttr, false); | 297 HTMLNames::disableremoteplaybackAttr, false); |
| 295 ASSERT_TRUE(isElementVisible(*castOverlayButton)); | 298 ASSERT_TRUE(isElementVisible(*castOverlayButton)); |
| 296 } | 299 } |
| 297 | 300 |
| 298 TEST_F(MediaControlsTest, CastOverlayMediaControlsDisabled) { | 301 TEST_F(MediaControlsTest, CastOverlayMediaControlsDisabled) { |
| 299 Element* castOverlayButton = getElementByShadowPseudoId( | 302 Element* castOverlayButton = getElementByShadowPseudoId( |
| 300 mediaControls(), "-internal-media-controls-overlay-cast-button"); | 303 mediaControls(), "-internal-media-controls-overlay-cast-button"); |
| 301 ASSERT_NE(nullptr, castOverlayButton); | 304 ASSERT_NE(nullptr, castOverlayButton); |
| 302 | 305 |
| 303 EXPECT_FALSE(isElementVisible(*castOverlayButton)); | 306 EXPECT_FALSE(isElementVisible(*castOverlayButton)); |
| 304 simulateRouteAvailabe(); | 307 simulateRouteAvailable(); |
| 305 EXPECT_TRUE(isElementVisible(*castOverlayButton)); | 308 EXPECT_TRUE(isElementVisible(*castOverlayButton)); |
| 306 | 309 |
| 307 document().settings()->setMediaControlsEnabled(false); | 310 document().settings()->setMediaControlsEnabled(false); |
| 308 EXPECT_FALSE(isElementVisible(*castOverlayButton)); | 311 EXPECT_FALSE(isElementVisible(*castOverlayButton)); |
| 309 | 312 |
| 310 document().settings()->setMediaControlsEnabled(true); | 313 document().settings()->setMediaControlsEnabled(true); |
| 311 EXPECT_TRUE(isElementVisible(*castOverlayButton)); | 314 EXPECT_TRUE(isElementVisible(*castOverlayButton)); |
| 312 } | 315 } |
| 313 | 316 |
| 314 TEST_F(MediaControlsTest, KeepControlsVisibleIfOverflowListVisible) { | 317 TEST_F(MediaControlsTest, KeepControlsVisibleIfOverflowListVisible) { |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 494 double duration = 600; | 497 double duration = 600; |
| 495 loadMediaWithDuration(duration); | 498 loadMediaWithDuration(duration); |
| 496 | 499 |
| 497 // Simulate seeking the underlying range to 50%. Current time display should | 500 // Simulate seeking the underlying range to 50%. Current time display should |
| 498 // update synchronously (rather than waiting for media to finish seeking). | 501 // update synchronously (rather than waiting for media to finish seeking). |
| 499 timeline->setValueAsNumber(duration / 2, ASSERT_NO_EXCEPTION); | 502 timeline->setValueAsNumber(duration / 2, ASSERT_NO_EXCEPTION); |
| 500 timeline->dispatchInputEvent(); | 503 timeline->dispatchInputEvent(); |
| 501 EXPECT_EQ(duration / 2, currentTimeDisplay->currentValue()); | 504 EXPECT_EQ(duration / 2, currentTimeDisplay->currentValue()); |
| 502 } | 505 } |
| 503 | 506 |
| 507 TEST_F(MediaControlsTest, ControlsRemainVisibleDuringKeyboardInteraction) { | |
| 508 ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler> | |
| 509 m_platform; | |
| 510 m_platform->advanceClockSeconds(1); | |
|
johnme
2017/04/06 17:15:28
Can you add a comment explaining why you need to a
steimel
2017/04/07 16:47:16
Done.
| |
| 511 | |
| 512 // Need to reinitialize page since we changed the platform. | |
| 513 initializePage(); | |
| 514 ensureSizing(); | |
| 515 | |
| 516 Element* panel = getElementByShadowPseudoId(mediaControls(), | |
|
johnme
2017/04/06 17:15:28
Nit: you can use mediaControls().panelElement() he
steimel
2017/04/07 16:47:17
Done.
| |
| 517 "-webkit-media-controls-panel"); | |
| 518 ASSERT_NE(nullptr, panel); | |
| 519 | |
| 520 mediaControls().mediaElement().setBooleanAttribute(HTMLNames::controlsAttr, | |
| 521 true); | |
| 522 mediaControls().mediaElement().setSrc("http://example.com"); | |
| 523 mediaControls().mediaElement().play(); | |
| 524 | |
| 525 // Controls start out visible. | |
| 526 EXPECT_TRUE(isElementVisible(*panel)); | |
| 527 | |
| 528 // Tabbing between controls prevents controls from hiding. | |
| 529 m_platform->runForPeriodSeconds(2); | |
| 530 mediaControls().dispatchEvent(Event::create("focusin")); | |
| 531 m_platform->runForPeriodSeconds(2); | |
| 532 EXPECT_TRUE(isElementVisible(*panel)); | |
| 533 | |
| 534 // Seeking on the timeline or volume bar prevents controls from hiding. | |
| 535 mediaControls().dispatchEvent(Event::create("input")); | |
| 536 m_platform->runForPeriodSeconds(2); | |
| 537 EXPECT_TRUE(isElementVisible(*panel)); | |
| 538 | |
| 539 // Pressing a key prevents controls from hiding. | |
| 540 mediaControls().panelElement()->dispatchEvent(Event::create("keypress")); | |
| 541 m_platform->runForPeriodSeconds(2); | |
| 542 EXPECT_TRUE(isElementVisible(*panel)); | |
| 543 | |
| 544 // Once user interaction stops, controls can hide. | |
| 545 m_platform->runForPeriodSeconds(2); | |
| 546 EXPECT_FALSE(isElementVisible(*panel)); | |
| 547 } | |
| 548 | |
| 504 } // namespace blink | 549 } // namespace blink |
| OLD | NEW |