Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved. | 2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 240 // when used with parameters, e.g. "application/octet-stream;codecs=theora", is a type that the user agent knows | 240 // when used with parameters, e.g. "application/octet-stream;codecs=theora", is a type that the user agent knows |
| 241 // it cannot render. | 241 // it cannot render. |
| 242 if (contentMIMEType != "application/octet-stream" || contentTypeCodecs.isEmp ty()) { | 242 if (contentMIMEType != "application/octet-stream" || contentTypeCodecs.isEmp ty()) { |
| 243 WebMimeRegistry::SupportsType supported = Platform::current()->mimeRegis try()->supportsMediaMIMEType(contentMIMEType, contentTypeCodecs, keySystem.lower ()); | 243 WebMimeRegistry::SupportsType supported = Platform::current()->mimeRegis try()->supportsMediaMIMEType(contentMIMEType, contentTypeCodecs, keySystem.lower ()); |
| 244 return supported > WebMimeRegistry::IsNotSupported; | 244 return supported > WebMimeRegistry::IsNotSupported; |
| 245 } | 245 } |
| 246 | 246 |
| 247 return false; | 247 return false; |
| 248 } | 248 } |
| 249 | 249 |
| 250 // These values are used for a histogram. Do not reorder. | 250 void HTMLMediaElement::recordAutoplayMetric(AutoplayMetrics metric) |
| 251 enum AutoplayMetrics { | |
| 252 // Media element with autoplay seen. | |
| 253 AutoplayMediaFound = 0, | |
| 254 // Autoplay enabled and user stopped media play at any point. | |
| 255 AutoplayStopped = 1, | |
| 256 // Autoplay enabled but user bailed out on media play early. | |
| 257 AutoplayBailout = 2, | |
| 258 // Autoplay disabled but user manually started media. | |
| 259 AutoplayManualStart = 3, | |
| 260 // Autoplay was (re)enabled through a user-gesture triggered load() | |
| 261 AutoplayEnabledThroughLoad = 4, | |
| 262 // Autoplay disabled by sandbox flags. | |
| 263 AutoplayDisabledBySandbox = 5, | |
| 264 // This enum value must be last. | |
| 265 NumberOfAutoplayMetrics, | |
| 266 }; | |
| 267 | |
| 268 static void recordAutoplayMetric(AutoplayMetrics metric) | |
| 269 { | 251 { |
| 270 Platform::current()->histogramEnumeration("Blink.MediaElement.Autoplay", met ric, NumberOfAutoplayMetrics); | 252 Platform::current()->histogramEnumeration("Blink.MediaElement.Autoplay", met ric, NumberOfAutoplayMetrics); |
| 271 } | 253 } |
| 272 | 254 |
| 273 WebMimeRegistry::SupportsType HTMLMediaElement::supportsType(const ContentType& contentType, const String& keySystem) | 255 WebMimeRegistry::SupportsType HTMLMediaElement::supportsType(const ContentType& contentType, const String& keySystem) |
| 274 { | 256 { |
| 275 DEFINE_STATIC_LOCAL(const String, codecs, ("codecs")); | 257 DEFINE_STATIC_LOCAL(const String, codecs, ("codecs")); |
| 276 | 258 |
| 277 if (!RuntimeEnabledFeatures::mediaEnabled()) | 259 if (!RuntimeEnabledFeatures::mediaEnabled()) |
| 278 return WebMimeRegistry::IsNotSupported; | 260 return WebMimeRegistry::IsNotSupported; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 348 , m_sentEndEvent(false) | 330 , m_sentEndEvent(false) |
| 349 , m_closedCaptionsVisible(false) | 331 , m_closedCaptionsVisible(false) |
| 350 , m_completelyLoaded(false) | 332 , m_completelyLoaded(false) |
| 351 , m_havePreparedToPlay(false) | 333 , m_havePreparedToPlay(false) |
| 352 , m_tracksAreReady(true) | 334 , m_tracksAreReady(true) |
| 353 , m_haveVisibleTextTrack(false) | 335 , m_haveVisibleTextTrack(false) |
| 354 , m_processingPreferenceChange(false) | 336 , m_processingPreferenceChange(false) |
| 355 , m_remoteRoutesAvailable(false) | 337 , m_remoteRoutesAvailable(false) |
| 356 , m_playingRemotely(false) | 338 , m_playingRemotely(false) |
| 357 , m_isFinalizing(false) | 339 , m_isFinalizing(false) |
| 358 , m_initialPlayWithoutUserGestures(false) | 340 , m_initialPlayWithoutUserGesture(false) |
| 359 , m_autoplayMediaCounted(false) | 341 , m_autoplayMediaCounted(false) |
| 360 , m_inOverlayFullscreenVideo(false) | 342 , m_inOverlayFullscreenVideo(false) |
| 361 , m_audioTracks(AudioTrackList::create(*this)) | 343 , m_audioTracks(AudioTrackList::create(*this)) |
| 362 , m_videoTracks(VideoTrackList::create(*this)) | 344 , m_videoTracks(VideoTrackList::create(*this)) |
| 363 , m_textTracks(nullptr) | 345 , m_textTracks(nullptr) |
| 364 #if ENABLE(WEB_AUDIO) | 346 #if ENABLE(WEB_AUDIO) |
| 365 , m_audioSourceNode(nullptr) | 347 , m_audioSourceNode(nullptr) |
| 366 #endif | 348 #endif |
| 349 , m_autoplayHelper(*this) | |
| 367 { | 350 { |
| 368 #if ENABLE(OILPAN) | 351 #if ENABLE(OILPAN) |
| 369 ThreadState::current()->registerPreFinalizer(this); | 352 ThreadState::current()->registerPreFinalizer(this); |
| 370 #endif | 353 #endif |
| 371 ASSERT(RuntimeEnabledFeatures::mediaEnabled()); | 354 ASSERT(RuntimeEnabledFeatures::mediaEnabled()); |
| 372 | 355 |
| 373 WTF_LOG(Media, "HTMLMediaElement::HTMLMediaElement(%p)", this); | 356 WTF_LOG(Media, "HTMLMediaElement::HTMLMediaElement(%p)", this); |
| 374 | 357 |
| 375 if (document.settings() && document.settings()->mediaPlaybackRequiresUserGes ture()) | 358 if (document.settings() && document.settings()->mediaPlaybackRequiresUserGes ture()) |
| 376 m_userGestureRequiredForPlay = true; | 359 m_userGestureRequiredForPlay = true; |
| 377 | 360 |
| 378 setHasCustomStyleCallbacks(); | 361 setHasCustomStyleCallbacks(); |
| 379 addElementToDocumentMap(this, &document); | 362 addElementToDocumentMap(this, &document); |
| 380 } | 363 } |
| 381 | 364 |
| 382 HTMLMediaElement::~HTMLMediaElement() | 365 HTMLMediaElement::~HTMLMediaElement() |
| 383 { | 366 { |
| 384 WTF_LOG(Media, "HTMLMediaElement::~HTMLMediaElement(%p)", this); | 367 WTF_LOG(Media, "HTMLMediaElement::~HTMLMediaElement(%p)", this); |
| 368 | |
| 385 #if !ENABLE(OILPAN) | 369 #if !ENABLE(OILPAN) |
| 386 // HTMLMediaElement and m_asyncEventQueue always become unreachable | 370 // HTMLMediaElement and m_asyncEventQueue always become unreachable |
| 387 // together. So HTMLMediaElement and m_asyncEventQueue are destructed in | 371 // together. So HTMLMediaElement and m_asyncEventQueue are destructed in |
| 388 // the same GC. We don't need to close it explicitly in Oilpan. | 372 // the same GC. We don't need to close it explicitly in Oilpan. |
| 389 m_asyncEventQueue->close(); | 373 m_asyncEventQueue->close(); |
| 390 | 374 |
| 391 setShouldDelayLoadEvent(false); | 375 setShouldDelayLoadEvent(false); |
| 392 | 376 |
| 393 if (m_textTracks) | 377 if (m_textTracks) |
| 394 m_textTracks->clearOwner(); | 378 m_textTracks->clearOwner(); |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 684 case WebMimeRegistry::IsSupported: | 668 case WebMimeRegistry::IsSupported: |
| 685 canPlay = "probably"; | 669 canPlay = "probably"; |
| 686 break; | 670 break; |
| 687 } | 671 } |
| 688 | 672 |
| 689 WTF_LOG(Media, "HTMLMediaElement::canPlayType(%p, %s, %s) -> %s", this, mime Type.utf8().data(), keySystem.utf8().data(), canPlay.utf8().data()); | 673 WTF_LOG(Media, "HTMLMediaElement::canPlayType(%p, %s, %s) -> %s", this, mime Type.utf8().data(), keySystem.utf8().data(), canPlay.utf8().data()); |
| 690 | 674 |
| 691 return canPlay; | 675 return canPlay; |
| 692 } | 676 } |
| 693 | 677 |
| 678 void HTMLMediaElement::recordMetricsIfPausing() | |
| 679 { | |
| 680 // If not playing, then nothing to record. | |
| 681 // TODO(liberato): test metrics. this was m_paused. | |
| 682 if (m_paused) | |
| 683 return; | |
| 684 | |
| 685 const bool bailout = isBailout(); | |
| 686 | |
| 687 // Record that play was paused. We don't care if it was autoplay, | |
| 688 // play(), or the user manually started it. | |
| 689 recordAutoplayMetric(AnyPlaybackPaused); | |
| 690 if (bailout) | |
| 691 recordAutoplayMetric(AnyPlaybackBailout); | |
| 692 | |
| 693 // If this was a gestureless play, then record that separately. | |
| 694 // These cover attr and play() gestureless starts. | |
| 695 if (m_initialPlayWithoutUserGesture) { | |
| 696 m_initialPlayWithoutUserGesture = false; | |
| 697 | |
| 698 recordAutoplayMetric(AutoplayPaused); | |
| 699 | |
| 700 if (bailout) | |
| 701 recordAutoplayMetric(AutoplayBailout); | |
| 702 } | |
| 703 } | |
| 704 | |
| 694 void HTMLMediaElement::load() | 705 void HTMLMediaElement::load() |
| 695 { | 706 { |
| 696 WTF_LOG(Media, "HTMLMediaElement::load(%p)", this); | 707 WTF_LOG(Media, "HTMLMediaElement::load(%p)", this); |
| 697 | 708 |
| 698 if (m_initialPlayWithoutUserGestures && m_playing) | 709 recordMetricsIfPausing(); |
| 699 gesturelessInitialPlayHalted(); | |
| 700 | 710 |
| 701 if (UserGestureIndicator::processingUserGesture() && m_userGestureRequiredFo rPlay) { | 711 if (UserGestureIndicator::processingUserGesture() && m_userGestureRequiredFo rPlay) { |
| 702 recordAutoplayMetric(AutoplayEnabledThroughLoad); | 712 recordAutoplayMetric(AutoplayEnabledThroughLoad); |
| 703 m_userGestureRequiredForPlay = false; | 713 m_userGestureRequiredForPlay = false; |
| 704 // While usergesture-initiated load()s technically count as autoplayed, | 714 // While usergesture-initiated load()s technically count as autoplayed, |
| 705 // they don't feel like such to the users and hence we don't want to | 715 // they don't feel like such to the users and hence we don't want to |
| 706 // count them for the purposes of metrics. | 716 // count them for the purposes of metrics. |
| 707 m_autoplayMediaCounted = true; | 717 m_autoplayMediaCounted = true; |
| 708 } | 718 } |
| 709 | 719 |
| (...skipping 838 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1548 scheduleEvent(EventTypeNames::canplay); | 1558 scheduleEvent(EventTypeNames::canplay); |
| 1549 if (isPotentiallyPlaying) | 1559 if (isPotentiallyPlaying) |
| 1550 scheduleEvent(EventTypeNames::playing); | 1560 scheduleEvent(EventTypeNames::playing); |
| 1551 } | 1561 } |
| 1552 | 1562 |
| 1553 if (m_autoplaying && m_paused && autoplay()) { | 1563 if (m_autoplaying && m_paused && autoplay()) { |
| 1554 autoplayMediaEncountered(); | 1564 autoplayMediaEncountered(); |
| 1555 | 1565 |
| 1556 if (document().isSandboxed(SandboxAutomaticFeatures)) { | 1566 if (document().isSandboxed(SandboxAutomaticFeatures)) { |
| 1557 recordAutoplayMetric(AutoplayDisabledBySandbox); | 1567 recordAutoplayMetric(AutoplayDisabledBySandbox); |
| 1558 } else if (!m_userGestureRequiredForPlay) { | 1568 } else { |
| 1559 m_paused = false; | 1569 // If the autoplay experiment says that it's okay to play now, |
| 1560 invalidateCachedTime(); | 1570 // then don't require a user gesture. |
| 1561 scheduleEvent(EventTypeNames::play); | 1571 m_autoplayHelper.becameReadyToPlay(); |
| 1562 scheduleEvent(EventTypeNames::playing); | 1572 |
| 1573 if (!m_userGestureRequiredForPlay) { | |
| 1574 m_paused = false; | |
| 1575 invalidateCachedTime(); | |
| 1576 scheduleEvent(EventTypeNames::play); | |
| 1577 scheduleEvent(EventTypeNames::playing); | |
| 1578 } | |
| 1563 } | 1579 } |
| 1564 } | 1580 } |
| 1565 | 1581 |
| 1566 scheduleEvent(EventTypeNames::canplaythrough); | 1582 scheduleEvent(EventTypeNames::canplaythrough); |
| 1567 | 1583 |
| 1568 shouldUpdateDisplayState = true; | 1584 shouldUpdateDisplayState = true; |
| 1569 } | 1585 } |
| 1570 | 1586 |
| 1571 if (shouldUpdateDisplayState) { | 1587 if (shouldUpdateDisplayState) { |
| 1572 updateDisplayState(); | 1588 updateDisplayState(); |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1685 | 1701 |
| 1686 m_lastSeekTime = time; | 1702 m_lastSeekTime = time; |
| 1687 m_sentEndEvent = false; | 1703 m_sentEndEvent = false; |
| 1688 | 1704 |
| 1689 // 10 - Queue a task to fire a simple event named seeking at the element. | 1705 // 10 - Queue a task to fire a simple event named seeking at the element. |
| 1690 scheduleEvent(EventTypeNames::seeking); | 1706 scheduleEvent(EventTypeNames::seeking); |
| 1691 | 1707 |
| 1692 // 11 - Set the current playback position to the given new playback position . | 1708 // 11 - Set the current playback position to the given new playback position . |
| 1693 webMediaPlayer()->seek(time); | 1709 webMediaPlayer()->seek(time); |
| 1694 | 1710 |
| 1695 m_initialPlayWithoutUserGestures = false; | 1711 m_initialPlayWithoutUserGesture = false; |
| 1696 | 1712 |
| 1697 // 14-17 are handled, if necessary, when the engine signals a readystate cha nge or otherwise | 1713 // 14-17 are handled, if necessary, when the engine signals a readystate cha nge or otherwise |
| 1698 // satisfies seek completion and signals a time change. | 1714 // satisfies seek completion and signals a time change. |
| 1699 } | 1715 } |
| 1700 | 1716 |
| 1701 void HTMLMediaElement::finishSeek() | 1717 void HTMLMediaElement::finishSeek() |
| 1702 { | 1718 { |
| 1703 WTF_LOG(Media, "HTMLMediaElement::finishSeek(%p)", this); | 1719 WTF_LOG(Media, "HTMLMediaElement::finishSeek(%p)", this); |
| 1704 | 1720 |
| 1705 // 14 - Set the seeking IDL attribute to false. | 1721 // 14 - Set the seeking IDL attribute to false. |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1876 // The ended attribute must return true if the media element has ended | 1892 // The ended attribute must return true if the media element has ended |
| 1877 // playback and the direction of playback is forwards, and false otherwise. | 1893 // playback and the direction of playback is forwards, and false otherwise. |
| 1878 return endedPlayback() && directionOfPlayback() == Forward; | 1894 return endedPlayback() && directionOfPlayback() == Forward; |
| 1879 } | 1895 } |
| 1880 | 1896 |
| 1881 bool HTMLMediaElement::autoplay() const | 1897 bool HTMLMediaElement::autoplay() const |
| 1882 { | 1898 { |
| 1883 return fastHasAttribute(autoplayAttr); | 1899 return fastHasAttribute(autoplayAttr); |
| 1884 } | 1900 } |
| 1885 | 1901 |
| 1902 bool HTMLMediaElement::shouldAutoplay() const | |
| 1903 { | |
| 1904 return m_autoplaying && autoplay(); | |
|
philipj_slow
2015/09/04 09:24:27
Can you also add m_paused and the sandbox requirem
liberato (no reviews please)
2015/09/08 21:58:01
done. i just moved the metrics recording into sho
philipj_slow
2015/09/10 10:05:13
Did you forget to upload some changes? I can't see
liberato (no reviews please)
2015/09/10 14:52:27
this was applied to the branch with visibility che
| |
| 1905 } | |
| 1906 | |
| 1886 String HTMLMediaElement::preload() const | 1907 String HTMLMediaElement::preload() const |
| 1887 { | 1908 { |
| 1888 switch (preloadType()) { | 1909 switch (preloadType()) { |
| 1889 case WebMediaPlayer::PreloadNone: | 1910 case WebMediaPlayer::PreloadNone: |
| 1890 return "none"; | 1911 return "none"; |
| 1891 case WebMediaPlayer::PreloadMetaData: | 1912 case WebMediaPlayer::PreloadMetaData: |
| 1892 return "metadata"; | 1913 return "metadata"; |
| 1893 case WebMediaPlayer::PreloadAuto: | 1914 case WebMediaPlayer::PreloadAuto: |
| 1894 return "auto"; | 1915 return "auto"; |
| 1895 } | 1916 } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1935 | 1956 |
| 1936 WebMediaPlayer::Preload HTMLMediaElement::effectivePreloadType() const | 1957 WebMediaPlayer::Preload HTMLMediaElement::effectivePreloadType() const |
| 1937 { | 1958 { |
| 1938 return autoplay() ? WebMediaPlayer::PreloadAuto : preloadType(); | 1959 return autoplay() ? WebMediaPlayer::PreloadAuto : preloadType(); |
| 1939 } | 1960 } |
| 1940 | 1961 |
| 1941 void HTMLMediaElement::play() | 1962 void HTMLMediaElement::play() |
| 1942 { | 1963 { |
| 1943 WTF_LOG(Media, "HTMLMediaElement::play(%p)", this); | 1964 WTF_LOG(Media, "HTMLMediaElement::play(%p)", this); |
| 1944 | 1965 |
| 1966 m_autoplayHelper.playMethodCalled(); | |
| 1967 | |
| 1945 if (!UserGestureIndicator::processingUserGesture()) { | 1968 if (!UserGestureIndicator::processingUserGesture()) { |
| 1946 autoplayMediaEncountered(); | 1969 autoplayMediaEncountered(); |
| 1970 | |
| 1947 if (m_userGestureRequiredForPlay) { | 1971 if (m_userGestureRequiredForPlay) { |
| 1972 recordAutoplayMetric(PlayMethodFailed); | |
| 1948 String message = ExceptionMessages::failedToExecute("play", "HTMLMed iaElement", "API can only be initiated by a user gesture."); | 1973 String message = ExceptionMessages::failedToExecute("play", "HTMLMed iaElement", "API can only be initiated by a user gesture."); |
| 1949 document().executionContext()->addConsoleMessage(ConsoleMessage::cre ate(JSMessageSource, WarningMessageLevel, message)); | 1974 document().executionContext()->addConsoleMessage(ConsoleMessage::cre ate(JSMessageSource, WarningMessageLevel, message)); |
| 1950 return; | 1975 return; |
| 1951 } | 1976 } |
| 1952 } else if (m_userGestureRequiredForPlay) { | 1977 } else if (m_userGestureRequiredForPlay) { |
| 1953 if (m_autoplayMediaCounted) | 1978 if (m_autoplayMediaCounted) |
| 1954 recordAutoplayMetric(AutoplayManualStart); | 1979 recordAutoplayMetric(AutoplayManualStart); |
| 1955 m_userGestureRequiredForPlay = false; | 1980 m_userGestureRequiredForPlay = false; |
| 1956 } | 1981 } |
| 1957 | 1982 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1991 updateMediaController(); | 2016 updateMediaController(); |
| 1992 } | 2017 } |
| 1993 | 2018 |
| 1994 void HTMLMediaElement::autoplayMediaEncountered() | 2019 void HTMLMediaElement::autoplayMediaEncountered() |
| 1995 { | 2020 { |
| 1996 if (!m_autoplayMediaCounted) { | 2021 if (!m_autoplayMediaCounted) { |
| 1997 m_autoplayMediaCounted = true; | 2022 m_autoplayMediaCounted = true; |
| 1998 recordAutoplayMetric(AutoplayMediaFound); | 2023 recordAutoplayMetric(AutoplayMediaFound); |
| 1999 | 2024 |
| 2000 if (!m_userGestureRequiredForPlay) | 2025 if (!m_userGestureRequiredForPlay) |
| 2001 m_initialPlayWithoutUserGestures = true; | 2026 m_initialPlayWithoutUserGesture = true; |
| 2002 } | 2027 } |
| 2003 } | 2028 } |
| 2004 | 2029 |
| 2005 void HTMLMediaElement::gesturelessInitialPlayHalted() | 2030 bool HTMLMediaElement::isBailout() const |
| 2006 { | 2031 { |
| 2007 ASSERT(m_initialPlayWithoutUserGestures); | |
| 2008 m_initialPlayWithoutUserGestures = false; | |
| 2009 | |
| 2010 recordAutoplayMetric(AutoplayStopped); | |
| 2011 | |
| 2012 // We count the user as having bailed-out on the video if they watched | 2032 // We count the user as having bailed-out on the video if they watched |
| 2013 // less than one minute and less than 50% of it. | 2033 // less than one minute and less than 50% of it. |
| 2014 double playedTime = currentTime(); | 2034 const double playedTime = currentTime(); |
| 2015 if (playedTime < 60) { | 2035 const double progress = playedTime / duration(); |
| 2016 double progress = playedTime / duration(); | 2036 return (playedTime < 60) && (progress < 0.5); |
| 2017 if (progress < 0.5) | |
| 2018 recordAutoplayMetric(AutoplayBailout); | |
| 2019 } | |
| 2020 } | 2037 } |
| 2021 | 2038 |
| 2022 void HTMLMediaElement::pause() | 2039 void HTMLMediaElement::pause() |
| 2023 { | 2040 { |
| 2024 WTF_LOG(Media, "HTMLMediaElement::pause(%p)", this); | 2041 WTF_LOG(Media, "HTMLMediaElement::pause(%p)", this); |
| 2025 | 2042 |
| 2026 if (m_networkState == NETWORK_EMPTY) | 2043 if (m_networkState == NETWORK_EMPTY) |
| 2027 scheduleDelayedAction(LoadMediaResource); | 2044 scheduleDelayedAction(LoadMediaResource); |
| 2028 | 2045 |
| 2046 m_autoplayHelper.pauseMethodCalled(); | |
| 2047 | |
| 2029 m_autoplaying = false; | 2048 m_autoplaying = false; |
| 2030 | 2049 |
| 2031 if (!m_paused) { | 2050 if (!m_paused) { |
| 2032 if (m_initialPlayWithoutUserGestures) | 2051 recordMetricsIfPausing(); |
| 2033 gesturelessInitialPlayHalted(); | |
| 2034 | 2052 |
| 2035 m_paused = true; | 2053 m_paused = true; |
| 2036 scheduleTimeupdateEvent(false); | 2054 scheduleTimeupdateEvent(false); |
| 2037 scheduleEvent(EventTypeNames::pause); | 2055 scheduleEvent(EventTypeNames::pause); |
| 2038 } | 2056 } |
| 2039 | 2057 |
| 2040 updatePlayState(); | 2058 updatePlayState(); |
| 2041 } | 2059 } |
| 2042 | 2060 |
| 2043 void HTMLMediaElement::requestRemotePlayback() | 2061 void HTMLMediaElement::requestRemotePlayback() |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2116 | 2134 |
| 2117 void HTMLMediaElement::setMuted(bool muted) | 2135 void HTMLMediaElement::setMuted(bool muted) |
| 2118 { | 2136 { |
| 2119 WTF_LOG(Media, "HTMLMediaElement::setMuted(%p, %s)", this, boolString(muted) ); | 2137 WTF_LOG(Media, "HTMLMediaElement::setMuted(%p, %s)", this, boolString(muted) ); |
| 2120 | 2138 |
| 2121 if (m_muted == muted) | 2139 if (m_muted == muted) |
| 2122 return; | 2140 return; |
| 2123 | 2141 |
| 2124 m_muted = muted; | 2142 m_muted = muted; |
| 2125 | 2143 |
| 2144 m_autoplayHelper.mutedChanged(); | |
| 2145 | |
| 2126 updateVolume(); | 2146 updateVolume(); |
| 2127 | 2147 |
| 2128 scheduleEvent(EventTypeNames::volumechange); | 2148 scheduleEvent(EventTypeNames::volumechange); |
| 2129 } | 2149 } |
| 2130 | 2150 |
| 2131 void HTMLMediaElement::updateVolume() | 2151 void HTMLMediaElement::updateVolume() |
| 2132 { | 2152 { |
| 2133 if (webMediaPlayer()) | 2153 if (webMediaPlayer()) |
| 2134 webMediaPlayer()->setVolume(effectiveMediaVolume()); | 2154 webMediaPlayer()->setVolume(effectiveMediaVolume()); |
| 2135 | 2155 |
| (...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2747 if (!m_mediaController && !m_paused) { | 2767 if (!m_mediaController && !m_paused) { |
| 2748 // changes paused to true and fires a simple event named pause a t the media element. | 2768 // changes paused to true and fires a simple event named pause a t the media element. |
| 2749 m_paused = true; | 2769 m_paused = true; |
| 2750 scheduleEvent(EventTypeNames::pause); | 2770 scheduleEvent(EventTypeNames::pause); |
| 2751 } | 2771 } |
| 2752 // Queue a task to fire a simple event named ended at the media elem ent. | 2772 // Queue a task to fire a simple event named ended at the media elem ent. |
| 2753 if (!m_sentEndEvent) { | 2773 if (!m_sentEndEvent) { |
| 2754 m_sentEndEvent = true; | 2774 m_sentEndEvent = true; |
| 2755 scheduleEvent(EventTypeNames::ended); | 2775 scheduleEvent(EventTypeNames::ended); |
| 2756 } | 2776 } |
| 2777 recordMetricsIfPausing(); | |
| 2757 // If the media element has a current media controller, then report the controller state | 2778 // If the media element has a current media controller, then report the controller state |
| 2758 // for the media element's current media controller. | 2779 // for the media element's current media controller. |
| 2759 updateMediaController(); | 2780 updateMediaController(); |
| 2760 } | 2781 } |
| 2761 } else { | 2782 } else { |
| 2762 m_sentEndEvent = false; | 2783 m_sentEndEvent = false; |
| 2763 } | 2784 } |
| 2764 | 2785 |
| 2765 updatePlayState(); | 2786 updatePlayState(); |
| 2766 } | 2787 } |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2967 // The media engine should just stash the rate and muted values sinc e it isn't already playing. | 2988 // The media engine should just stash the rate and muted values sinc e it isn't already playing. |
| 2968 webMediaPlayer()->setRate(effectivePlaybackRate()); | 2989 webMediaPlayer()->setRate(effectivePlaybackRate()); |
| 2969 updateVolume(); | 2990 updateVolume(); |
| 2970 webMediaPlayer()->play(); | 2991 webMediaPlayer()->play(); |
| 2971 } | 2992 } |
| 2972 | 2993 |
| 2973 if (mediaControls()) | 2994 if (mediaControls()) |
| 2974 mediaControls()->playbackStarted(); | 2995 mediaControls()->playbackStarted(); |
| 2975 startPlaybackProgressTimer(); | 2996 startPlaybackProgressTimer(); |
| 2976 m_playing = true; | 2997 m_playing = true; |
| 2998 recordAutoplayMetric(AnyPlaybackStarted); | |
| 2977 | 2999 |
| 2978 } else { // Should not be playing right now | 3000 } else { // Should not be playing right now |
| 2979 if (isPlaying) | 3001 if (isPlaying) |
| 2980 webMediaPlayer()->pause(); | 3002 webMediaPlayer()->pause(); |
| 2981 refreshCachedTime(); | 3003 refreshCachedTime(); |
| 2982 | 3004 |
| 2983 m_playbackProgressTimer.stop(); | 3005 m_playbackProgressTimer.stop(); |
| 2984 m_playing = false; | 3006 m_playing = false; |
| 2985 double time = currentTime(); | 3007 double time = currentTime(); |
| 2986 if (time > m_lastSeekTime) | 3008 if (time > m_lastSeekTime) |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3086 mediaControls()->refreshCastButtonVisibilityWithoutUpdate(); | 3108 mediaControls()->refreshCastButtonVisibilityWithoutUpdate(); |
| 3087 | 3109 |
| 3088 if (layoutObject()) | 3110 if (layoutObject()) |
| 3089 layoutObject()->setShouldDoFullPaintInvalidation(); | 3111 layoutObject()->setShouldDoFullPaintInvalidation(); |
| 3090 } | 3112 } |
| 3091 | 3113 |
| 3092 void HTMLMediaElement::stop() | 3114 void HTMLMediaElement::stop() |
| 3093 { | 3115 { |
| 3094 WTF_LOG(Media, "HTMLMediaElement::stop(%p)", this); | 3116 WTF_LOG(Media, "HTMLMediaElement::stop(%p)", this); |
| 3095 | 3117 |
| 3096 if (m_playing && m_initialPlayWithoutUserGestures) | 3118 recordMetricsIfPausing(); |
| 3097 gesturelessInitialPlayHalted(); | |
| 3098 | 3119 |
| 3099 // Close the async event queue so that no events are enqueued by userCancell edLoad. | 3120 // Close the async event queue so that no events are enqueued by userCancell edLoad. |
| 3100 cancelPendingEventsAndCallbacks(); | 3121 cancelPendingEventsAndCallbacks(); |
| 3101 m_asyncEventQueue->close(); | 3122 m_asyncEventQueue->close(); |
| 3102 | 3123 |
| 3103 userCancelledLoad(); | 3124 userCancelledLoad(); |
| 3104 | 3125 |
| 3105 // Stop the playback without generating events | 3126 // Stop the playback without generating events |
| 3106 m_playing = false; | 3127 m_playing = false; |
| 3107 m_paused = true; | 3128 m_paused = true; |
| (...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3701 | 3722 |
| 3702 // Enable the first audio track if an audio track hasn't been enabled yet. | 3723 // Enable the first audio track if an audio track hasn't been enabled yet. |
| 3703 if (audioTracks().length() > 0 && !audioTracks().hasEnabledTrack()) | 3724 if (audioTracks().length() > 0 && !audioTracks().hasEnabledTrack()) |
| 3704 audioTracks().anonymousIndexedGetter(0)->setEnabled(true); | 3725 audioTracks().anonymousIndexedGetter(0)->setEnabled(true); |
| 3705 | 3726 |
| 3706 // Select the first video track if a video track hasn't been selected yet. | 3727 // Select the first video track if a video track hasn't been selected yet. |
| 3707 if (videoTracks().length() > 0 && videoTracks().selectedIndex() == -1) | 3728 if (videoTracks().length() > 0 && videoTracks().selectedIndex() == -1) |
| 3708 videoTracks().anonymousIndexedGetter(0)->setSelected(true); | 3729 videoTracks().anonymousIndexedGetter(0)->setSelected(true); |
| 3709 } | 3730 } |
| 3710 | 3731 |
| 3732 bool HTMLMediaElement::isUserGestureRequiredForPlay() const | |
| 3733 { | |
| 3734 return m_userGestureRequiredForPlay; | |
| 3735 } | |
| 3736 | |
| 3737 void HTMLMediaElement::removeUserGestureRequirement() | |
| 3738 { | |
| 3739 m_userGestureRequiredForPlay = false; | |
| 3740 } | |
| 3741 | |
| 3742 void HTMLMediaElement::setInitialPlayWithoutUserGestures(bool value) | |
| 3743 { | |
| 3744 m_initialPlayWithoutUserGesture = value; | |
| 3745 } | |
| 3746 | |
| 3711 #if ENABLE(WEB_AUDIO) | 3747 #if ENABLE(WEB_AUDIO) |
| 3712 void HTMLMediaElement::clearWeakMembers(Visitor* visitor) | 3748 void HTMLMediaElement::clearWeakMembers(Visitor* visitor) |
| 3713 { | 3749 { |
| 3714 if (!Heap::isHeapObjectAlive(m_audioSourceNode)) | 3750 if (!Heap::isHeapObjectAlive(m_audioSourceNode)) |
| 3715 audioSourceProvider().setClient(nullptr); | 3751 audioSourceProvider().setClient(nullptr); |
| 3716 } | 3752 } |
| 3717 | 3753 |
| 3718 void HTMLMediaElement::AudioSourceProviderImpl::wrap(WebAudioSourceProvider* pro vider) | 3754 void HTMLMediaElement::AudioSourceProviderImpl::wrap(WebAudioSourceProvider* pro vider) |
| 3719 { | 3755 { |
| 3720 MutexLocker locker(provideInputLock); | 3756 MutexLocker locker(provideInputLock); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3770 visitor->trace(m_client); | 3806 visitor->trace(m_client); |
| 3771 } | 3807 } |
| 3772 | 3808 |
| 3773 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) | 3809 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) |
| 3774 { | 3810 { |
| 3775 visitor->trace(m_client); | 3811 visitor->trace(m_client); |
| 3776 } | 3812 } |
| 3777 #endif | 3813 #endif |
| 3778 | 3814 |
| 3779 } | 3815 } |
| OLD | NEW |