| 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 "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/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/events/Event.h" | 14 #include "core/events/Event.h" |
| 15 #include "core/frame/Settings.h" | 15 #include "core/frame/Settings.h" |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 | 137 |
| 138 // This must match MediaControlDownloadButtonElement::DownloadActionMetrics. | 138 // This must match MediaControlDownloadButtonElement::DownloadActionMetrics. |
| 139 enum DownloadActionMetrics { | 139 enum DownloadActionMetrics { |
| 140 Shown = 0, | 140 Shown = 0, |
| 141 Clicked, | 141 Clicked, |
| 142 Count // Keep last. | 142 Count // Keep last. |
| 143 }; | 143 }; |
| 144 | 144 |
| 145 } // namespace | 145 } // namespace |
| 146 | 146 |
| 147 class MediaControlsTest : public ::testing::Test { | 147 class MediaControlsImplTest : public ::testing::Test { |
| 148 protected: | 148 protected: |
| 149 virtual void SetUp() { | 149 virtual void SetUp() { |
| 150 m_pageHolder = DummyPageHolder::create(IntSize(800, 600), nullptr, | 150 m_pageHolder = DummyPageHolder::create(IntSize(800, 600), nullptr, |
| 151 StubLocalFrameClient::create()); | 151 StubLocalFrameClient::create()); |
| 152 Document& document = this->document(); | 152 Document& document = this->document(); |
| 153 | 153 |
| 154 document.write("<video>"); | 154 document.write("<video>"); |
| 155 HTMLVideoElement& video = | 155 HTMLVideoElement& video = |
| 156 toHTMLVideoElement(*document.querySelector("video")); | 156 toHTMLVideoElement(*document.querySelector("video")); |
| 157 m_mediaControls = video.mediaControls(); | 157 m_mediaControls = static_cast<MediaControlsImpl*>(video.mediaControls()); |
| 158 | 158 |
| 159 // If scripts are not enabled, controls will always be shown. | 159 // If scripts are not enabled, controls will always be shown. |
| 160 m_pageHolder->frame().settings()->setScriptEnabled(true); | 160 m_pageHolder->frame().settings()->setScriptEnabled(true); |
| 161 } | 161 } |
| 162 | 162 |
| 163 void simulateRouteAvailabe() { | 163 void simulateRouteAvailabe() { |
| 164 m_mediaControls->mediaElement().remoteRouteAvailabilityChanged( | 164 m_mediaControls->mediaElement().remoteRouteAvailabilityChanged( |
| 165 WebRemotePlaybackAvailability::DeviceAvailable); | 165 WebRemotePlaybackAvailability::DeviceAvailable); |
| 166 } | 166 } |
| 167 | 167 |
| 168 void ensureSizing() { | 168 void ensureSizing() { |
| 169 // Fire the size-change callback to ensure that the controls have | 169 // Fire the size-change callback to ensure that the controls have |
| 170 // been properly notified of the video size. | 170 // been properly notified of the video size. |
| 171 m_mediaControls->notifyElementSizeChanged( | 171 m_mediaControls->notifyElementSizeChanged( |
| 172 m_mediaControls->mediaElement().getBoundingClientRect()); | 172 m_mediaControls->mediaElement().getBoundingClientRect()); |
| 173 } | 173 } |
| 174 | 174 |
| 175 void simulateHideMediaControlsTimerFired() { | 175 void simulateHideMediaControlsTimerFired() { |
| 176 m_mediaControls->hideMediaControlsTimerFired(nullptr); | 176 m_mediaControls->hideMediaControlsTimerFired(nullptr); |
| 177 } | 177 } |
| 178 | 178 |
| 179 void simulateLoadedMetadata() { m_mediaControls->onLoadedMetadata(); } | 179 void simulateLoadedMetadata() { m_mediaControls->onLoadedMetadata(); } |
| 180 | 180 |
| 181 MediaControls& mediaControls() { return *m_mediaControls; } | 181 MediaControlsImpl& mediaControls() { return *m_mediaControls; } |
| 182 MockVideoWebMediaPlayer* webMediaPlayer() { | 182 MockVideoWebMediaPlayer* webMediaPlayer() { |
| 183 return static_cast<MockVideoWebMediaPlayer*>( | 183 return static_cast<MockVideoWebMediaPlayer*>( |
| 184 mediaControls().mediaElement().webMediaPlayer()); | 184 mediaControls().mediaElement().webMediaPlayer()); |
| 185 } | 185 } |
| 186 Document& document() { return m_pageHolder->document(); } | 186 Document& document() { return m_pageHolder->document(); } |
| 187 | 187 |
| 188 HistogramTester& histogramTester() { return m_histogramTester; } | 188 HistogramTester& histogramTester() { return m_histogramTester; } |
| 189 | 189 |
| 190 void loadMediaWithDuration(double duration) { | 190 void loadMediaWithDuration(double duration) { |
| 191 mediaControls().mediaElement().setSrc("https://example.com/foo.mp4"); | 191 mediaControls().mediaElement().setSrc("https://example.com/foo.mp4"); |
| 192 testing::runPendingTasks(); | 192 testing::runPendingTasks(); |
| 193 WebTimeRange timeRange(0.0, duration); | 193 WebTimeRange timeRange(0.0, duration); |
| 194 webMediaPlayer()->m_seekable.assign(&timeRange, 1); | 194 webMediaPlayer()->m_seekable.assign(&timeRange, 1); |
| 195 mediaControls().mediaElement().durationChanged(duration, | 195 mediaControls().mediaElement().durationChanged(duration, |
| 196 false /* requestSeek */); | 196 false /* requestSeek */); |
| 197 simulateLoadedMetadata(); | 197 simulateLoadedMetadata(); |
| 198 } | 198 } |
| 199 | 199 |
| 200 private: | 200 private: |
| 201 std::unique_ptr<DummyPageHolder> m_pageHolder; | 201 std::unique_ptr<DummyPageHolder> m_pageHolder; |
| 202 Persistent<MediaControls> m_mediaControls; | 202 Persistent<MediaControlsImpl> m_mediaControls; |
| 203 HistogramTester m_histogramTester; | 203 HistogramTester m_histogramTester; |
| 204 }; | 204 }; |
| 205 | 205 |
| 206 TEST_F(MediaControlsTest, HideAndShow) { | 206 TEST_F(MediaControlsImplTest, HideAndShow) { |
| 207 mediaControls().mediaElement().setBooleanAttribute(HTMLNames::controlsAttr, | 207 mediaControls().mediaElement().setBooleanAttribute(HTMLNames::controlsAttr, |
| 208 true); | 208 true); |
| 209 | 209 |
| 210 Element* panel = getElementByShadowPseudoId(mediaControls(), | 210 Element* panel = getElementByShadowPseudoId(mediaControls(), |
| 211 "-webkit-media-controls-panel"); | 211 "-webkit-media-controls-panel"); |
| 212 ASSERT_NE(nullptr, panel); | 212 ASSERT_NE(nullptr, panel); |
| 213 | 213 |
| 214 ASSERT_TRUE(isElementVisible(*panel)); | 214 ASSERT_TRUE(isElementVisible(*panel)); |
| 215 mediaControls().hide(); | 215 mediaControls().hide(); |
| 216 ASSERT_FALSE(isElementVisible(*panel)); | 216 ASSERT_FALSE(isElementVisible(*panel)); |
| 217 mediaControls().show(); | 217 mediaControls().show(); |
| 218 ASSERT_TRUE(isElementVisible(*panel)); | 218 ASSERT_TRUE(isElementVisible(*panel)); |
| 219 } | 219 } |
| 220 | 220 |
| 221 TEST_F(MediaControlsTest, Reset) { | 221 TEST_F(MediaControlsImplTest, Reset) { |
| 222 mediaControls().mediaElement().setBooleanAttribute(HTMLNames::controlsAttr, | 222 mediaControls().mediaElement().setBooleanAttribute(HTMLNames::controlsAttr, |
| 223 true); | 223 true); |
| 224 | 224 |
| 225 Element* panel = getElementByShadowPseudoId(mediaControls(), | 225 Element* panel = getElementByShadowPseudoId(mediaControls(), |
| 226 "-webkit-media-controls-panel"); | 226 "-webkit-media-controls-panel"); |
| 227 ASSERT_NE(nullptr, panel); | 227 ASSERT_NE(nullptr, panel); |
| 228 | 228 |
| 229 ASSERT_TRUE(isElementVisible(*panel)); | 229 ASSERT_TRUE(isElementVisible(*panel)); |
| 230 mediaControls().reset(); | 230 mediaControls().reset(); |
| 231 ASSERT_TRUE(isElementVisible(*panel)); | 231 ASSERT_TRUE(isElementVisible(*panel)); |
| 232 } | 232 } |
| 233 | 233 |
| 234 TEST_F(MediaControlsTest, HideAndReset) { | 234 TEST_F(MediaControlsImplTest, HideAndReset) { |
| 235 mediaControls().mediaElement().setBooleanAttribute(HTMLNames::controlsAttr, | 235 mediaControls().mediaElement().setBooleanAttribute(HTMLNames::controlsAttr, |
| 236 true); | 236 true); |
| 237 | 237 |
| 238 Element* panel = getElementByShadowPseudoId(mediaControls(), | 238 Element* panel = getElementByShadowPseudoId(mediaControls(), |
| 239 "-webkit-media-controls-panel"); | 239 "-webkit-media-controls-panel"); |
| 240 ASSERT_NE(nullptr, panel); | 240 ASSERT_NE(nullptr, panel); |
| 241 | 241 |
| 242 ASSERT_TRUE(isElementVisible(*panel)); | 242 ASSERT_TRUE(isElementVisible(*panel)); |
| 243 mediaControls().hide(); | 243 mediaControls().hide(); |
| 244 ASSERT_FALSE(isElementVisible(*panel)); | 244 ASSERT_FALSE(isElementVisible(*panel)); |
| 245 mediaControls().reset(); | 245 mediaControls().reset(); |
| 246 ASSERT_FALSE(isElementVisible(*panel)); | 246 ASSERT_FALSE(isElementVisible(*panel)); |
| 247 } | 247 } |
| 248 | 248 |
| 249 TEST_F(MediaControlsTest, ResetDoesNotTriggerInitialLayout) { | 249 TEST_F(MediaControlsImplTest, ResetDoesNotTriggerInitialLayout) { |
| 250 Document& document = this->document(); | 250 Document& document = this->document(); |
| 251 int oldElementCount = document.styleEngine().styleForElementCount(); | 251 int oldElementCount = document.styleEngine().styleForElementCount(); |
| 252 // Also assert that there are no layouts yet. | 252 // Also assert that there are no layouts yet. |
| 253 ASSERT_EQ(0, oldElementCount); | 253 ASSERT_EQ(0, oldElementCount); |
| 254 mediaControls().reset(); | 254 mediaControls().reset(); |
| 255 int newElementCount = document.styleEngine().styleForElementCount(); | 255 int newElementCount = document.styleEngine().styleForElementCount(); |
| 256 ASSERT_EQ(oldElementCount, newElementCount); | 256 ASSERT_EQ(oldElementCount, newElementCount); |
| 257 } | 257 } |
| 258 | 258 |
| 259 TEST_F(MediaControlsTest, CastButtonRequiresRoute) { | 259 TEST_F(MediaControlsImplTest, CastButtonRequiresRoute) { |
| 260 ensureSizing(); | 260 ensureSizing(); |
| 261 mediaControls().mediaElement().setBooleanAttribute(HTMLNames::controlsAttr, | 261 mediaControls().mediaElement().setBooleanAttribute(HTMLNames::controlsAttr, |
| 262 true); | 262 true); |
| 263 | 263 |
| 264 Element* castButton = getElementByShadowPseudoId( | 264 Element* castButton = getElementByShadowPseudoId( |
| 265 mediaControls(), "-internal-media-controls-cast-button"); | 265 mediaControls(), "-internal-media-controls-cast-button"); |
| 266 ASSERT_NE(nullptr, castButton); | 266 ASSERT_NE(nullptr, castButton); |
| 267 | 267 |
| 268 ASSERT_FALSE(isElementVisible(*castButton)); | 268 ASSERT_FALSE(isElementVisible(*castButton)); |
| 269 | 269 |
| 270 simulateRouteAvailabe(); | 270 simulateRouteAvailabe(); |
| 271 ASSERT_TRUE(isElementVisible(*castButton)); | 271 ASSERT_TRUE(isElementVisible(*castButton)); |
| 272 } | 272 } |
| 273 | 273 |
| 274 TEST_F(MediaControlsTest, CastButtonDisableRemotePlaybackAttr) { | 274 TEST_F(MediaControlsImplTest, CastButtonDisableRemotePlaybackAttr) { |
| 275 ensureSizing(); | 275 ensureSizing(); |
| 276 mediaControls().mediaElement().setBooleanAttribute(HTMLNames::controlsAttr, | 276 mediaControls().mediaElement().setBooleanAttribute(HTMLNames::controlsAttr, |
| 277 true); | 277 true); |
| 278 | 278 |
| 279 Element* castButton = getElementByShadowPseudoId( | 279 Element* castButton = getElementByShadowPseudoId( |
| 280 mediaControls(), "-internal-media-controls-cast-button"); | 280 mediaControls(), "-internal-media-controls-cast-button"); |
| 281 ASSERT_NE(nullptr, castButton); | 281 ASSERT_NE(nullptr, castButton); |
| 282 | 282 |
| 283 ASSERT_FALSE(isElementVisible(*castButton)); | 283 ASSERT_FALSE(isElementVisible(*castButton)); |
| 284 simulateRouteAvailabe(); | 284 simulateRouteAvailabe(); |
| 285 ASSERT_TRUE(isElementVisible(*castButton)); | 285 ASSERT_TRUE(isElementVisible(*castButton)); |
| 286 | 286 |
| 287 mediaControls().mediaElement().setBooleanAttribute( | 287 mediaControls().mediaElement().setBooleanAttribute( |
| 288 HTMLNames::disableremoteplaybackAttr, true); | 288 HTMLNames::disableremoteplaybackAttr, true); |
| 289 ASSERT_FALSE(isElementVisible(*castButton)); | 289 ASSERT_FALSE(isElementVisible(*castButton)); |
| 290 | 290 |
| 291 mediaControls().mediaElement().setBooleanAttribute( | 291 mediaControls().mediaElement().setBooleanAttribute( |
| 292 HTMLNames::disableremoteplaybackAttr, false); | 292 HTMLNames::disableremoteplaybackAttr, false); |
| 293 ASSERT_TRUE(isElementVisible(*castButton)); | 293 ASSERT_TRUE(isElementVisible(*castButton)); |
| 294 } | 294 } |
| 295 | 295 |
| 296 TEST_F(MediaControlsTest, CastOverlayDefault) { | 296 TEST_F(MediaControlsImplTest, CastOverlayDefault) { |
| 297 Element* castOverlayButton = getElementByShadowPseudoId( | 297 Element* castOverlayButton = getElementByShadowPseudoId( |
| 298 mediaControls(), "-internal-media-controls-overlay-cast-button"); | 298 mediaControls(), "-internal-media-controls-overlay-cast-button"); |
| 299 ASSERT_NE(nullptr, castOverlayButton); | 299 ASSERT_NE(nullptr, castOverlayButton); |
| 300 | 300 |
| 301 simulateRouteAvailabe(); | 301 simulateRouteAvailabe(); |
| 302 ASSERT_TRUE(isElementVisible(*castOverlayButton)); | 302 ASSERT_TRUE(isElementVisible(*castOverlayButton)); |
| 303 } | 303 } |
| 304 | 304 |
| 305 TEST_F(MediaControlsTest, CastOverlayDisableRemotePlaybackAttr) { | 305 TEST_F(MediaControlsImplTest, CastOverlayDisableRemotePlaybackAttr) { |
| 306 Element* castOverlayButton = getElementByShadowPseudoId( | 306 Element* castOverlayButton = getElementByShadowPseudoId( |
| 307 mediaControls(), "-internal-media-controls-overlay-cast-button"); | 307 mediaControls(), "-internal-media-controls-overlay-cast-button"); |
| 308 ASSERT_NE(nullptr, castOverlayButton); | 308 ASSERT_NE(nullptr, castOverlayButton); |
| 309 | 309 |
| 310 ASSERT_FALSE(isElementVisible(*castOverlayButton)); | 310 ASSERT_FALSE(isElementVisible(*castOverlayButton)); |
| 311 simulateRouteAvailabe(); | 311 simulateRouteAvailabe(); |
| 312 ASSERT_TRUE(isElementVisible(*castOverlayButton)); | 312 ASSERT_TRUE(isElementVisible(*castOverlayButton)); |
| 313 | 313 |
| 314 mediaControls().mediaElement().setBooleanAttribute( | 314 mediaControls().mediaElement().setBooleanAttribute( |
| 315 HTMLNames::disableremoteplaybackAttr, true); | 315 HTMLNames::disableremoteplaybackAttr, true); |
| 316 ASSERT_FALSE(isElementVisible(*castOverlayButton)); | 316 ASSERT_FALSE(isElementVisible(*castOverlayButton)); |
| 317 | 317 |
| 318 mediaControls().mediaElement().setBooleanAttribute( | 318 mediaControls().mediaElement().setBooleanAttribute( |
| 319 HTMLNames::disableremoteplaybackAttr, false); | 319 HTMLNames::disableremoteplaybackAttr, false); |
| 320 ASSERT_TRUE(isElementVisible(*castOverlayButton)); | 320 ASSERT_TRUE(isElementVisible(*castOverlayButton)); |
| 321 } | 321 } |
| 322 | 322 |
| 323 TEST_F(MediaControlsTest, CastOverlayMediaControlsDisabled) { | 323 TEST_F(MediaControlsImplTest, CastOverlayMediaControlsDisabled) { |
| 324 Element* castOverlayButton = getElementByShadowPseudoId( | 324 Element* castOverlayButton = getElementByShadowPseudoId( |
| 325 mediaControls(), "-internal-media-controls-overlay-cast-button"); | 325 mediaControls(), "-internal-media-controls-overlay-cast-button"); |
| 326 ASSERT_NE(nullptr, castOverlayButton); | 326 ASSERT_NE(nullptr, castOverlayButton); |
| 327 | 327 |
| 328 EXPECT_FALSE(isElementVisible(*castOverlayButton)); | 328 EXPECT_FALSE(isElementVisible(*castOverlayButton)); |
| 329 simulateRouteAvailabe(); | 329 simulateRouteAvailabe(); |
| 330 EXPECT_TRUE(isElementVisible(*castOverlayButton)); | 330 EXPECT_TRUE(isElementVisible(*castOverlayButton)); |
| 331 | 331 |
| 332 document().settings()->setMediaControlsEnabled(false); | 332 document().settings()->setMediaControlsEnabled(false); |
| 333 EXPECT_FALSE(isElementVisible(*castOverlayButton)); | 333 EXPECT_FALSE(isElementVisible(*castOverlayButton)); |
| 334 | 334 |
| 335 document().settings()->setMediaControlsEnabled(true); | 335 document().settings()->setMediaControlsEnabled(true); |
| 336 EXPECT_TRUE(isElementVisible(*castOverlayButton)); | 336 EXPECT_TRUE(isElementVisible(*castOverlayButton)); |
| 337 } | 337 } |
| 338 | 338 |
| 339 TEST_F(MediaControlsTest, KeepControlsVisibleIfOverflowListVisible) { | 339 TEST_F(MediaControlsImplTest, KeepControlsVisibleIfOverflowListVisible) { |
| 340 Element* overflowList = getElementByShadowPseudoId( | 340 Element* overflowList = getElementByShadowPseudoId( |
| 341 mediaControls(), "-internal-media-controls-overflow-menu-list"); | 341 mediaControls(), "-internal-media-controls-overflow-menu-list"); |
| 342 ASSERT_NE(nullptr, overflowList); | 342 ASSERT_NE(nullptr, overflowList); |
| 343 | 343 |
| 344 Element* panel = getElementByShadowPseudoId(mediaControls(), | 344 Element* panel = getElementByShadowPseudoId(mediaControls(), |
| 345 "-webkit-media-controls-panel"); | 345 "-webkit-media-controls-panel"); |
| 346 ASSERT_NE(nullptr, panel); | 346 ASSERT_NE(nullptr, panel); |
| 347 | 347 |
| 348 mediaControls().mediaElement().setSrc("http://example.com"); | 348 mediaControls().mediaElement().setSrc("http://example.com"); |
| 349 mediaControls().mediaElement().play(); | 349 mediaControls().mediaElement().play(); |
| 350 testing::runPendingTasks(); | 350 testing::runPendingTasks(); |
| 351 | 351 |
| 352 mediaControls().show(); | 352 mediaControls().show(); |
| 353 mediaControls().toggleOverflowMenu(); | 353 mediaControls().toggleOverflowMenu(); |
| 354 EXPECT_TRUE(isElementVisible(*overflowList)); | 354 EXPECT_TRUE(isElementVisible(*overflowList)); |
| 355 | 355 |
| 356 simulateHideMediaControlsTimerFired(); | 356 simulateHideMediaControlsTimerFired(); |
| 357 EXPECT_TRUE(isElementVisible(*overflowList)); | 357 EXPECT_TRUE(isElementVisible(*overflowList)); |
| 358 EXPECT_TRUE(isElementVisible(*panel)); | 358 EXPECT_TRUE(isElementVisible(*panel)); |
| 359 } | 359 } |
| 360 | 360 |
| 361 TEST_F(MediaControlsTest, DownloadButtonDisplayed) { | 361 TEST_F(MediaControlsImplTest, DownloadButtonDisplayed) { |
| 362 ensureSizing(); | 362 ensureSizing(); |
| 363 | 363 |
| 364 Element* downloadButton = getElementByShadowPseudoId( | 364 Element* downloadButton = getElementByShadowPseudoId( |
| 365 mediaControls(), "-internal-media-controls-download-button"); | 365 mediaControls(), "-internal-media-controls-download-button"); |
| 366 ASSERT_NE(nullptr, downloadButton); | 366 ASSERT_NE(nullptr, downloadButton); |
| 367 | 367 |
| 368 mediaControls().mediaElement().setSrc("https://example.com/foo.mp4"); | 368 mediaControls().mediaElement().setSrc("https://example.com/foo.mp4"); |
| 369 testing::runPendingTasks(); | 369 testing::runPendingTasks(); |
| 370 simulateLoadedMetadata(); | 370 simulateLoadedMetadata(); |
| 371 | 371 |
| 372 // Download button should normally be displayed. | 372 // Download button should normally be displayed. |
| 373 EXPECT_TRUE(isElementVisible(*downloadButton)); | 373 EXPECT_TRUE(isElementVisible(*downloadButton)); |
| 374 } | 374 } |
| 375 | 375 |
| 376 TEST_F(MediaControlsTest, DownloadButtonNotDisplayedEmptyUrl) { | 376 TEST_F(MediaControlsImplTest, DownloadButtonNotDisplayedEmptyUrl) { |
| 377 ensureSizing(); | 377 ensureSizing(); |
| 378 | 378 |
| 379 Element* downloadButton = getElementByShadowPseudoId( | 379 Element* downloadButton = getElementByShadowPseudoId( |
| 380 mediaControls(), "-internal-media-controls-download-button"); | 380 mediaControls(), "-internal-media-controls-download-button"); |
| 381 ASSERT_NE(nullptr, downloadButton); | 381 ASSERT_NE(nullptr, downloadButton); |
| 382 | 382 |
| 383 // Download button should not be displayed when URL is empty. | 383 // Download button should not be displayed when URL is empty. |
| 384 mediaControls().mediaElement().setSrc(""); | 384 mediaControls().mediaElement().setSrc(""); |
| 385 testing::runPendingTasks(); | 385 testing::runPendingTasks(); |
| 386 simulateLoadedMetadata(); | 386 simulateLoadedMetadata(); |
| 387 EXPECT_FALSE(isElementVisible(*downloadButton)); | 387 EXPECT_FALSE(isElementVisible(*downloadButton)); |
| 388 } | 388 } |
| 389 | 389 |
| 390 TEST_F(MediaControlsTest, DownloadButtonDisplayedHiddenAndDisplayed) { | 390 TEST_F(MediaControlsImplTest, DownloadButtonDisplayedHiddenAndDisplayed) { |
| 391 ensureSizing(); | 391 ensureSizing(); |
| 392 | 392 |
| 393 Element* downloadButton = getElementByShadowPseudoId( | 393 Element* downloadButton = getElementByShadowPseudoId( |
| 394 mediaControls(), "-internal-media-controls-download-button"); | 394 mediaControls(), "-internal-media-controls-download-button"); |
| 395 ASSERT_NE(nullptr, downloadButton); | 395 ASSERT_NE(nullptr, downloadButton); |
| 396 | 396 |
| 397 // Initially show button. | 397 // Initially show button. |
| 398 mediaControls().mediaElement().setSrc("https://example.com/foo.mp4"); | 398 mediaControls().mediaElement().setSrc("https://example.com/foo.mp4"); |
| 399 testing::runPendingTasks(); | 399 testing::runPendingTasks(); |
| 400 simulateLoadedMetadata(); | 400 simulateLoadedMetadata(); |
| 401 EXPECT_TRUE(isElementVisible(*downloadButton)); | 401 EXPECT_TRUE(isElementVisible(*downloadButton)); |
| 402 histogramTester().expectBucketCount("Media.Controls.Download", | 402 histogramTester().expectBucketCount("Media.Controls.Download", |
| 403 DownloadActionMetrics::Shown, 1); | 403 DownloadActionMetrics::Shown, 1); |
| 404 | 404 |
| 405 // Hide button. | 405 // Hide button. |
| 406 mediaControls().mediaElement().setSrc(""); | 406 mediaControls().mediaElement().setSrc(""); |
| 407 testing::runPendingTasks(); | 407 testing::runPendingTasks(); |
| 408 EXPECT_FALSE(isElementVisible(*downloadButton)); | 408 EXPECT_FALSE(isElementVisible(*downloadButton)); |
| 409 histogramTester().expectBucketCount("Media.Controls.Download", | 409 histogramTester().expectBucketCount("Media.Controls.Download", |
| 410 DownloadActionMetrics::Shown, 1); | 410 DownloadActionMetrics::Shown, 1); |
| 411 | 411 |
| 412 // Showing button again should not increment Shown count. | 412 // Showing button again should not increment Shown count. |
| 413 mediaControls().mediaElement().setSrc("https://example.com/foo.mp4"); | 413 mediaControls().mediaElement().setSrc("https://example.com/foo.mp4"); |
| 414 testing::runPendingTasks(); | 414 testing::runPendingTasks(); |
| 415 EXPECT_TRUE(isElementVisible(*downloadButton)); | 415 EXPECT_TRUE(isElementVisible(*downloadButton)); |
| 416 histogramTester().expectBucketCount("Media.Controls.Download", | 416 histogramTester().expectBucketCount("Media.Controls.Download", |
| 417 DownloadActionMetrics::Shown, 1); | 417 DownloadActionMetrics::Shown, 1); |
| 418 } | 418 } |
| 419 | 419 |
| 420 TEST_F(MediaControlsTest, DownloadButtonRecordsClickOnlyOnce) { | 420 TEST_F(MediaControlsImplTest, DownloadButtonRecordsClickOnlyOnce) { |
| 421 ensureSizing(); | 421 ensureSizing(); |
| 422 | 422 |
| 423 MediaControlDownloadButtonElement* downloadButton = | 423 MediaControlDownloadButtonElement* downloadButton = |
| 424 static_cast<MediaControlDownloadButtonElement*>( | 424 static_cast<MediaControlDownloadButtonElement*>( |
| 425 getElementByShadowPseudoId( | 425 getElementByShadowPseudoId( |
| 426 mediaControls(), "-internal-media-controls-download-button")); | 426 mediaControls(), "-internal-media-controls-download-button")); |
| 427 ASSERT_NE(nullptr, downloadButton); | 427 ASSERT_NE(nullptr, downloadButton); |
| 428 | 428 |
| 429 // Initially show button. | 429 // Initially show button. |
| 430 mediaControls().mediaElement().setSrc("https://example.com/foo.mp4"); | 430 mediaControls().mediaElement().setSrc("https://example.com/foo.mp4"); |
| 431 testing::runPendingTasks(); | 431 testing::runPendingTasks(); |
| 432 simulateLoadedMetadata(); | 432 simulateLoadedMetadata(); |
| 433 EXPECT_TRUE(isElementVisible(*downloadButton)); | 433 EXPECT_TRUE(isElementVisible(*downloadButton)); |
| 434 histogramTester().expectBucketCount("Media.Controls.Download", | 434 histogramTester().expectBucketCount("Media.Controls.Download", |
| 435 DownloadActionMetrics::Shown, 1); | 435 DownloadActionMetrics::Shown, 1); |
| 436 | 436 |
| 437 // Click button once. | 437 // Click button once. |
| 438 downloadButton->dispatchSimulatedClick( | 438 downloadButton->dispatchSimulatedClick( |
| 439 Event::createBubble(EventTypeNames::click), SendNoEvents); | 439 Event::createBubble(EventTypeNames::click), SendNoEvents); |
| 440 histogramTester().expectBucketCount("Media.Controls.Download", | 440 histogramTester().expectBucketCount("Media.Controls.Download", |
| 441 DownloadActionMetrics::Clicked, 1); | 441 DownloadActionMetrics::Clicked, 1); |
| 442 | 442 |
| 443 // Clicking button again should not increment Clicked count. | 443 // Clicking button again should not increment Clicked count. |
| 444 downloadButton->dispatchSimulatedClick( | 444 downloadButton->dispatchSimulatedClick( |
| 445 Event::createBubble(EventTypeNames::click), SendNoEvents); | 445 Event::createBubble(EventTypeNames::click), SendNoEvents); |
| 446 histogramTester().expectBucketCount("Media.Controls.Download", | 446 histogramTester().expectBucketCount("Media.Controls.Download", |
| 447 DownloadActionMetrics::Clicked, 1); | 447 DownloadActionMetrics::Clicked, 1); |
| 448 } | 448 } |
| 449 | 449 |
| 450 TEST_F(MediaControlsTest, DownloadButtonNotDisplayedInfiniteDuration) { | 450 TEST_F(MediaControlsImplTest, DownloadButtonNotDisplayedInfiniteDuration) { |
| 451 ensureSizing(); | 451 ensureSizing(); |
| 452 | 452 |
| 453 Element* downloadButton = getElementByShadowPseudoId( | 453 Element* downloadButton = getElementByShadowPseudoId( |
| 454 mediaControls(), "-internal-media-controls-download-button"); | 454 mediaControls(), "-internal-media-controls-download-button"); |
| 455 ASSERT_NE(nullptr, downloadButton); | 455 ASSERT_NE(nullptr, downloadButton); |
| 456 | 456 |
| 457 mediaControls().mediaElement().setSrc("https://example.com/foo.mp4"); | 457 mediaControls().mediaElement().setSrc("https://example.com/foo.mp4"); |
| 458 testing::runPendingTasks(); | 458 testing::runPendingTasks(); |
| 459 | 459 |
| 460 // Download button should not be displayed when duration is infinite. | 460 // Download button should not be displayed when duration is infinite. |
| 461 mediaControls().mediaElement().durationChanged( | 461 mediaControls().mediaElement().durationChanged( |
| 462 std::numeric_limits<double>::infinity(), false /* requestSeek */); | 462 std::numeric_limits<double>::infinity(), false /* requestSeek */); |
| 463 simulateLoadedMetadata(); | 463 simulateLoadedMetadata(); |
| 464 EXPECT_FALSE(isElementVisible(*downloadButton)); | 464 EXPECT_FALSE(isElementVisible(*downloadButton)); |
| 465 } | 465 } |
| 466 | 466 |
| 467 TEST_F(MediaControlsTest, DownloadButtonNotDisplayedHLS) { | 467 TEST_F(MediaControlsImplTest, DownloadButtonNotDisplayedHLS) { |
| 468 ensureSizing(); | 468 ensureSizing(); |
| 469 | 469 |
| 470 Element* downloadButton = getElementByShadowPseudoId( | 470 Element* downloadButton = getElementByShadowPseudoId( |
| 471 mediaControls(), "-internal-media-controls-download-button"); | 471 mediaControls(), "-internal-media-controls-download-button"); |
| 472 ASSERT_NE(nullptr, downloadButton); | 472 ASSERT_NE(nullptr, downloadButton); |
| 473 | 473 |
| 474 // Download button should not be displayed for HLS streams. | 474 // Download button should not be displayed for HLS streams. |
| 475 mediaControls().mediaElement().setSrc("https://example.com/foo.m3u8"); | 475 mediaControls().mediaElement().setSrc("https://example.com/foo.m3u8"); |
| 476 testing::runPendingTasks(); | 476 testing::runPendingTasks(); |
| 477 simulateLoadedMetadata(); | 477 simulateLoadedMetadata(); |
| 478 EXPECT_FALSE(isElementVisible(*downloadButton)); | 478 EXPECT_FALSE(isElementVisible(*downloadButton)); |
| 479 } | 479 } |
| 480 | 480 |
| 481 TEST_F(MediaControlsTest, TimelineSeekToRoundedEnd) { | 481 TEST_F(MediaControlsImplTest, TimelineSeekToRoundedEnd) { |
| 482 ensureSizing(); | 482 ensureSizing(); |
| 483 | 483 |
| 484 MediaControlTimelineElement* timeline = | 484 MediaControlTimelineElement* timeline = |
| 485 static_cast<MediaControlTimelineElement*>(getElementByShadowPseudoId( | 485 static_cast<MediaControlTimelineElement*>(getElementByShadowPseudoId( |
| 486 mediaControls(), "-webkit-media-controls-timeline")); | 486 mediaControls(), "-webkit-media-controls-timeline")); |
| 487 ASSERT_NE(nullptr, timeline); | 487 ASSERT_NE(nullptr, timeline); |
| 488 | 488 |
| 489 // Tests the case where the real length of the video, |exactDuration|, gets | 489 // Tests the case where the real length of the video, |exactDuration|, gets |
| 490 // rounded up slightly to |roundedUpDuration| when setting the timeline's | 490 // rounded up slightly to |roundedUpDuration| when setting the timeline's |
| 491 // |max| attribute (crbug.com/695065). | 491 // |max| attribute (crbug.com/695065). |
| 492 double exactDuration = 596.586667; | 492 double exactDuration = 596.586667; |
| 493 double roundedUpDuration = 596.587; | 493 double roundedUpDuration = 596.587; |
| 494 loadMediaWithDuration(exactDuration); | 494 loadMediaWithDuration(exactDuration); |
| 495 | 495 |
| 496 // Simulate a click slightly past the end of the track of the timeline's | 496 // Simulate a click slightly past the end of the track of the timeline's |
| 497 // underlying <input type="range">. This would set the |value| to the |max| | 497 // underlying <input type="range">. This would set the |value| to the |max| |
| 498 // attribute, which can be slightly rounded relative to the duration. | 498 // attribute, which can be slightly rounded relative to the duration. |
| 499 timeline->setValueAsNumber(roundedUpDuration, ASSERT_NO_EXCEPTION); | 499 timeline->setValueAsNumber(roundedUpDuration, ASSERT_NO_EXCEPTION); |
| 500 ASSERT_EQ(roundedUpDuration, timeline->valueAsNumber()); | 500 ASSERT_EQ(roundedUpDuration, timeline->valueAsNumber()); |
| 501 EXPECT_EQ(0.0, mediaControls().mediaElement().currentTime()); | 501 EXPECT_EQ(0.0, mediaControls().mediaElement().currentTime()); |
| 502 timeline->dispatchInputEvent(); | 502 timeline->dispatchInputEvent(); |
| 503 EXPECT_EQ(exactDuration, mediaControls().mediaElement().currentTime()); | 503 EXPECT_EQ(exactDuration, mediaControls().mediaElement().currentTime()); |
| 504 } | 504 } |
| 505 | 505 |
| 506 TEST_F(MediaControlsTest, TimelineImmediatelyUpdatesCurrentTime) { | 506 TEST_F(MediaControlsImplTest, TimelineImmediatelyUpdatesCurrentTime) { |
| 507 ensureSizing(); | 507 ensureSizing(); |
| 508 | 508 |
| 509 MediaControlTimelineElement* timeline = | 509 MediaControlTimelineElement* timeline = |
| 510 static_cast<MediaControlTimelineElement*>(getElementByShadowPseudoId( | 510 static_cast<MediaControlTimelineElement*>(getElementByShadowPseudoId( |
| 511 mediaControls(), "-webkit-media-controls-timeline")); | 511 mediaControls(), "-webkit-media-controls-timeline")); |
| 512 ASSERT_NE(nullptr, timeline); | 512 ASSERT_NE(nullptr, timeline); |
| 513 MediaControlCurrentTimeDisplayElement* currentTimeDisplay = | 513 MediaControlCurrentTimeDisplayElement* currentTimeDisplay = |
| 514 static_cast<MediaControlCurrentTimeDisplayElement*>( | 514 static_cast<MediaControlCurrentTimeDisplayElement*>( |
| 515 getElementByShadowPseudoId( | 515 getElementByShadowPseudoId( |
| 516 mediaControls(), "-webkit-media-controls-current-time-display")); | 516 mediaControls(), "-webkit-media-controls-current-time-display")); |
| 517 ASSERT_NE(nullptr, currentTimeDisplay); | 517 ASSERT_NE(nullptr, currentTimeDisplay); |
| 518 | 518 |
| 519 double duration = 600; | 519 double duration = 600; |
| 520 loadMediaWithDuration(duration); | 520 loadMediaWithDuration(duration); |
| 521 | 521 |
| 522 // Simulate seeking the underlying range to 50%. Current time display should | 522 // Simulate seeking the underlying range to 50%. Current time display should |
| 523 // update synchronously (rather than waiting for media to finish seeking). | 523 // update synchronously (rather than waiting for media to finish seeking). |
| 524 timeline->setValueAsNumber(duration / 2, ASSERT_NO_EXCEPTION); | 524 timeline->setValueAsNumber(duration / 2, ASSERT_NO_EXCEPTION); |
| 525 timeline->dispatchInputEvent(); | 525 timeline->dispatchInputEvent(); |
| 526 EXPECT_EQ(duration / 2, currentTimeDisplay->currentValue()); | 526 EXPECT_EQ(duration / 2, currentTimeDisplay->currentValue()); |
| 527 } | 527 } |
| 528 | 528 |
| 529 TEST_F(MediaControlsTest, VolumeSliderPaintInvalidationOnInput) { | 529 TEST_F(MediaControlsImplTest, VolumeSliderPaintInvalidationOnInput) { |
| 530 ensureSizing(); | 530 ensureSizing(); |
| 531 | 531 |
| 532 MediaControlVolumeSliderElement* volumeSlider = | 532 MediaControlVolumeSliderElement* volumeSlider = |
| 533 static_cast<MediaControlVolumeSliderElement*>(getElementByShadowPseudoId( | 533 static_cast<MediaControlVolumeSliderElement*>(getElementByShadowPseudoId( |
| 534 mediaControls(), "-webkit-media-controls-volume-slider")); | 534 mediaControls(), "-webkit-media-controls-volume-slider")); |
| 535 ASSERT_NE(nullptr, volumeSlider); | 535 ASSERT_NE(nullptr, volumeSlider); |
| 536 | 536 |
| 537 HTMLElement* element = volumeSlider; | 537 HTMLElement* element = volumeSlider; |
| 538 | 538 |
| 539 MockLayoutObject layoutObject; | 539 MockLayoutObject layoutObject; |
| 540 LayoutObject* prevLayoutObject = volumeSlider->layoutObject(); | 540 LayoutObject* prevLayoutObject = volumeSlider->layoutObject(); |
| 541 volumeSlider->setLayoutObject(&layoutObject); | 541 volumeSlider->setLayoutObject(&layoutObject); |
| 542 | 542 |
| 543 Event* event = Event::create(EventTypeNames::input); | 543 Event* event = Event::create(EventTypeNames::input); |
| 544 element->defaultEventHandler(event); | 544 element->defaultEventHandler(event); |
| 545 EXPECT_EQ(1, layoutObject.fullPaintInvalidationCallCount()); | 545 EXPECT_EQ(1, layoutObject.fullPaintInvalidationCallCount()); |
| 546 | 546 |
| 547 event = Event::create(EventTypeNames::input); | 547 event = Event::create(EventTypeNames::input); |
| 548 element->defaultEventHandler(event); | 548 element->defaultEventHandler(event); |
| 549 EXPECT_EQ(2, layoutObject.fullPaintInvalidationCallCount()); | 549 EXPECT_EQ(2, layoutObject.fullPaintInvalidationCallCount()); |
| 550 | 550 |
| 551 event = Event::create(EventTypeNames::input); | 551 event = Event::create(EventTypeNames::input); |
| 552 element->defaultEventHandler(event); | 552 element->defaultEventHandler(event); |
| 553 EXPECT_EQ(3, layoutObject.fullPaintInvalidationCallCount()); | 553 EXPECT_EQ(3, layoutObject.fullPaintInvalidationCallCount()); |
| 554 | 554 |
| 555 volumeSlider->setLayoutObject(prevLayoutObject); | 555 volumeSlider->setLayoutObject(prevLayoutObject); |
| 556 } | 556 } |
| 557 | 557 |
| 558 } // namespace blink | 558 } // namespace blink |
| OLD | NEW |