| 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/loader/EmptyClients.h" | 17 #include "core/loader/EmptyClients.h" |
| 17 #include "core/testing/DummyPageHolder.h" | 18 #include "core/testing/DummyPageHolder.h" |
| 18 #include "platform/heap/Handle.h" | 19 #include "platform/heap/Handle.h" |
| 19 #include "platform/testing/UnitTestHelpers.h" | 20 #include "platform/testing/UnitTestHelpers.h" |
| 20 #include "public/platform/WebMediaPlayer.h" | 21 #include "public/platform/WebMediaPlayer.h" |
| 21 #include "public/platform/WebSize.h" | 22 #include "public/platform/WebSize.h" |
| 22 #include "public/platform/modules/remoteplayback/WebRemotePlaybackAvailability.h
" | 23 #include "public/platform/modules/remoteplayback/WebRemotePlaybackAvailability.h
" |
| 23 #include "public/platform/modules/remoteplayback/WebRemotePlaybackClient.h" | 24 #include "public/platform/modules/remoteplayback/WebRemotePlaybackClient.h" |
| 24 #include "testing/gtest/include/gtest/gtest.h" | 25 #include "testing/gtest/include/gtest/gtest.h" |
| 25 | 26 |
| 26 namespace blink { | 27 namespace blink { |
| 27 | 28 |
| 28 namespace { | 29 namespace { |
| 29 | 30 |
| 30 class MockVideoWebMediaPlayer : public WebMediaPlayer { | 31 class MockVideoWebMediaPlayer : public WebMediaPlayer { |
| 31 public: | 32 public: |
| 32 // WebMediaPlayer overrides: | 33 // WebMediaPlayer overrides: |
| 33 void load(LoadType, const WebMediaPlayerSource&, CORSMode) override{}; | 34 void load(LoadType, const WebMediaPlayerSource&, CORSMode) override{}; |
| 34 void play() override{}; | 35 void play() override{}; |
| 35 void pause() override{}; | 36 void pause() override{}; |
| 36 bool supportsSave() const override { return false; }; | 37 bool supportsSave() const override { return false; }; |
| 37 void seek(double seconds) override{}; | 38 void seek(double seconds) override{}; |
| 38 void setRate(double) override{}; | 39 void setRate(double) override{}; |
| 39 void setVolume(double) override{}; | 40 void setVolume(double) override{}; |
| 40 WebTimeRanges buffered() const override { return WebTimeRanges(); }; | 41 WebTimeRanges buffered() const override { return WebTimeRanges(); }; |
| 41 WebTimeRanges seekable() const override { return WebTimeRanges(); }; | 42 WebTimeRanges seekable() const override { return m_seekable; }; |
| 42 void setSinkId(const WebString& sinkId, | 43 void setSinkId(const WebString& sinkId, |
| 43 const WebSecurityOrigin&, | 44 const WebSecurityOrigin&, |
| 44 WebSetSinkIdCallbacks*) override{}; | 45 WebSetSinkIdCallbacks*) override{}; |
| 45 bool hasVideo() const override { return true; }; | 46 bool hasVideo() const override { return true; }; |
| 46 bool hasAudio() const override { return false; }; | 47 bool hasAudio() const override { return false; }; |
| 47 WebSize naturalSize() const override { return WebSize(0, 0); }; | 48 WebSize naturalSize() const override { return WebSize(0, 0); }; |
| 48 bool paused() const override { return false; }; | 49 bool paused() const override { return false; }; |
| 49 bool seeking() const override { return false; }; | 50 bool seeking() const override { return false; }; |
| 50 double duration() const override { return 0.0; }; | 51 double duration() const override { return 0.0; }; |
| 51 double currentTime() const override { return 0.0; }; | 52 double currentTime() const override { return 0.0; }; |
| 52 NetworkState getNetworkState() const override { return NetworkStateEmpty; }; | 53 NetworkState getNetworkState() const override { return NetworkStateEmpty; }; |
| 53 ReadyState getReadyState() const override { return ReadyStateHaveNothing; }; | 54 ReadyState getReadyState() const override { return ReadyStateHaveNothing; }; |
| 54 WebString getErrorMessage() override { return WebString(); }; | 55 WebString getErrorMessage() override { return WebString(); }; |
| 55 bool didLoadingProgress() override { return false; }; | 56 bool didLoadingProgress() override { return false; }; |
| 56 bool hasSingleSecurityOrigin() const override { return true; }; | 57 bool hasSingleSecurityOrigin() const override { return true; }; |
| 57 bool didPassCORSAccessCheck() const override { return true; }; | 58 bool didPassCORSAccessCheck() const override { return true; }; |
| 58 double mediaTimeForTimeValue(double timeValue) const override { | 59 double mediaTimeForTimeValue(double timeValue) const override { |
| 59 return timeValue; | 60 return timeValue; |
| 60 }; | 61 }; |
| 61 unsigned decodedFrameCount() const override { return 0; }; | 62 unsigned decodedFrameCount() const override { return 0; }; |
| 62 unsigned droppedFrameCount() const override { return 0; }; | 63 unsigned droppedFrameCount() const override { return 0; }; |
| 63 size_t audioDecodedByteCount() const override { return 0; }; | 64 size_t audioDecodedByteCount() const override { return 0; }; |
| 64 size_t videoDecodedByteCount() const override { return 0; }; | 65 size_t videoDecodedByteCount() const override { return 0; }; |
| 65 void paint(WebCanvas*, const WebRect&, PaintFlags&) override{}; | 66 void paint(WebCanvas*, const WebRect&, PaintFlags&) override{}; |
| 67 |
| 68 WebTimeRanges m_seekable; |
| 66 }; | 69 }; |
| 67 | 70 |
| 68 class MockWebRemotePlaybackClient : public WebRemotePlaybackClient { | 71 class MockWebRemotePlaybackClient : public WebRemotePlaybackClient { |
| 69 public: | 72 public: |
| 70 void stateChanged(WebRemotePlaybackState) override {} | 73 void stateChanged(WebRemotePlaybackState) override {} |
| 71 void availabilityChanged( | 74 void availabilityChanged( |
| 72 WebRemotePlaybackAvailability availability) override { | 75 WebRemotePlaybackAvailability availability) override { |
| 73 m_availability = availability; | 76 m_availability = availability; |
| 74 } | 77 } |
| 75 void promptCancelled() override {} | 78 void promptCancelled() override {} |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 166 m_mediaControls->mediaElement().clientWidth(); | 169 m_mediaControls->mediaElement().clientWidth(); |
| 167 } | 170 } |
| 168 | 171 |
| 169 void simulateHideMediaControlsTimerFired() { | 172 void simulateHideMediaControlsTimerFired() { |
| 170 m_mediaControls->hideMediaControlsTimerFired(nullptr); | 173 m_mediaControls->hideMediaControlsTimerFired(nullptr); |
| 171 } | 174 } |
| 172 | 175 |
| 173 void simulateLoadedMetadata() { m_mediaControls->onLoadedMetadata(); } | 176 void simulateLoadedMetadata() { m_mediaControls->onLoadedMetadata(); } |
| 174 | 177 |
| 175 MediaControls& mediaControls() { return *m_mediaControls; } | 178 MediaControls& mediaControls() { return *m_mediaControls; } |
| 179 MockVideoWebMediaPlayer* webMediaPlayer() { |
| 180 return static_cast<MockVideoWebMediaPlayer*>( |
| 181 mediaControls().mediaElement().webMediaPlayer()); |
| 182 } |
| 176 Document& document() { return m_pageHolder->document(); } | 183 Document& document() { return m_pageHolder->document(); } |
| 177 | 184 |
| 178 private: | 185 private: |
| 179 std::unique_ptr<DummyPageHolder> m_pageHolder; | 186 std::unique_ptr<DummyPageHolder> m_pageHolder; |
| 180 Persistent<MediaControls> m_mediaControls; | 187 Persistent<MediaControls> m_mediaControls; |
| 181 }; | 188 }; |
| 182 | 189 |
| 183 TEST_F(MediaControlsTest, HideAndShow) { | 190 TEST_F(MediaControlsTest, HideAndShow) { |
| 184 mediaControls().mediaElement().setBooleanAttribute(HTMLNames::controlsAttr, | 191 mediaControls().mediaElement().setBooleanAttribute(HTMLNames::controlsAttr, |
| 185 true); | 192 true); |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 388 mediaControls(), "-internal-media-controls-download-button"); | 395 mediaControls(), "-internal-media-controls-download-button"); |
| 389 ASSERT_NE(nullptr, downloadButton); | 396 ASSERT_NE(nullptr, downloadButton); |
| 390 | 397 |
| 391 // Download button should not be displayed for HLS streams. | 398 // Download button should not be displayed for HLS streams. |
| 392 mediaControls().mediaElement().setSrc("https://example.com/foo.m3u8"); | 399 mediaControls().mediaElement().setSrc("https://example.com/foo.m3u8"); |
| 393 testing::runPendingTasks(); | 400 testing::runPendingTasks(); |
| 394 simulateLoadedMetadata(); | 401 simulateLoadedMetadata(); |
| 395 EXPECT_FALSE(isElementVisible(*downloadButton)); | 402 EXPECT_FALSE(isElementVisible(*downloadButton)); |
| 396 } | 403 } |
| 397 | 404 |
| 405 TEST_F(MediaControlsTest, TimelineSeekToRoundedEnd) { |
| 406 ensureLayout(); |
| 407 |
| 408 MediaControlTimelineElement* timeline = |
| 409 static_cast<MediaControlTimelineElement*>(getElementByShadowPseudoId( |
| 410 mediaControls(), "-webkit-media-controls-timeline")); |
| 411 ASSERT_NE(nullptr, timeline); |
| 412 |
| 413 mediaControls().mediaElement().setSrc("https://example.com/foo.mp4"); |
| 414 testing::runPendingTasks(); |
| 415 |
| 416 // Tests the case where the real length of the video, |exactDuration|, gets |
| 417 // rounded up slightly to |roundedUpDuration| when setting the timeline's |
| 418 // |max| attribute (crbug.com/695065). |
| 419 double exactDuration = 596.586667; |
| 420 double roundedUpDuration = 596.587; |
| 421 |
| 422 WebTimeRange timeRange(0.0, exactDuration); |
| 423 webMediaPlayer()->m_seekable.assign(&timeRange, 1); |
| 424 mediaControls().mediaElement().durationChanged(exactDuration, |
| 425 false /* requestSeek */); |
| 426 simulateLoadedMetadata(); |
| 427 |
| 428 // Simulate a click slightly past the end of the track of the timeline's |
| 429 // underlying <input type="range">. This would set the |value| to the |max| |
| 430 // attribute, which can be slightly rounded relative to the duration. |
| 431 timeline->setValueAsNumber(roundedUpDuration, ASSERT_NO_EXCEPTION); |
| 432 ASSERT_EQ(roundedUpDuration, timeline->valueAsNumber()); |
| 433 EXPECT_EQ(0.0, mediaControls().mediaElement().currentTime()); |
| 434 timeline->dispatchInputEvent(); |
| 435 EXPECT_EQ(exactDuration, mediaControls().mediaElement().currentTime()); |
| 436 } |
| 437 |
| 398 } // namespace blink | 438 } // namespace blink |
| OLD | NEW |