| 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" |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 156 | 156 |
| 157 // If scripts are not enabled, controls will always be shown. | 157 // If scripts are not enabled, controls will always be shown. |
| 158 m_pageHolder->frame().settings()->setScriptEnabled(true); | 158 m_pageHolder->frame().settings()->setScriptEnabled(true); |
| 159 } | 159 } |
| 160 | 160 |
| 161 void simulateRouteAvailabe() { | 161 void simulateRouteAvailabe() { |
| 162 m_mediaControls->mediaElement().remoteRouteAvailabilityChanged( | 162 m_mediaControls->mediaElement().remoteRouteAvailabilityChanged( |
| 163 WebRemotePlaybackAvailability::DeviceAvailable); | 163 WebRemotePlaybackAvailability::DeviceAvailable); |
| 164 } | 164 } |
| 165 | 165 |
| 166 void ensureLayout() { | 166 void ensureSizing() { |
| 167 // Force a relayout, so that the controls know the width. Otherwise, | 167 // Fire the size-change callback to ensure that the controls have |
| 168 // they don't know if, for example, the cast button will fit. | 168 // been properly notified of the video size. |
| 169 m_mediaControls->mediaElement().clientWidth(); | 169 m_mediaControls->notifyElementSizeChanged( |
| 170 m_mediaControls->mediaElement().getBoundingClientRect()); |
| 170 } | 171 } |
| 171 | 172 |
| 172 void simulateHideMediaControlsTimerFired() { | 173 void simulateHideMediaControlsTimerFired() { |
| 173 m_mediaControls->hideMediaControlsTimerFired(nullptr); | 174 m_mediaControls->hideMediaControlsTimerFired(nullptr); |
| 174 } | 175 } |
| 175 | 176 |
| 176 void simulateLoadedMetadata() { m_mediaControls->onLoadedMetadata(); } | 177 void simulateLoadedMetadata() { m_mediaControls->onLoadedMetadata(); } |
| 177 | 178 |
| 178 MediaControls& mediaControls() { return *m_mediaControls; } | 179 MediaControls& mediaControls() { return *m_mediaControls; } |
| 179 MockVideoWebMediaPlayer* webMediaPlayer() { | 180 MockVideoWebMediaPlayer* webMediaPlayer() { |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 Document& document = this->document(); | 235 Document& document = this->document(); |
| 235 int oldElementCount = document.styleEngine().styleForElementCount(); | 236 int oldElementCount = document.styleEngine().styleForElementCount(); |
| 236 // Also assert that there are no layouts yet. | 237 // Also assert that there are no layouts yet. |
| 237 ASSERT_EQ(0, oldElementCount); | 238 ASSERT_EQ(0, oldElementCount); |
| 238 mediaControls().reset(); | 239 mediaControls().reset(); |
| 239 int newElementCount = document.styleEngine().styleForElementCount(); | 240 int newElementCount = document.styleEngine().styleForElementCount(); |
| 240 ASSERT_EQ(oldElementCount, newElementCount); | 241 ASSERT_EQ(oldElementCount, newElementCount); |
| 241 } | 242 } |
| 242 | 243 |
| 243 TEST_F(MediaControlsTest, CastButtonRequiresRoute) { | 244 TEST_F(MediaControlsTest, CastButtonRequiresRoute) { |
| 244 ensureLayout(); | 245 ensureSizing(); |
| 245 mediaControls().mediaElement().setBooleanAttribute(HTMLNames::controlsAttr, | 246 mediaControls().mediaElement().setBooleanAttribute(HTMLNames::controlsAttr, |
| 246 true); | 247 true); |
| 247 | 248 |
| 248 Element* castButton = getElementByShadowPseudoId( | 249 Element* castButton = getElementByShadowPseudoId( |
| 249 mediaControls(), "-internal-media-controls-cast-button"); | 250 mediaControls(), "-internal-media-controls-cast-button"); |
| 250 ASSERT_NE(nullptr, castButton); | 251 ASSERT_NE(nullptr, castButton); |
| 251 | 252 |
| 252 ASSERT_FALSE(isElementVisible(*castButton)); | 253 ASSERT_FALSE(isElementVisible(*castButton)); |
| 253 | 254 |
| 254 simulateRouteAvailabe(); | 255 simulateRouteAvailabe(); |
| 255 ASSERT_TRUE(isElementVisible(*castButton)); | 256 ASSERT_TRUE(isElementVisible(*castButton)); |
| 256 } | 257 } |
| 257 | 258 |
| 258 TEST_F(MediaControlsTest, CastButtonDisableRemotePlaybackAttr) { | 259 TEST_F(MediaControlsTest, CastButtonDisableRemotePlaybackAttr) { |
| 259 ensureLayout(); | 260 ensureSizing(); |
| 260 mediaControls().mediaElement().setBooleanAttribute(HTMLNames::controlsAttr, | 261 mediaControls().mediaElement().setBooleanAttribute(HTMLNames::controlsAttr, |
| 261 true); | 262 true); |
| 262 | 263 |
| 263 Element* castButton = getElementByShadowPseudoId( | 264 Element* castButton = getElementByShadowPseudoId( |
| 264 mediaControls(), "-internal-media-controls-cast-button"); | 265 mediaControls(), "-internal-media-controls-cast-button"); |
| 265 ASSERT_NE(nullptr, castButton); | 266 ASSERT_NE(nullptr, castButton); |
| 266 | 267 |
| 267 ASSERT_FALSE(isElementVisible(*castButton)); | 268 ASSERT_FALSE(isElementVisible(*castButton)); |
| 268 simulateRouteAvailabe(); | 269 simulateRouteAvailabe(); |
| 269 ASSERT_TRUE(isElementVisible(*castButton)); | 270 ASSERT_TRUE(isElementVisible(*castButton)); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 mediaControls().show(); | 337 mediaControls().show(); |
| 337 mediaControls().toggleOverflowMenu(); | 338 mediaControls().toggleOverflowMenu(); |
| 338 EXPECT_TRUE(isElementVisible(*overflowList)); | 339 EXPECT_TRUE(isElementVisible(*overflowList)); |
| 339 | 340 |
| 340 simulateHideMediaControlsTimerFired(); | 341 simulateHideMediaControlsTimerFired(); |
| 341 EXPECT_TRUE(isElementVisible(*overflowList)); | 342 EXPECT_TRUE(isElementVisible(*overflowList)); |
| 342 EXPECT_TRUE(isElementVisible(*panel)); | 343 EXPECT_TRUE(isElementVisible(*panel)); |
| 343 } | 344 } |
| 344 | 345 |
| 345 TEST_F(MediaControlsTest, DownloadButtonDisplayed) { | 346 TEST_F(MediaControlsTest, DownloadButtonDisplayed) { |
| 346 ensureLayout(); | 347 ensureSizing(); |
| 347 | 348 |
| 348 Element* downloadButton = getElementByShadowPseudoId( | 349 Element* downloadButton = getElementByShadowPseudoId( |
| 349 mediaControls(), "-internal-media-controls-download-button"); | 350 mediaControls(), "-internal-media-controls-download-button"); |
| 350 ASSERT_NE(nullptr, downloadButton); | 351 ASSERT_NE(nullptr, downloadButton); |
| 351 | 352 |
| 352 mediaControls().mediaElement().setSrc("https://example.com/foo.mp4"); | 353 mediaControls().mediaElement().setSrc("https://example.com/foo.mp4"); |
| 353 testing::runPendingTasks(); | 354 testing::runPendingTasks(); |
| 354 simulateLoadedMetadata(); | 355 simulateLoadedMetadata(); |
| 355 | 356 |
| 356 // Download button should normally be displayed. | 357 // Download button should normally be displayed. |
| 357 EXPECT_TRUE(isElementVisible(*downloadButton)); | 358 EXPECT_TRUE(isElementVisible(*downloadButton)); |
| 358 } | 359 } |
| 359 | 360 |
| 360 TEST_F(MediaControlsTest, DownloadButtonNotDisplayedEmptyUrl) { | 361 TEST_F(MediaControlsTest, DownloadButtonNotDisplayedEmptyUrl) { |
| 361 ensureLayout(); | 362 ensureSizing(); |
| 362 | 363 |
| 363 Element* downloadButton = getElementByShadowPseudoId( | 364 Element* downloadButton = getElementByShadowPseudoId( |
| 364 mediaControls(), "-internal-media-controls-download-button"); | 365 mediaControls(), "-internal-media-controls-download-button"); |
| 365 ASSERT_NE(nullptr, downloadButton); | 366 ASSERT_NE(nullptr, downloadButton); |
| 366 | 367 |
| 367 // Download button should not be displayed when URL is empty. | 368 // Download button should not be displayed when URL is empty. |
| 368 mediaControls().mediaElement().setSrc(""); | 369 mediaControls().mediaElement().setSrc(""); |
| 369 testing::runPendingTasks(); | 370 testing::runPendingTasks(); |
| 370 simulateLoadedMetadata(); | 371 simulateLoadedMetadata(); |
| 371 EXPECT_FALSE(isElementVisible(*downloadButton)); | 372 EXPECT_FALSE(isElementVisible(*downloadButton)); |
| 372 } | 373 } |
| 373 | 374 |
| 374 TEST_F(MediaControlsTest, DownloadButtonNotDisplayedInfiniteDuration) { | 375 TEST_F(MediaControlsTest, DownloadButtonNotDisplayedInfiniteDuration) { |
| 375 ensureLayout(); | 376 ensureSizing(); |
| 376 | 377 |
| 377 Element* downloadButton = getElementByShadowPseudoId( | 378 Element* downloadButton = getElementByShadowPseudoId( |
| 378 mediaControls(), "-internal-media-controls-download-button"); | 379 mediaControls(), "-internal-media-controls-download-button"); |
| 379 ASSERT_NE(nullptr, downloadButton); | 380 ASSERT_NE(nullptr, downloadButton); |
| 380 | 381 |
| 381 mediaControls().mediaElement().setSrc("https://example.com/foo.mp4"); | 382 mediaControls().mediaElement().setSrc("https://example.com/foo.mp4"); |
| 382 testing::runPendingTasks(); | 383 testing::runPendingTasks(); |
| 383 | 384 |
| 384 // Download button should not be displayed when duration is infinite. | 385 // Download button should not be displayed when duration is infinite. |
| 385 mediaControls().mediaElement().durationChanged( | 386 mediaControls().mediaElement().durationChanged( |
| 386 std::numeric_limits<double>::infinity(), false /* requestSeek */); | 387 std::numeric_limits<double>::infinity(), false /* requestSeek */); |
| 387 simulateLoadedMetadata(); | 388 simulateLoadedMetadata(); |
| 388 EXPECT_FALSE(isElementVisible(*downloadButton)); | 389 EXPECT_FALSE(isElementVisible(*downloadButton)); |
| 389 } | 390 } |
| 390 | 391 |
| 391 TEST_F(MediaControlsTest, DownloadButtonNotDisplayedHLS) { | 392 TEST_F(MediaControlsTest, DownloadButtonNotDisplayedHLS) { |
| 392 ensureLayout(); | 393 ensureSizing(); |
| 393 | 394 |
| 394 Element* downloadButton = getElementByShadowPseudoId( | 395 Element* downloadButton = getElementByShadowPseudoId( |
| 395 mediaControls(), "-internal-media-controls-download-button"); | 396 mediaControls(), "-internal-media-controls-download-button"); |
| 396 ASSERT_NE(nullptr, downloadButton); | 397 ASSERT_NE(nullptr, downloadButton); |
| 397 | 398 |
| 398 // Download button should not be displayed for HLS streams. | 399 // Download button should not be displayed for HLS streams. |
| 399 mediaControls().mediaElement().setSrc("https://example.com/foo.m3u8"); | 400 mediaControls().mediaElement().setSrc("https://example.com/foo.m3u8"); |
| 400 testing::runPendingTasks(); | 401 testing::runPendingTasks(); |
| 401 simulateLoadedMetadata(); | 402 simulateLoadedMetadata(); |
| 402 EXPECT_FALSE(isElementVisible(*downloadButton)); | 403 EXPECT_FALSE(isElementVisible(*downloadButton)); |
| 403 } | 404 } |
| 404 | 405 |
| 405 TEST_F(MediaControlsTest, TimelineSeekToRoundedEnd) { | 406 TEST_F(MediaControlsTest, TimelineSeekToRoundedEnd) { |
| 406 ensureLayout(); | 407 ensureSizing(); |
| 407 | 408 |
| 408 MediaControlTimelineElement* timeline = | 409 MediaControlTimelineElement* timeline = |
| 409 static_cast<MediaControlTimelineElement*>(getElementByShadowPseudoId( | 410 static_cast<MediaControlTimelineElement*>(getElementByShadowPseudoId( |
| 410 mediaControls(), "-webkit-media-controls-timeline")); | 411 mediaControls(), "-webkit-media-controls-timeline")); |
| 411 ASSERT_NE(nullptr, timeline); | 412 ASSERT_NE(nullptr, timeline); |
| 412 | 413 |
| 413 mediaControls().mediaElement().setSrc("https://example.com/foo.mp4"); | 414 mediaControls().mediaElement().setSrc("https://example.com/foo.mp4"); |
| 414 testing::runPendingTasks(); | 415 testing::runPendingTasks(); |
| 415 | 416 |
| 416 // Tests the case where the real length of the video, |exactDuration|, gets | 417 // Tests the case where the real length of the video, |exactDuration|, gets |
| (...skipping 12 matching lines...) Expand all Loading... |
| 429 // underlying <input type="range">. This would set the |value| to the |max| | 430 // underlying <input type="range">. This would set the |value| to the |max| |
| 430 // attribute, which can be slightly rounded relative to the duration. | 431 // attribute, which can be slightly rounded relative to the duration. |
| 431 timeline->setValueAsNumber(roundedUpDuration, ASSERT_NO_EXCEPTION); | 432 timeline->setValueAsNumber(roundedUpDuration, ASSERT_NO_EXCEPTION); |
| 432 ASSERT_EQ(roundedUpDuration, timeline->valueAsNumber()); | 433 ASSERT_EQ(roundedUpDuration, timeline->valueAsNumber()); |
| 433 EXPECT_EQ(0.0, mediaControls().mediaElement().currentTime()); | 434 EXPECT_EQ(0.0, mediaControls().mediaElement().currentTime()); |
| 434 timeline->dispatchInputEvent(); | 435 timeline->dispatchInputEvent(); |
| 435 EXPECT_EQ(exactDuration, mediaControls().mediaElement().currentTime()); | 436 EXPECT_EQ(exactDuration, mediaControls().mediaElement().currentTime()); |
| 436 } | 437 } |
| 437 | 438 |
| 438 } // namespace blink | 439 } // namespace blink |
| OLD | NEW |