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 |