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 "modules/media_controls/MediaControlsImpl.h" | 5 #include "modules/media_controls/MediaControlsImpl.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/ClientRect.h" | 11 #include "core/dom/ClientRect.h" |
12 #include "core/dom/Document.h" | 12 #include "core/dom/Document.h" |
13 #include "core/dom/ElementTraversal.h" | 13 #include "core/dom/ElementTraversal.h" |
14 #include "core/dom/StyleEngine.h" | 14 #include "core/dom/StyleEngine.h" |
15 #include "core/events/Event.h" | 15 #include "core/events/Event.h" |
16 #include "core/frame/Settings.h" | 16 #include "core/frame/Settings.h" |
17 #include "core/html/HTMLElement.h" | 17 #include "core/html/HTMLElement.h" |
18 #include "core/html/HTMLVideoElement.h" | 18 #include "core/html/HTMLVideoElement.h" |
19 #include "core/html/shadow/MediaControlElementTypes.h" | 19 #include "core/html/shadow/MediaControlElementTypes.h" |
20 #include "core/input/EventHandler.h" | 20 #include "core/input/EventHandler.h" |
21 #include "core/layout/LayoutObject.h" | 21 #include "core/layout/LayoutObject.h" |
22 #include "core/loader/EmptyClients.h" | 22 #include "core/loader/EmptyClients.h" |
23 #include "core/testing/DummyPageHolder.h" | 23 #include "core/testing/DummyPageHolder.h" |
24 #include "platform/heap/Handle.h" | 24 #include "platform/heap/Handle.h" |
25 #include "platform/testing/EmptyWebMediaPlayer.h" | 25 #include "platform/testing/EmptyWebMediaPlayer.h" |
26 #include "platform/testing/HistogramTester.h" | 26 #include "platform/testing/HistogramTester.h" |
| 27 #include "platform/testing/TestingPlatformSupport.h" |
27 #include "platform/testing/UnitTestHelpers.h" | 28 #include "platform/testing/UnitTestHelpers.h" |
28 #include "public/platform/WebMouseEvent.h" | 29 #include "public/platform/WebMouseEvent.h" |
29 #include "public/platform/WebScreenInfo.h" | 30 #include "public/platform/WebScreenInfo.h" |
30 #include "public/platform/WebSize.h" | 31 #include "public/platform/WebSize.h" |
31 #include "public/platform/modules/remoteplayback/WebRemotePlaybackAvailability.h
" | 32 #include "public/platform/modules/remoteplayback/WebRemotePlaybackAvailability.h
" |
32 #include "public/platform/modules/remoteplayback/WebRemotePlaybackClient.h" | 33 #include "public/platform/modules/remoteplayback/WebRemotePlaybackClient.h" |
33 #include "testing/gtest/include/gtest/gtest.h" | 34 #include "testing/gtest/include/gtest/gtest.h" |
34 | 35 |
35 namespace blink { | 36 namespace blink { |
36 | 37 |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 enum DownloadActionMetrics { | 154 enum DownloadActionMetrics { |
154 Shown = 0, | 155 Shown = 0, |
155 Clicked, | 156 Clicked, |
156 Count // Keep last. | 157 Count // Keep last. |
157 }; | 158 }; |
158 | 159 |
159 } // namespace | 160 } // namespace |
160 | 161 |
161 class MediaControlsImplTest : public ::testing::Test { | 162 class MediaControlsImplTest : public ::testing::Test { |
162 protected: | 163 protected: |
163 virtual void SetUp() { | 164 virtual void SetUp() { initializePage(); } |
| 165 |
| 166 void initializePage() { |
164 Page::PageClients clients; | 167 Page::PageClients clients; |
165 fillWithEmptyClients(clients); | 168 fillWithEmptyClients(clients); |
166 clients.chromeClient = new MockChromeClient(); | 169 clients.chromeClient = new MockChromeClient(); |
167 m_pageHolder = DummyPageHolder::create(IntSize(800, 600), &clients, | 170 m_pageHolder = DummyPageHolder::create(IntSize(800, 600), &clients, |
168 StubLocalFrameClient::create()); | 171 StubLocalFrameClient::create()); |
169 | 172 |
170 document().write("<video>"); | 173 document().write("<video>"); |
171 HTMLVideoElement& video = | 174 HTMLVideoElement& video = |
172 toHTMLVideoElement(*document().querySelector("video")); | 175 toHTMLVideoElement(*document().querySelector("video")); |
173 m_mediaControls = static_cast<MediaControlsImpl*>(video.mediaControls()); | 176 m_mediaControls = static_cast<MediaControlsImpl*>(video.mediaControls()); |
174 | 177 |
175 // If scripts are not enabled, controls will always be shown. | 178 // If scripts are not enabled, controls will always be shown. |
176 m_pageHolder->frame().settings()->setScriptEnabled(true); | 179 m_pageHolder->frame().settings()->setScriptEnabled(true); |
177 } | 180 } |
178 | 181 |
179 void simulateRouteAvailabe() { | 182 void simulateRouteAvailable() { |
180 m_mediaControls->mediaElement().remoteRouteAvailabilityChanged( | 183 m_mediaControls->mediaElement().remoteRouteAvailabilityChanged( |
181 WebRemotePlaybackAvailability::DeviceAvailable); | 184 WebRemotePlaybackAvailability::DeviceAvailable); |
182 } | 185 } |
183 | 186 |
184 void ensureSizing() { | 187 void ensureSizing() { |
185 // Fire the size-change callback to ensure that the controls have | 188 // Fire the size-change callback to ensure that the controls have |
186 // been properly notified of the video size. | 189 // been properly notified of the video size. |
187 m_mediaControls->notifyElementSizeChanged( | 190 m_mediaControls->notifyElementSizeChanged( |
188 m_mediaControls->mediaElement().getBoundingClientRect()); | 191 m_mediaControls->mediaElement().getBoundingClientRect()); |
189 } | 192 } |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 ensureSizing(); | 317 ensureSizing(); |
315 mediaControls().mediaElement().setBooleanAttribute(HTMLNames::controlsAttr, | 318 mediaControls().mediaElement().setBooleanAttribute(HTMLNames::controlsAttr, |
316 true); | 319 true); |
317 | 320 |
318 Element* castButton = getElementByShadowPseudoId( | 321 Element* castButton = getElementByShadowPseudoId( |
319 mediaControls(), "-internal-media-controls-cast-button"); | 322 mediaControls(), "-internal-media-controls-cast-button"); |
320 ASSERT_NE(nullptr, castButton); | 323 ASSERT_NE(nullptr, castButton); |
321 | 324 |
322 ASSERT_FALSE(isElementVisible(*castButton)); | 325 ASSERT_FALSE(isElementVisible(*castButton)); |
323 | 326 |
324 simulateRouteAvailabe(); | 327 simulateRouteAvailable(); |
325 ASSERT_TRUE(isElementVisible(*castButton)); | 328 ASSERT_TRUE(isElementVisible(*castButton)); |
326 } | 329 } |
327 | 330 |
328 TEST_F(MediaControlsImplTest, CastButtonDisableRemotePlaybackAttr) { | 331 TEST_F(MediaControlsImplTest, CastButtonDisableRemotePlaybackAttr) { |
329 ensureSizing(); | 332 ensureSizing(); |
330 mediaControls().mediaElement().setBooleanAttribute(HTMLNames::controlsAttr, | 333 mediaControls().mediaElement().setBooleanAttribute(HTMLNames::controlsAttr, |
331 true); | 334 true); |
332 | 335 |
333 Element* castButton = getElementByShadowPseudoId( | 336 Element* castButton = getElementByShadowPseudoId( |
334 mediaControls(), "-internal-media-controls-cast-button"); | 337 mediaControls(), "-internal-media-controls-cast-button"); |
335 ASSERT_NE(nullptr, castButton); | 338 ASSERT_NE(nullptr, castButton); |
336 | 339 |
337 ASSERT_FALSE(isElementVisible(*castButton)); | 340 ASSERT_FALSE(isElementVisible(*castButton)); |
338 simulateRouteAvailabe(); | 341 simulateRouteAvailable(); |
339 ASSERT_TRUE(isElementVisible(*castButton)); | 342 ASSERT_TRUE(isElementVisible(*castButton)); |
340 | 343 |
341 mediaControls().mediaElement().setBooleanAttribute( | 344 mediaControls().mediaElement().setBooleanAttribute( |
342 HTMLNames::disableremoteplaybackAttr, true); | 345 HTMLNames::disableremoteplaybackAttr, true); |
343 ASSERT_FALSE(isElementVisible(*castButton)); | 346 ASSERT_FALSE(isElementVisible(*castButton)); |
344 | 347 |
345 mediaControls().mediaElement().setBooleanAttribute( | 348 mediaControls().mediaElement().setBooleanAttribute( |
346 HTMLNames::disableremoteplaybackAttr, false); | 349 HTMLNames::disableremoteplaybackAttr, false); |
347 ASSERT_TRUE(isElementVisible(*castButton)); | 350 ASSERT_TRUE(isElementVisible(*castButton)); |
348 } | 351 } |
349 | 352 |
350 TEST_F(MediaControlsImplTest, CastOverlayDefault) { | 353 TEST_F(MediaControlsImplTest, CastOverlayDefault) { |
351 Element* castOverlayButton = getElementByShadowPseudoId( | 354 Element* castOverlayButton = getElementByShadowPseudoId( |
352 mediaControls(), "-internal-media-controls-overlay-cast-button"); | 355 mediaControls(), "-internal-media-controls-overlay-cast-button"); |
353 ASSERT_NE(nullptr, castOverlayButton); | 356 ASSERT_NE(nullptr, castOverlayButton); |
354 | 357 |
355 simulateRouteAvailabe(); | 358 simulateRouteAvailable(); |
356 ASSERT_TRUE(isElementVisible(*castOverlayButton)); | 359 ASSERT_TRUE(isElementVisible(*castOverlayButton)); |
357 } | 360 } |
358 | 361 |
359 TEST_F(MediaControlsImplTest, CastOverlayDisableRemotePlaybackAttr) { | 362 TEST_F(MediaControlsImplTest, CastOverlayDisableRemotePlaybackAttr) { |
360 Element* castOverlayButton = getElementByShadowPseudoId( | 363 Element* castOverlayButton = getElementByShadowPseudoId( |
361 mediaControls(), "-internal-media-controls-overlay-cast-button"); | 364 mediaControls(), "-internal-media-controls-overlay-cast-button"); |
362 ASSERT_NE(nullptr, castOverlayButton); | 365 ASSERT_NE(nullptr, castOverlayButton); |
363 | 366 |
364 ASSERT_FALSE(isElementVisible(*castOverlayButton)); | 367 ASSERT_FALSE(isElementVisible(*castOverlayButton)); |
365 simulateRouteAvailabe(); | 368 simulateRouteAvailable(); |
366 ASSERT_TRUE(isElementVisible(*castOverlayButton)); | 369 ASSERT_TRUE(isElementVisible(*castOverlayButton)); |
367 | 370 |
368 mediaControls().mediaElement().setBooleanAttribute( | 371 mediaControls().mediaElement().setBooleanAttribute( |
369 HTMLNames::disableremoteplaybackAttr, true); | 372 HTMLNames::disableremoteplaybackAttr, true); |
370 ASSERT_FALSE(isElementVisible(*castOverlayButton)); | 373 ASSERT_FALSE(isElementVisible(*castOverlayButton)); |
371 | 374 |
372 mediaControls().mediaElement().setBooleanAttribute( | 375 mediaControls().mediaElement().setBooleanAttribute( |
373 HTMLNames::disableremoteplaybackAttr, false); | 376 HTMLNames::disableremoteplaybackAttr, false); |
374 ASSERT_TRUE(isElementVisible(*castOverlayButton)); | 377 ASSERT_TRUE(isElementVisible(*castOverlayButton)); |
375 } | 378 } |
376 | 379 |
377 TEST_F(MediaControlsImplTest, CastOverlayMediaControlsDisabled) { | 380 TEST_F(MediaControlsImplTest, CastOverlayMediaControlsDisabled) { |
378 Element* castOverlayButton = getElementByShadowPseudoId( | 381 Element* castOverlayButton = getElementByShadowPseudoId( |
379 mediaControls(), "-internal-media-controls-overlay-cast-button"); | 382 mediaControls(), "-internal-media-controls-overlay-cast-button"); |
380 ASSERT_NE(nullptr, castOverlayButton); | 383 ASSERT_NE(nullptr, castOverlayButton); |
381 | 384 |
382 EXPECT_FALSE(isElementVisible(*castOverlayButton)); | 385 EXPECT_FALSE(isElementVisible(*castOverlayButton)); |
383 simulateRouteAvailabe(); | 386 simulateRouteAvailable(); |
384 EXPECT_TRUE(isElementVisible(*castOverlayButton)); | 387 EXPECT_TRUE(isElementVisible(*castOverlayButton)); |
385 | 388 |
386 document().settings()->setMediaControlsEnabled(false); | 389 document().settings()->setMediaControlsEnabled(false); |
387 EXPECT_FALSE(isElementVisible(*castOverlayButton)); | 390 EXPECT_FALSE(isElementVisible(*castOverlayButton)); |
388 | 391 |
389 document().settings()->setMediaControlsEnabled(true); | 392 document().settings()->setMediaControlsEnabled(true); |
390 EXPECT_TRUE(isElementVisible(*castOverlayButton)); | 393 EXPECT_TRUE(isElementVisible(*castOverlayButton)); |
391 } | 394 } |
392 | 395 |
393 TEST_F(MediaControlsImplTest, KeepControlsVisibleIfOverflowListVisible) { | 396 TEST_F(MediaControlsImplTest, KeepControlsVisibleIfOverflowListVisible) { |
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
786 histogramTester().expectTotalCount( | 789 histogramTester().expectTotalCount( |
787 "Media.Timeline.DragGestureDuration.128_255", 1); | 790 "Media.Timeline.DragGestureDuration.128_255", 1); |
788 histogramTester().expectUniqueSample("Media.Timeline.DragPercent.128_255", | 791 histogramTester().expectUniqueSample("Media.Timeline.DragPercent.128_255", |
789 8 /* (-35.0%, -30.0%] */, 1); | 792 8 /* (-35.0%, -30.0%] */, 1); |
790 histogramTester().expectUniqueSample( | 793 histogramTester().expectUniqueSample( |
791 "Media.Timeline.DragSumAbsTimeDelta.128_255", 17 /* [8m, 15m) */, 1); | 794 "Media.Timeline.DragSumAbsTimeDelta.128_255", 17 /* [8m, 15m) */, 1); |
792 histogramTester().expectUniqueSample("Media.Timeline.DragTimeDelta.128_255", | 795 histogramTester().expectUniqueSample("Media.Timeline.DragTimeDelta.128_255", |
793 9 /* (-4m, -2m] */, 1); | 796 9 /* (-4m, -2m] */, 1); |
794 } | 797 } |
795 | 798 |
| 799 TEST_F(MediaControlsImplTest, ControlsRemainVisibleDuringKeyboardInteraction) { |
| 800 ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler> |
| 801 m_platform; |
| 802 |
| 803 // DocumentParserTiming has DCHECKS to make sure time > 0.0. |
| 804 m_platform->advanceClockSeconds(1); |
| 805 |
| 806 // Need to reinitialize page since we changed the platform. |
| 807 initializePage(); |
| 808 ensureSizing(); |
| 809 |
| 810 Element* panel = mediaControls().panelElement(); |
| 811 |
| 812 mediaControls().mediaElement().setBooleanAttribute(HTMLNames::controlsAttr, |
| 813 true); |
| 814 mediaControls().mediaElement().setSrc("http://example.com"); |
| 815 mediaControls().mediaElement().play(); |
| 816 |
| 817 // Controls start out visible. |
| 818 EXPECT_TRUE(isElementVisible(*panel)); |
| 819 |
| 820 // Tabbing between controls prevents controls from hiding. |
| 821 m_platform->runForPeriodSeconds(2); |
| 822 mediaControls().dispatchEvent(Event::create("focusin")); |
| 823 m_platform->runForPeriodSeconds(2); |
| 824 EXPECT_TRUE(isElementVisible(*panel)); |
| 825 |
| 826 // Seeking on the timeline or volume bar prevents controls from hiding. |
| 827 mediaControls().dispatchEvent(Event::create("input")); |
| 828 m_platform->runForPeriodSeconds(2); |
| 829 EXPECT_TRUE(isElementVisible(*panel)); |
| 830 |
| 831 // Pressing a key prevents controls from hiding. |
| 832 mediaControls().panelElement()->dispatchEvent(Event::create("keypress")); |
| 833 m_platform->runForPeriodSeconds(2); |
| 834 EXPECT_TRUE(isElementVisible(*panel)); |
| 835 |
| 836 // Once user interaction stops, controls can hide. |
| 837 m_platform->runForPeriodSeconds(2); |
| 838 EXPECT_FALSE(isElementVisible(*panel)); |
| 839 } |
| 840 |
796 } // namespace blink | 841 } // namespace blink |
OLD | NEW |