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 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 330 , m_sentEndEvent(false) | 330 , m_sentEndEvent(false) |
| 331 , m_closedCaptionsVisible(false) | 331 , m_closedCaptionsVisible(false) |
| 332 , m_completelyLoaded(false) | 332 , m_completelyLoaded(false) |
| 333 , m_havePreparedToPlay(false) | 333 , m_havePreparedToPlay(false) |
| 334 , m_tracksAreReady(true) | 334 , m_tracksAreReady(true) |
| 335 , m_haveVisibleTextTrack(false) | 335 , m_haveVisibleTextTrack(false) |
| 336 , m_processingPreferenceChange(false) | 336 , m_processingPreferenceChange(false) |
| 337 , m_remoteRoutesAvailable(false) | 337 , m_remoteRoutesAvailable(false) |
| 338 , m_playingRemotely(false) | 338 , m_playingRemotely(false) |
| 339 , m_isFinalizing(false) | 339 , m_isFinalizing(false) |
| 340 , m_initialPlayWithoutUserGesture(false) | |
| 341 , m_autoplayMediaCounted(false) | |
| 342 , m_inOverlayFullscreenVideo(false) | 340 , m_inOverlayFullscreenVideo(false) |
| 343 , m_audioTracks(AudioTrackList::create(*this)) | 341 , m_audioTracks(AudioTrackList::create(*this)) |
| 344 , m_videoTracks(VideoTrackList::create(*this)) | 342 , m_videoTracks(VideoTrackList::create(*this)) |
| 345 , m_textTracks(nullptr) | 343 , m_textTracks(nullptr) |
| 346 #if ENABLE(WEB_AUDIO) | 344 #if ENABLE(WEB_AUDIO) |
| 347 , m_audioSourceNode(nullptr) | 345 , m_audioSourceNode(nullptr) |
| 348 #endif | 346 #endif |
| 349 , m_autoplayHelper(*this) | 347 , m_autoplayHelper(*this) |
| 350 { | 348 { |
| 351 #if ENABLE(OILPAN) | 349 #if ENABLE(OILPAN) |
| (...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 662 case WebMimeRegistry::IsSupported: | 660 case WebMimeRegistry::IsSupported: |
| 663 canPlay = "probably"; | 661 canPlay = "probably"; |
| 664 break; | 662 break; |
| 665 } | 663 } |
| 666 | 664 |
| 667 WTF_LOG(Media, "HTMLMediaElement::canPlayType(%p, %s, %s) -> %s", this, mime Type.utf8().data(), keySystem.utf8().data(), canPlay.utf8().data()); | 665 WTF_LOG(Media, "HTMLMediaElement::canPlayType(%p, %s, %s) -> %s", this, mime Type.utf8().data(), keySystem.utf8().data(), canPlay.utf8().data()); |
| 668 | 666 |
| 669 return canPlay; | 667 return canPlay; |
| 670 } | 668 } |
| 671 | 669 |
| 672 void HTMLMediaElement::recordMetricsIfPausing() | |
| 673 { | |
| 674 // If not playing, then nothing to record. | |
| 675 // TODO(liberato): test metrics. this was m_paused. | |
| 676 if (m_paused) | |
| 677 return; | |
| 678 | |
| 679 const bool bailout = isBailout(); | |
| 680 | |
| 681 // Record that play was paused. We don't care if it was autoplay, | |
| 682 // play(), or the user manually started it. | |
| 683 recordAutoplayMetric(AnyPlaybackPaused); | |
| 684 if (bailout) | |
| 685 recordAutoplayMetric(AnyPlaybackBailout); | |
| 686 | |
| 687 // If this was a gestureless play, then record that separately. | |
| 688 // These cover attr and play() gestureless starts. | |
| 689 if (m_initialPlayWithoutUserGesture) { | |
| 690 m_initialPlayWithoutUserGesture = false; | |
| 691 | |
| 692 recordAutoplayMetric(AutoplayPaused); | |
| 693 | |
| 694 if (bailout) | |
| 695 recordAutoplayMetric(AutoplayBailout); | |
| 696 } | |
| 697 } | |
| 698 | |
| 699 void HTMLMediaElement::load() | 670 void HTMLMediaElement::load() |
| 700 { | 671 { |
| 701 WTF_LOG(Media, "HTMLMediaElement::load(%p)", this); | 672 WTF_LOG(Media, "HTMLMediaElement::load(%p)", this); |
| 702 | 673 |
| 703 recordMetricsIfPausing(); | 674 m_autoplayHelper.loadMethodCalled(); |
| 704 | |
| 705 if (UserGestureIndicator::processingUserGesture() && m_userGestureRequiredFo rPlay) { | |
| 706 recordAutoplayMetric(AutoplayEnabledThroughLoad); | |
| 707 m_userGestureRequiredForPlay = false; | |
| 708 // While usergesture-initiated load()s technically count as autoplayed, | |
| 709 // they don't feel like such to the users and hence we don't want to | |
| 710 // count them for the purposes of metrics. | |
| 711 m_autoplayMediaCounted = true; | |
| 712 } | |
| 713 | 675 |
| 714 prepareForLoad(); | 676 prepareForLoad(); |
| 715 loadInternal(); | 677 loadInternal(); |
| 716 prepareToPlay(); | 678 prepareToPlay(); |
| 717 } | 679 } |
| 718 | 680 |
| 719 void HTMLMediaElement::prepareForLoad() | 681 void HTMLMediaElement::prepareForLoad() |
| 720 { | 682 { |
| 721 WTF_LOG(Media, "HTMLMediaElement::prepareForLoad(%p)", this); | 683 WTF_LOG(Media, "HTMLMediaElement::prepareForLoad(%p)", this); |
| 722 | 684 |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 926 | 888 |
| 927 LocalFrame* frame = document().frame(); | 889 LocalFrame* frame = document().frame(); |
| 928 if (!frame) { | 890 if (!frame) { |
| 929 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError); | 891 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError); |
| 930 return; | 892 return; |
| 931 } | 893 } |
| 932 | 894 |
| 933 // The resource fetch algorithm | 895 // The resource fetch algorithm |
| 934 setNetworkState(NETWORK_LOADING); | 896 setNetworkState(NETWORK_LOADING); |
| 935 | 897 |
| 898 m_autoplayHelper.loadingStarted(); | |
| 899 | |
| 936 // Set m_currentSrc *before* changing to the cache url, the fact that we are loading from the app | 900 // Set m_currentSrc *before* changing to the cache url, the fact that we are loading from the app |
| 937 // cache is an internal detail not exposed through the media element API. | 901 // cache is an internal detail not exposed through the media element API. |
| 938 m_currentSrc = url; | 902 m_currentSrc = url; |
| 939 | 903 |
| 940 #if ENABLE(WEB_AUDIO) | 904 #if ENABLE(WEB_AUDIO) |
| 941 if (m_audioSourceNode) | 905 if (m_audioSourceNode) |
| 942 m_audioSourceNode->onCurrentSrcChanged(m_currentSrc); | 906 m_audioSourceNode->onCurrentSrcChanged(m_currentSrc); |
| 943 #endif | 907 #endif |
| 944 | 908 |
| 945 WTF_LOG(Media, "HTMLMediaElement::loadResource(%p) - m_currentSrc -> %s", th is, urlForLoggingMedia(m_currentSrc).utf8().data()); | 909 WTF_LOG(Media, "HTMLMediaElement::loadResource(%p) - m_currentSrc -> %s", th is, urlForLoggingMedia(m_currentSrc).utf8().data()); |
| 946 | 910 |
| 947 startProgressEventTimer(); | 911 startProgressEventTimer(); |
| 948 | 912 |
| 949 // Reset display mode to force a recalculation of what to show because we ar e resetting the player. | 913 // Reset display mode to force a recalculation of what to show because we ar e resetting the player. |
| 950 setDisplayMode(Unknown); | 914 setDisplayMode(Unknown); |
| 951 | 915 |
| 952 setPlayerPreload(); | 916 setPlayerPreload(); |
| 953 | 917 |
| 954 if (fastHasAttribute(mutedAttr)) | 918 if (fastHasAttribute(mutedAttr)) |
| 955 m_muted = true; | 919 m_muted = true; |
| 956 updateVolume(); | 920 updateVolume(); |
| 957 | 921 |
| 958 ASSERT(!m_mediaSource); | 922 ASSERT(!m_mediaSource); |
| 959 | 923 |
| 960 bool attemptLoad = true; | 924 bool attemptLoad = true; |
| 961 | 925 |
| 962 if (url.protocolIs(mediaSourceBlobProtocol)) { | 926 if (url.protocolIs(mediaSourceBlobProtocol)) { |
| 963 if (isMediaStreamURL(url.string())) { | 927 if (isMediaStreamURL(url.string())) { |
| 964 m_userGestureRequiredForPlay = false; | 928 removeUserGestureRequirement(GesturelessPlaybackEnabledByStream); |
| 965 } else { | 929 } else { |
| 966 m_mediaSource = HTMLMediaSource::lookup(url.string()); | 930 m_mediaSource = HTMLMediaSource::lookup(url.string()); |
| 967 | 931 |
| 968 if (m_mediaSource) { | 932 if (m_mediaSource) { |
| 969 if (!m_mediaSource->attachToElement(this)) { | 933 if (!m_mediaSource->attachToElement(this)) { |
| 970 // Forget our reference to the MediaSource, so we leave it a lone | 934 // Forget our reference to the MediaSource, so we leave it a lone |
| 971 // while processing remainder of load failure. | 935 // while processing remainder of load failure. |
| 972 m_mediaSource = nullptr; | 936 m_mediaSource = nullptr; |
| 973 attemptLoad = false; | 937 attemptLoad = false; |
| 974 } | 938 } |
| (...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1526 if (m_readyState >= HAVE_CURRENT_DATA && oldState < HAVE_CURRENT_DATA && !m_ haveFiredLoadedData) { | 1490 if (m_readyState >= HAVE_CURRENT_DATA && oldState < HAVE_CURRENT_DATA && !m_ haveFiredLoadedData) { |
| 1527 m_haveFiredLoadedData = true; | 1491 m_haveFiredLoadedData = true; |
| 1528 shouldUpdateDisplayState = true; | 1492 shouldUpdateDisplayState = true; |
| 1529 scheduleEvent(EventTypeNames::loadeddata); | 1493 scheduleEvent(EventTypeNames::loadeddata); |
| 1530 setShouldDelayLoadEvent(false); | 1494 setShouldDelayLoadEvent(false); |
| 1531 } | 1495 } |
| 1532 | 1496 |
| 1533 bool isPotentiallyPlaying = potentiallyPlaying(); | 1497 bool isPotentiallyPlaying = potentiallyPlaying(); |
| 1534 if (m_readyState == HAVE_FUTURE_DATA && oldState <= HAVE_CURRENT_DATA && tra cksAreReady) { | 1498 if (m_readyState == HAVE_FUTURE_DATA && oldState <= HAVE_CURRENT_DATA && tra cksAreReady) { |
| 1535 scheduleEvent(EventTypeNames::canplay); | 1499 scheduleEvent(EventTypeNames::canplay); |
| 1536 if (isPotentiallyPlaying) | 1500 if (isPotentiallyPlaying) { |
|
philipj_slow
2015/12/02 09:01:46
Some extra {} here and elsewhere.
liberato (no reviews please)
2015/12/30 16:58:24
Done.
| |
| 1537 scheduleEvent(EventTypeNames::playing); | 1501 scheduleEvent(EventTypeNames::playing); |
| 1502 } | |
| 1538 shouldUpdateDisplayState = true; | 1503 shouldUpdateDisplayState = true; |
| 1539 } | 1504 } |
| 1540 | 1505 |
| 1541 if (m_readyState == HAVE_ENOUGH_DATA && oldState < HAVE_ENOUGH_DATA && track sAreReady) { | 1506 if (m_readyState == HAVE_ENOUGH_DATA && oldState < HAVE_ENOUGH_DATA && track sAreReady) { |
| 1542 if (oldState <= HAVE_CURRENT_DATA) { | 1507 if (oldState <= HAVE_CURRENT_DATA) { |
| 1543 scheduleEvent(EventTypeNames::canplay); | 1508 scheduleEvent(EventTypeNames::canplay); |
| 1544 if (isPotentiallyPlaying) | 1509 if (isPotentiallyPlaying) { |
| 1545 scheduleEvent(EventTypeNames::playing); | 1510 scheduleEvent(EventTypeNames::playing); |
| 1511 } | |
| 1546 } | 1512 } |
| 1547 | 1513 |
| 1548 // Check for autoplay, and record metrics about it if needed. | 1514 // Check for autoplay, and record metrics about it if needed. |
| 1549 if (shouldAutoplay(RecordMetricsBehavior::DoRecord)) { | 1515 if (shouldAutoplay(RecordMetricsBehavior::RecordOnSandboxFailure)) { |
| 1550 // If the autoplay experiment says that it's okay to play now, | 1516 // If the autoplay experiment says that it's okay to play now, |
| 1551 // then don't require a user gesture. | 1517 // then don't require a user gesture. |
| 1552 m_autoplayHelper.becameReadyToPlay(); | 1518 m_autoplayHelper.becameReadyToPlay(); |
| 1553 | 1519 |
| 1554 if (!m_userGestureRequiredForPlay) { | 1520 if (!m_userGestureRequiredForPlay) { |
| 1555 m_paused = false; | 1521 m_paused = false; |
| 1556 invalidateCachedTime(); | 1522 invalidateCachedTime(); |
| 1557 scheduleEvent(EventTypeNames::play); | 1523 scheduleEvent(EventTypeNames::play); |
| 1558 scheduleEvent(EventTypeNames::playing); | 1524 scheduleEvent(EventTypeNames::playing); |
| 1559 } | 1525 } |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1680 | 1646 |
| 1681 m_lastSeekTime = time; | 1647 m_lastSeekTime = time; |
| 1682 m_sentEndEvent = false; | 1648 m_sentEndEvent = false; |
| 1683 | 1649 |
| 1684 // 10 - Queue a task to fire a simple event named seeking at the element. | 1650 // 10 - Queue a task to fire a simple event named seeking at the element. |
| 1685 scheduleEvent(EventTypeNames::seeking); | 1651 scheduleEvent(EventTypeNames::seeking); |
| 1686 | 1652 |
| 1687 // 11 - Set the current playback position to the given new playback position . | 1653 // 11 - Set the current playback position to the given new playback position . |
| 1688 webMediaPlayer()->seek(time); | 1654 webMediaPlayer()->seek(time); |
| 1689 | 1655 |
| 1690 m_initialPlayWithoutUserGesture = false; | 1656 m_autoplayHelper.initialPlayWithUserGesture(); |
|
philipj_slow
2015/12/02 09:01:46
This is the seek method, can you remind me why `m_
liberato (no reviews please)
2015/12/30 16:58:24
i'm not sure either. i think that was left over i
| |
| 1691 | 1657 |
| 1692 // 14-17 are handled, if necessary, when the engine signals a readystate cha nge or otherwise | 1658 // 14-17 are handled, if necessary, when the engine signals a readystate cha nge or otherwise |
| 1693 // satisfies seek completion and signals a time change. | 1659 // satisfies seek completion and signals a time change. |
| 1694 } | 1660 } |
| 1695 | 1661 |
| 1696 void HTMLMediaElement::finishSeek() | 1662 void HTMLMediaElement::finishSeek() |
| 1697 { | 1663 { |
| 1698 WTF_LOG(Media, "HTMLMediaElement::finishSeek(%p)", this); | 1664 WTF_LOG(Media, "HTMLMediaElement::finishSeek(%p)", this); |
| 1699 | 1665 |
| 1700 // 14 - Set the seeking IDL attribute to false. | 1666 // 14 - Set the seeking IDL attribute to false. |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1863 } | 1829 } |
| 1864 | 1830 |
| 1865 bool HTMLMediaElement::autoplay() const | 1831 bool HTMLMediaElement::autoplay() const |
| 1866 { | 1832 { |
| 1867 return fastHasAttribute(autoplayAttr); | 1833 return fastHasAttribute(autoplayAttr); |
| 1868 } | 1834 } |
| 1869 | 1835 |
| 1870 bool HTMLMediaElement::shouldAutoplay(const RecordMetricsBehavior recordMetrics) | 1836 bool HTMLMediaElement::shouldAutoplay(const RecordMetricsBehavior recordMetrics) |
| 1871 { | 1837 { |
| 1872 if (m_autoplaying && m_paused && autoplay()) { | 1838 if (m_autoplaying && m_paused && autoplay()) { |
| 1873 if (recordMetrics == RecordMetricsBehavior::DoRecord) | |
| 1874 autoplayMediaEncountered(); | |
| 1875 | |
| 1876 if (document().isSandboxed(SandboxAutomaticFeatures)) { | 1839 if (document().isSandboxed(SandboxAutomaticFeatures)) { |
| 1877 if (recordMetrics == RecordMetricsBehavior::DoRecord) | 1840 if (recordMetrics == RecordMetricsBehavior::RecordOnSandboxFailure) { |
| 1878 recordAutoplayMetric(AutoplayDisabledBySandbox); | 1841 m_autoplayHelper.recordSandboxFailure(); |
| 1842 } | |
| 1879 return false; | 1843 return false; |
| 1880 } | 1844 } |
| 1881 | 1845 |
| 1882 return true; | 1846 return true; |
| 1883 } | 1847 } |
| 1884 | 1848 |
| 1885 return false; | 1849 return false; |
| 1886 } | 1850 } |
| 1887 | 1851 |
| 1888 String HTMLMediaElement::preload() const | 1852 String HTMLMediaElement::preload() const |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1946 return autoplay() ? WebMediaPlayer::PreloadAuto : preloadType(); | 1910 return autoplay() ? WebMediaPlayer::PreloadAuto : preloadType(); |
| 1947 } | 1911 } |
| 1948 | 1912 |
| 1949 void HTMLMediaElement::play() | 1913 void HTMLMediaElement::play() |
| 1950 { | 1914 { |
| 1951 WTF_LOG(Media, "HTMLMediaElement::play(%p)", this); | 1915 WTF_LOG(Media, "HTMLMediaElement::play(%p)", this); |
| 1952 | 1916 |
| 1953 m_autoplayHelper.playMethodCalled(); | 1917 m_autoplayHelper.playMethodCalled(); |
| 1954 | 1918 |
| 1955 if (!UserGestureIndicator::processingUserGesture()) { | 1919 if (!UserGestureIndicator::processingUserGesture()) { |
| 1956 autoplayMediaEncountered(); | |
| 1957 | |
| 1958 if (m_userGestureRequiredForPlay) { | 1920 if (m_userGestureRequiredForPlay) { |
| 1959 recordAutoplayMetric(PlayMethodFailed); | 1921 recordAutoplayMetric(PlayMethodFailed); |
| 1960 String message = ExceptionMessages::failedToExecute("play", "HTMLMed iaElement", "API can only be initiated by a user gesture."); | 1922 String message = ExceptionMessages::failedToExecute("play", "HTMLMed iaElement", "API can only be initiated by a user gesture."); |
| 1961 document().addConsoleMessage(ConsoleMessage::create(JSMessageSource, WarningMessageLevel, message)); | 1923 document().addConsoleMessage(ConsoleMessage::create(JSMessageSource, WarningMessageLevel, message)); |
| 1962 return; | 1924 return; |
| 1963 } | 1925 } |
| 1964 } else if (m_userGestureRequiredForPlay) { | 1926 } else if (m_userGestureRequiredForPlay) { |
|
philipj_slow
2015/12/02 09:01:46
You could now make this a plain else branch, since
liberato (no reviews please)
2015/12/30 16:58:24
Done.
| |
| 1965 if (m_autoplayMediaCounted) | 1927 removeUserGestureRequirement(GesturelessPlaybackEnabledByPlayMethod); |
| 1966 recordAutoplayMetric(AutoplayManualStart); | |
| 1967 m_userGestureRequiredForPlay = false; | |
| 1968 } | 1928 } |
| 1969 | 1929 |
| 1970 playInternal(); | 1930 playInternal(); |
| 1971 } | 1931 } |
| 1972 | 1932 |
| 1973 void HTMLMediaElement::playInternal() | 1933 void HTMLMediaElement::playInternal() |
| 1974 { | 1934 { |
| 1975 WTF_LOG(Media, "HTMLMediaElement::playInternal(%p)", this); | 1935 WTF_LOG(Media, "HTMLMediaElement::playInternal(%p)", this); |
| 1976 | 1936 |
| 1977 // 4.8.10.9. Playing the media resource | 1937 // 4.8.10.9. Playing the media resource |
| 1978 if (m_networkState == NETWORK_EMPTY) | 1938 if (m_networkState == NETWORK_EMPTY) |
| 1979 scheduleDelayedAction(LoadMediaResource); | 1939 scheduleDelayedAction(LoadMediaResource); |
| 1980 | 1940 |
| 1981 // Generally "ended" and "looping" are exclusive. Here, the loop attribute | 1941 // Generally "ended" and "looping" are exclusive. Here, the loop attribute |
| 1982 // is ignored to seek back to start in case loop was set after playback | 1942 // is ignored to seek back to start in case loop was set after playback |
| 1983 // ended. See http://crbug.com/364442 | 1943 // ended. See http://crbug.com/364442 |
| 1984 if (endedPlayback(LoopCondition::Ignored)) | 1944 if (endedPlayback(LoopCondition::Ignored)) |
| 1985 seek(0); | 1945 seek(0); |
| 1986 | 1946 |
| 1987 if (m_paused) { | 1947 if (m_paused) { |
| 1988 m_paused = false; | 1948 m_paused = false; |
| 1989 invalidateCachedTime(); | 1949 invalidateCachedTime(); |
| 1990 scheduleEvent(EventTypeNames::play); | 1950 scheduleEvent(EventTypeNames::play); |
| 1991 | 1951 |
| 1992 if (m_readyState <= HAVE_CURRENT_DATA) | 1952 if (m_readyState <= HAVE_CURRENT_DATA) |
| 1993 scheduleEvent(EventTypeNames::waiting); | 1953 scheduleEvent(EventTypeNames::waiting); |
| 1994 else if (m_readyState >= HAVE_FUTURE_DATA) | 1954 else if (m_readyState >= HAVE_FUTURE_DATA) |
| 1995 scheduleEvent(EventTypeNames::playing); | 1955 scheduleEvent(EventTypeNames::playing); |
| 1996 } | 1956 } |
| 1997 m_autoplaying = false; | |
|
philipj_slow
2015/12/02 09:01:46
Did this spill over from the other CL, or did you
liberato (no reviews please)
2015/12/30 16:58:24
spilled over, fixed.
| |
| 1998 | 1957 |
| 1999 updatePlayState(); | 1958 updatePlayState(); |
| 2000 } | 1959 } |
| 2001 | 1960 |
| 2002 void HTMLMediaElement::autoplayMediaEncountered() | |
| 2003 { | |
| 2004 if (!m_autoplayMediaCounted) { | |
| 2005 m_autoplayMediaCounted = true; | |
| 2006 recordAutoplayMetric(AutoplayMediaFound); | |
| 2007 | |
| 2008 if (!m_userGestureRequiredForPlay) | |
| 2009 m_initialPlayWithoutUserGesture = true; | |
| 2010 } | |
| 2011 } | |
| 2012 | |
| 2013 bool HTMLMediaElement::isBailout() const | |
| 2014 { | |
| 2015 // We count the user as having bailed-out on the video if they watched | |
| 2016 // less than one minute and less than 50% of it. | |
| 2017 const double playedTime = currentTime(); | |
| 2018 const double progress = playedTime / duration(); | |
| 2019 return (playedTime < 60) && (progress < 0.5); | |
| 2020 } | |
| 2021 | |
| 2022 void HTMLMediaElement::pause() | 1961 void HTMLMediaElement::pause() |
| 2023 { | 1962 { |
| 2024 WTF_LOG(Media, "HTMLMediaElement::pause(%p)", this); | 1963 WTF_LOG(Media, "HTMLMediaElement::pause(%p)", this); |
| 2025 | 1964 |
| 2026 if (m_networkState == NETWORK_EMPTY) | 1965 if (m_networkState == NETWORK_EMPTY) |
| 2027 scheduleDelayedAction(LoadMediaResource); | 1966 scheduleDelayedAction(LoadMediaResource); |
| 2028 | 1967 |
| 2029 m_autoplayHelper.pauseMethodCalled(); | 1968 m_autoplayHelper.pauseMethodCalled(); |
| 2030 | 1969 |
| 2031 m_autoplaying = false; | 1970 m_autoplaying = false; |
| 2032 | 1971 |
| 2033 if (!m_paused) { | 1972 if (!m_paused) { |
| 2034 recordMetricsIfPausing(); | |
| 2035 | |
| 2036 m_paused = true; | 1973 m_paused = true; |
| 2037 scheduleTimeupdateEvent(false); | 1974 scheduleTimeupdateEvent(false); |
| 2038 scheduleEvent(EventTypeNames::pause); | 1975 scheduleEvent(EventTypeNames::pause); |
| 2039 } | 1976 } |
| 2040 | 1977 |
| 2041 updatePlayState(); | 1978 updatePlayState(); |
| 2042 } | 1979 } |
| 2043 | 1980 |
| 2044 void HTMLMediaElement::requestRemotePlayback() | 1981 void HTMLMediaElement::requestRemotePlayback() |
| 2045 { | 1982 { |
| (...skipping 671 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2717 // If the media element has a loop attribute specified | 2654 // If the media element has a loop attribute specified |
| 2718 if (loop()) { | 2655 if (loop()) { |
| 2719 m_sentEndEvent = false; | 2656 m_sentEndEvent = false; |
| 2720 // then seek to the earliest possible position of the media resourc e and abort these steps. | 2657 // then seek to the earliest possible position of the media resourc e and abort these steps. |
| 2721 seek(0); | 2658 seek(0); |
| 2722 } else { | 2659 } else { |
| 2723 // If the media element has still ended playback, and the direction of playback is still | 2660 // If the media element has still ended playback, and the direction of playback is still |
| 2724 // forwards, and paused is false, | 2661 // forwards, and paused is false, |
| 2725 if (!m_paused) { | 2662 if (!m_paused) { |
| 2726 // changes paused to true and fires a simple event named pause a t the media element. | 2663 // changes paused to true and fires a simple event named pause a t the media element. |
| 2664 m_autoplayHelper.playbackEnded(); | |
| 2727 m_paused = true; | 2665 m_paused = true; |
| 2728 scheduleEvent(EventTypeNames::pause); | 2666 scheduleEvent(EventTypeNames::pause); |
| 2729 } | 2667 } |
| 2730 // Queue a task to fire a simple event named ended at the media elem ent. | 2668 // Queue a task to fire a simple event named ended at the media elem ent. |
| 2731 if (!m_sentEndEvent) { | 2669 if (!m_sentEndEvent) { |
| 2732 m_sentEndEvent = true; | 2670 m_sentEndEvent = true; |
| 2733 scheduleEvent(EventTypeNames::ended); | 2671 scheduleEvent(EventTypeNames::ended); |
| 2734 } | 2672 } |
| 2735 recordMetricsIfPausing(); | |
| 2736 } | 2673 } |
| 2737 } else { | 2674 } else { |
| 2738 m_sentEndEvent = false; | 2675 m_sentEndEvent = false; |
| 2739 } | 2676 } |
| 2740 | 2677 |
| 2741 updatePlayState(); | 2678 updatePlayState(); |
| 2742 } | 2679 } |
| 2743 | 2680 |
| 2744 void HTMLMediaElement::durationChanged() | 2681 void HTMLMediaElement::durationChanged() |
| 2745 { | 2682 { |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2932 if (shouldBePlaying) { | 2869 if (shouldBePlaying) { |
| 2933 setDisplayMode(Video); | 2870 setDisplayMode(Video); |
| 2934 invalidateCachedTime(); | 2871 invalidateCachedTime(); |
| 2935 | 2872 |
| 2936 if (!isPlaying) { | 2873 if (!isPlaying) { |
| 2937 // Set rate, muted before calling play in case they were set before the media engine was setup. | 2874 // Set rate, muted before calling play in case they were set before the media engine was setup. |
| 2938 // The media engine should just stash the rate and muted values sinc e it isn't already playing. | 2875 // The media engine should just stash the rate and muted values sinc e it isn't already playing. |
| 2939 webMediaPlayer()->setRate(playbackRate()); | 2876 webMediaPlayer()->setRate(playbackRate()); |
| 2940 updateVolume(); | 2877 updateVolume(); |
| 2941 webMediaPlayer()->play(); | 2878 webMediaPlayer()->play(); |
| 2879 m_autoplayHelper.playbackStarted(); | |
| 2942 } | 2880 } |
| 2943 | 2881 |
| 2944 if (mediaControls()) | 2882 if (mediaControls()) |
| 2945 mediaControls()->playbackStarted(); | 2883 mediaControls()->playbackStarted(); |
| 2946 startPlaybackProgressTimer(); | 2884 startPlaybackProgressTimer(); |
| 2947 m_playing = true; | 2885 m_playing = true; |
| 2948 recordAutoplayMetric(AnyPlaybackStarted); | |
| 2949 | 2886 |
| 2950 } else { // Should not be playing right now | 2887 } else { // Should not be playing right now |
| 2951 if (isPlaying) | 2888 if (isPlaying) |
| 2952 webMediaPlayer()->pause(); | 2889 webMediaPlayer()->pause(); |
| 2890 | |
| 2953 refreshCachedTime(); | 2891 refreshCachedTime(); |
| 2954 | 2892 |
| 2955 m_playbackProgressTimer.stop(); | 2893 m_playbackProgressTimer.stop(); |
| 2956 m_playing = false; | 2894 m_playing = false; |
| 2957 double time = currentTime(); | 2895 double time = currentTime(); |
| 2958 if (time > m_lastSeekTime) | 2896 if (time > m_lastSeekTime) |
| 2959 addPlayedRange(m_lastSeekTime, time); | 2897 addPlayedRange(m_lastSeekTime, time); |
| 2960 | 2898 |
| 2961 if (couldPlayIfEnoughData()) | 2899 if (couldPlayIfEnoughData()) |
| 2962 prepareToPlay(); | 2900 prepareToPlay(); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3058 mediaControls()->refreshCastButtonVisibilityWithoutUpdate(); | 2996 mediaControls()->refreshCastButtonVisibilityWithoutUpdate(); |
| 3059 | 2997 |
| 3060 if (layoutObject()) | 2998 if (layoutObject()) |
| 3061 layoutObject()->setShouldDoFullPaintInvalidation(); | 2999 layoutObject()->setShouldDoFullPaintInvalidation(); |
| 3062 } | 3000 } |
| 3063 | 3001 |
| 3064 void HTMLMediaElement::stop() | 3002 void HTMLMediaElement::stop() |
| 3065 { | 3003 { |
| 3066 WTF_LOG(Media, "HTMLMediaElement::stop(%p)", this); | 3004 WTF_LOG(Media, "HTMLMediaElement::stop(%p)", this); |
| 3067 | 3005 |
| 3068 recordMetricsIfPausing(); | |
| 3069 | |
| 3070 // Close the async event queue so that no events are enqueued by userCancell edLoad. | 3006 // Close the async event queue so that no events are enqueued by userCancell edLoad. |
| 3071 cancelPendingEventsAndCallbacks(); | 3007 cancelPendingEventsAndCallbacks(); |
| 3072 m_asyncEventQueue->close(); | 3008 m_asyncEventQueue->close(); |
| 3073 | 3009 |
| 3074 userCancelledLoad(); | 3010 userCancelledLoad(); |
| 3075 | 3011 |
| 3076 // Stop the playback without generating events | 3012 // Stop the playback without generating events |
| 3077 m_playing = false; | 3013 m_playing = false; |
| 3078 m_paused = true; | 3014 m_paused = true; |
| 3079 m_seeking = false; | 3015 m_seeking = false; |
| (...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3568 // Select the first video track if a video track hasn't been selected yet. | 3504 // Select the first video track if a video track hasn't been selected yet. |
| 3569 if (videoTracks().length() > 0 && videoTracks().selectedIndex() == -1) | 3505 if (videoTracks().length() > 0 && videoTracks().selectedIndex() == -1) |
| 3570 videoTracks().anonymousIndexedGetter(0)->setSelected(true); | 3506 videoTracks().anonymousIndexedGetter(0)->setSelected(true); |
| 3571 } | 3507 } |
| 3572 | 3508 |
| 3573 bool HTMLMediaElement::isUserGestureRequiredForPlay() const | 3509 bool HTMLMediaElement::isUserGestureRequiredForPlay() const |
| 3574 { | 3510 { |
| 3575 return m_userGestureRequiredForPlay; | 3511 return m_userGestureRequiredForPlay; |
| 3576 } | 3512 } |
| 3577 | 3513 |
| 3578 void HTMLMediaElement::removeUserGestureRequirement() | 3514 void HTMLMediaElement::removeUserGestureRequirement(AutoplayMetrics deferredMetr ic) |
| 3579 { | 3515 { |
| 3580 m_userGestureRequiredForPlay = false; | 3516 if (m_userGestureRequiredForPlay) { |
| 3581 } | 3517 m_userGestureRequiredForPlay = false; |
| 3582 | 3518 m_autoplayHelper.setGestureRemovalReason(deferredMetric); |
| 3583 void HTMLMediaElement::setInitialPlayWithoutUserGestures(bool value) | 3519 } |
| 3584 { | |
| 3585 m_initialPlayWithoutUserGesture = value; | |
| 3586 } | 3520 } |
| 3587 | 3521 |
| 3588 void HTMLMediaElement::setNetworkState(NetworkState state) | 3522 void HTMLMediaElement::setNetworkState(NetworkState state) |
| 3589 { | 3523 { |
| 3590 if (m_networkState != state) { | 3524 if (m_networkState != state) { |
| 3591 m_networkState = state; | 3525 m_networkState = state; |
| 3592 if (MediaControls* controls = mediaControls()) | 3526 if (MediaControls* controls = mediaControls()) |
| 3593 controls->networkStateChanged(); | 3527 controls->networkStateChanged(); |
| 3594 } | 3528 } |
| 3595 } | 3529 } |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3672 visitor->trace(m_client); | 3606 visitor->trace(m_client); |
| 3673 } | 3607 } |
| 3674 | 3608 |
| 3675 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) | 3609 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) |
| 3676 { | 3610 { |
| 3677 visitor->trace(m_client); | 3611 visitor->trace(m_client); |
| 3678 } | 3612 } |
| 3679 #endif | 3613 #endif |
| 3680 | 3614 |
| 3681 } | 3615 } |
| OLD | NEW |