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 |