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 833 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1543 shouldUpdateDisplayState = true; | 1553 shouldUpdateDisplayState = true; |
1544 } | 1554 } |
1545 | 1555 |
1546 if (m_readyState == HAVE_ENOUGH_DATA && oldState < HAVE_ENOUGH_DATA && track
sAreReady) { | 1556 if (m_readyState == HAVE_ENOUGH_DATA && oldState < HAVE_ENOUGH_DATA && track
sAreReady) { |
1547 if (oldState <= HAVE_CURRENT_DATA) { | 1557 if (oldState <= HAVE_CURRENT_DATA) { |
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 // Check for autoplay, and record metrics about it if needed. |
1554 autoplayMediaEncountered(); | 1564 if (shouldAutoplay(RecordMetricsBehavior::DoRecord)) { |
| 1565 // If the autoplay experiment says that it's okay to play now, |
| 1566 // then don't require a user gesture. |
| 1567 m_autoplayHelper.becameReadyToPlay(); |
1555 | 1568 |
1556 if (document().isSandboxed(SandboxAutomaticFeatures)) { | 1569 if (!m_userGestureRequiredForPlay) { |
1557 recordAutoplayMetric(AutoplayDisabledBySandbox); | |
1558 } else if (!m_userGestureRequiredForPlay) { | |
1559 m_paused = false; | 1570 m_paused = false; |
1560 invalidateCachedTime(); | 1571 invalidateCachedTime(); |
1561 scheduleEvent(EventTypeNames::play); | 1572 scheduleEvent(EventTypeNames::play); |
1562 scheduleEvent(EventTypeNames::playing); | 1573 scheduleEvent(EventTypeNames::playing); |
1563 } | 1574 } |
1564 } | 1575 } |
1565 | 1576 |
1566 scheduleEvent(EventTypeNames::canplaythrough); | 1577 scheduleEvent(EventTypeNames::canplaythrough); |
1567 | 1578 |
1568 shouldUpdateDisplayState = true; | 1579 shouldUpdateDisplayState = true; |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1685 | 1696 |
1686 m_lastSeekTime = time; | 1697 m_lastSeekTime = time; |
1687 m_sentEndEvent = false; | 1698 m_sentEndEvent = false; |
1688 | 1699 |
1689 // 10 - Queue a task to fire a simple event named seeking at the element. | 1700 // 10 - Queue a task to fire a simple event named seeking at the element. |
1690 scheduleEvent(EventTypeNames::seeking); | 1701 scheduleEvent(EventTypeNames::seeking); |
1691 | 1702 |
1692 // 11 - Set the current playback position to the given new playback position
. | 1703 // 11 - Set the current playback position to the given new playback position
. |
1693 webMediaPlayer()->seek(time); | 1704 webMediaPlayer()->seek(time); |
1694 | 1705 |
1695 m_initialPlayWithoutUserGestures = false; | 1706 m_initialPlayWithoutUserGesture = false; |
1696 | 1707 |
1697 // 14-17 are handled, if necessary, when the engine signals a readystate cha
nge or otherwise | 1708 // 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. | 1709 // satisfies seek completion and signals a time change. |
1699 } | 1710 } |
1700 | 1711 |
1701 void HTMLMediaElement::finishSeek() | 1712 void HTMLMediaElement::finishSeek() |
1702 { | 1713 { |
1703 WTF_LOG(Media, "HTMLMediaElement::finishSeek(%p)", this); | 1714 WTF_LOG(Media, "HTMLMediaElement::finishSeek(%p)", this); |
1704 | 1715 |
1705 // 14 - Set the seeking IDL attribute to false. | 1716 // 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 | 1887 // The ended attribute must return true if the media element has ended |
1877 // playback and the direction of playback is forwards, and false otherwise. | 1888 // playback and the direction of playback is forwards, and false otherwise. |
1878 return endedPlayback() && directionOfPlayback() == Forward; | 1889 return endedPlayback() && directionOfPlayback() == Forward; |
1879 } | 1890 } |
1880 | 1891 |
1881 bool HTMLMediaElement::autoplay() const | 1892 bool HTMLMediaElement::autoplay() const |
1882 { | 1893 { |
1883 return fastHasAttribute(autoplayAttr); | 1894 return fastHasAttribute(autoplayAttr); |
1884 } | 1895 } |
1885 | 1896 |
| 1897 bool HTMLMediaElement::shouldAutoplay(const RecordMetricsBehavior recordMetrics) |
| 1898 { |
| 1899 if (m_autoplaying && m_paused && autoplay()) { |
| 1900 if (recordMetrics == RecordMetricsBehavior::DoRecord) |
| 1901 autoplayMediaEncountered(); |
| 1902 |
| 1903 if (document().isSandboxed(SandboxAutomaticFeatures)) { |
| 1904 if (recordMetrics == RecordMetricsBehavior::DoRecord) |
| 1905 recordAutoplayMetric(AutoplayDisabledBySandbox); |
| 1906 return false; |
| 1907 } |
| 1908 |
| 1909 return true; |
| 1910 } |
| 1911 |
| 1912 return false; |
| 1913 } |
| 1914 |
1886 String HTMLMediaElement::preload() const | 1915 String HTMLMediaElement::preload() const |
1887 { | 1916 { |
1888 switch (preloadType()) { | 1917 switch (preloadType()) { |
1889 case WebMediaPlayer::PreloadNone: | 1918 case WebMediaPlayer::PreloadNone: |
1890 return "none"; | 1919 return "none"; |
1891 case WebMediaPlayer::PreloadMetaData: | 1920 case WebMediaPlayer::PreloadMetaData: |
1892 return "metadata"; | 1921 return "metadata"; |
1893 case WebMediaPlayer::PreloadAuto: | 1922 case WebMediaPlayer::PreloadAuto: |
1894 return "auto"; | 1923 return "auto"; |
1895 } | 1924 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1935 | 1964 |
1936 WebMediaPlayer::Preload HTMLMediaElement::effectivePreloadType() const | 1965 WebMediaPlayer::Preload HTMLMediaElement::effectivePreloadType() const |
1937 { | 1966 { |
1938 return autoplay() ? WebMediaPlayer::PreloadAuto : preloadType(); | 1967 return autoplay() ? WebMediaPlayer::PreloadAuto : preloadType(); |
1939 } | 1968 } |
1940 | 1969 |
1941 void HTMLMediaElement::play() | 1970 void HTMLMediaElement::play() |
1942 { | 1971 { |
1943 WTF_LOG(Media, "HTMLMediaElement::play(%p)", this); | 1972 WTF_LOG(Media, "HTMLMediaElement::play(%p)", this); |
1944 | 1973 |
| 1974 m_autoplayHelper.playMethodCalled(); |
| 1975 |
1945 if (!UserGestureIndicator::processingUserGesture()) { | 1976 if (!UserGestureIndicator::processingUserGesture()) { |
1946 autoplayMediaEncountered(); | 1977 autoplayMediaEncountered(); |
| 1978 |
1947 if (m_userGestureRequiredForPlay) { | 1979 if (m_userGestureRequiredForPlay) { |
| 1980 recordAutoplayMetric(PlayMethodFailed); |
1948 String message = ExceptionMessages::failedToExecute("play", "HTMLMed
iaElement", "API can only be initiated by a user gesture."); | 1981 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)); | 1982 document().executionContext()->addConsoleMessage(ConsoleMessage::cre
ate(JSMessageSource, WarningMessageLevel, message)); |
1950 return; | 1983 return; |
1951 } | 1984 } |
1952 } else if (m_userGestureRequiredForPlay) { | 1985 } else if (m_userGestureRequiredForPlay) { |
1953 if (m_autoplayMediaCounted) | 1986 if (m_autoplayMediaCounted) |
1954 recordAutoplayMetric(AutoplayManualStart); | 1987 recordAutoplayMetric(AutoplayManualStart); |
1955 m_userGestureRequiredForPlay = false; | 1988 m_userGestureRequiredForPlay = false; |
1956 } | 1989 } |
1957 | 1990 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1991 updateMediaController(); | 2024 updateMediaController(); |
1992 } | 2025 } |
1993 | 2026 |
1994 void HTMLMediaElement::autoplayMediaEncountered() | 2027 void HTMLMediaElement::autoplayMediaEncountered() |
1995 { | 2028 { |
1996 if (!m_autoplayMediaCounted) { | 2029 if (!m_autoplayMediaCounted) { |
1997 m_autoplayMediaCounted = true; | 2030 m_autoplayMediaCounted = true; |
1998 recordAutoplayMetric(AutoplayMediaFound); | 2031 recordAutoplayMetric(AutoplayMediaFound); |
1999 | 2032 |
2000 if (!m_userGestureRequiredForPlay) | 2033 if (!m_userGestureRequiredForPlay) |
2001 m_initialPlayWithoutUserGestures = true; | 2034 m_initialPlayWithoutUserGesture = true; |
2002 } | 2035 } |
2003 } | 2036 } |
2004 | 2037 |
2005 void HTMLMediaElement::gesturelessInitialPlayHalted() | 2038 bool HTMLMediaElement::isBailout() const |
2006 { | 2039 { |
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 | 2040 // 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. | 2041 // less than one minute and less than 50% of it. |
2014 double playedTime = currentTime(); | 2042 const double playedTime = currentTime(); |
2015 if (playedTime < 60) { | 2043 const double progress = playedTime / duration(); |
2016 double progress = playedTime / duration(); | 2044 return (playedTime < 60) && (progress < 0.5); |
2017 if (progress < 0.5) | |
2018 recordAutoplayMetric(AutoplayBailout); | |
2019 } | |
2020 } | 2045 } |
2021 | 2046 |
2022 void HTMLMediaElement::pause() | 2047 void HTMLMediaElement::pause() |
2023 { | 2048 { |
2024 WTF_LOG(Media, "HTMLMediaElement::pause(%p)", this); | 2049 WTF_LOG(Media, "HTMLMediaElement::pause(%p)", this); |
2025 | 2050 |
2026 if (m_networkState == NETWORK_EMPTY) | 2051 if (m_networkState == NETWORK_EMPTY) |
2027 scheduleDelayedAction(LoadMediaResource); | 2052 scheduleDelayedAction(LoadMediaResource); |
2028 | 2053 |
| 2054 m_autoplayHelper.pauseMethodCalled(); |
| 2055 |
2029 m_autoplaying = false; | 2056 m_autoplaying = false; |
2030 | 2057 |
2031 if (!m_paused) { | 2058 if (!m_paused) { |
2032 if (m_initialPlayWithoutUserGestures) | 2059 recordMetricsIfPausing(); |
2033 gesturelessInitialPlayHalted(); | |
2034 | 2060 |
2035 m_paused = true; | 2061 m_paused = true; |
2036 scheduleTimeupdateEvent(false); | 2062 scheduleTimeupdateEvent(false); |
2037 scheduleEvent(EventTypeNames::pause); | 2063 scheduleEvent(EventTypeNames::pause); |
2038 } | 2064 } |
2039 | 2065 |
2040 updatePlayState(); | 2066 updatePlayState(); |
2041 } | 2067 } |
2042 | 2068 |
2043 void HTMLMediaElement::requestRemotePlayback() | 2069 void HTMLMediaElement::requestRemotePlayback() |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2116 | 2142 |
2117 void HTMLMediaElement::setMuted(bool muted) | 2143 void HTMLMediaElement::setMuted(bool muted) |
2118 { | 2144 { |
2119 WTF_LOG(Media, "HTMLMediaElement::setMuted(%p, %s)", this, boolString(muted)
); | 2145 WTF_LOG(Media, "HTMLMediaElement::setMuted(%p, %s)", this, boolString(muted)
); |
2120 | 2146 |
2121 if (m_muted == muted) | 2147 if (m_muted == muted) |
2122 return; | 2148 return; |
2123 | 2149 |
2124 m_muted = muted; | 2150 m_muted = muted; |
2125 | 2151 |
| 2152 m_autoplayHelper.mutedChanged(); |
| 2153 |
2126 updateVolume(); | 2154 updateVolume(); |
2127 | 2155 |
2128 scheduleEvent(EventTypeNames::volumechange); | 2156 scheduleEvent(EventTypeNames::volumechange); |
2129 } | 2157 } |
2130 | 2158 |
2131 void HTMLMediaElement::updateVolume() | 2159 void HTMLMediaElement::updateVolume() |
2132 { | 2160 { |
2133 if (webMediaPlayer()) | 2161 if (webMediaPlayer()) |
2134 webMediaPlayer()->setVolume(effectiveMediaVolume()); | 2162 webMediaPlayer()->setVolume(effectiveMediaVolume()); |
2135 | 2163 |
(...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2747 if (!m_mediaController && !m_paused) { | 2775 if (!m_mediaController && !m_paused) { |
2748 // changes paused to true and fires a simple event named pause a
t the media element. | 2776 // changes paused to true and fires a simple event named pause a
t the media element. |
2749 m_paused = true; | 2777 m_paused = true; |
2750 scheduleEvent(EventTypeNames::pause); | 2778 scheduleEvent(EventTypeNames::pause); |
2751 } | 2779 } |
2752 // Queue a task to fire a simple event named ended at the media elem
ent. | 2780 // Queue a task to fire a simple event named ended at the media elem
ent. |
2753 if (!m_sentEndEvent) { | 2781 if (!m_sentEndEvent) { |
2754 m_sentEndEvent = true; | 2782 m_sentEndEvent = true; |
2755 scheduleEvent(EventTypeNames::ended); | 2783 scheduleEvent(EventTypeNames::ended); |
2756 } | 2784 } |
| 2785 recordMetricsIfPausing(); |
2757 // If the media element has a current media controller, then report
the controller state | 2786 // If the media element has a current media controller, then report
the controller state |
2758 // for the media element's current media controller. | 2787 // for the media element's current media controller. |
2759 updateMediaController(); | 2788 updateMediaController(); |
2760 } | 2789 } |
2761 } else { | 2790 } else { |
2762 m_sentEndEvent = false; | 2791 m_sentEndEvent = false; |
2763 } | 2792 } |
2764 | 2793 |
2765 updatePlayState(); | 2794 updatePlayState(); |
2766 } | 2795 } |
(...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. | 2996 // The media engine should just stash the rate and muted values sinc
e it isn't already playing. |
2968 webMediaPlayer()->setRate(effectivePlaybackRate()); | 2997 webMediaPlayer()->setRate(effectivePlaybackRate()); |
2969 updateVolume(); | 2998 updateVolume(); |
2970 webMediaPlayer()->play(); | 2999 webMediaPlayer()->play(); |
2971 } | 3000 } |
2972 | 3001 |
2973 if (mediaControls()) | 3002 if (mediaControls()) |
2974 mediaControls()->playbackStarted(); | 3003 mediaControls()->playbackStarted(); |
2975 startPlaybackProgressTimer(); | 3004 startPlaybackProgressTimer(); |
2976 m_playing = true; | 3005 m_playing = true; |
| 3006 recordAutoplayMetric(AnyPlaybackStarted); |
2977 | 3007 |
2978 } else { // Should not be playing right now | 3008 } else { // Should not be playing right now |
2979 if (isPlaying) | 3009 if (isPlaying) |
2980 webMediaPlayer()->pause(); | 3010 webMediaPlayer()->pause(); |
2981 refreshCachedTime(); | 3011 refreshCachedTime(); |
2982 | 3012 |
2983 m_playbackProgressTimer.stop(); | 3013 m_playbackProgressTimer.stop(); |
2984 m_playing = false; | 3014 m_playing = false; |
2985 double time = currentTime(); | 3015 double time = currentTime(); |
2986 if (time > m_lastSeekTime) | 3016 if (time > m_lastSeekTime) |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3086 mediaControls()->refreshCastButtonVisibilityWithoutUpdate(); | 3116 mediaControls()->refreshCastButtonVisibilityWithoutUpdate(); |
3087 | 3117 |
3088 if (layoutObject()) | 3118 if (layoutObject()) |
3089 layoutObject()->setShouldDoFullPaintInvalidation(); | 3119 layoutObject()->setShouldDoFullPaintInvalidation(); |
3090 } | 3120 } |
3091 | 3121 |
3092 void HTMLMediaElement::stop() | 3122 void HTMLMediaElement::stop() |
3093 { | 3123 { |
3094 WTF_LOG(Media, "HTMLMediaElement::stop(%p)", this); | 3124 WTF_LOG(Media, "HTMLMediaElement::stop(%p)", this); |
3095 | 3125 |
3096 if (m_playing && m_initialPlayWithoutUserGestures) | 3126 recordMetricsIfPausing(); |
3097 gesturelessInitialPlayHalted(); | |
3098 | 3127 |
3099 // Close the async event queue so that no events are enqueued by userCancell
edLoad. | 3128 // Close the async event queue so that no events are enqueued by userCancell
edLoad. |
3100 cancelPendingEventsAndCallbacks(); | 3129 cancelPendingEventsAndCallbacks(); |
3101 m_asyncEventQueue->close(); | 3130 m_asyncEventQueue->close(); |
3102 | 3131 |
3103 userCancelledLoad(); | 3132 userCancelledLoad(); |
3104 | 3133 |
3105 // Stop the playback without generating events | 3134 // Stop the playback without generating events |
3106 m_playing = false; | 3135 m_playing = false; |
3107 m_paused = true; | 3136 m_paused = true; |
(...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3701 | 3730 |
3702 // Enable the first audio track if an audio track hasn't been enabled yet. | 3731 // Enable the first audio track if an audio track hasn't been enabled yet. |
3703 if (audioTracks().length() > 0 && !audioTracks().hasEnabledTrack()) | 3732 if (audioTracks().length() > 0 && !audioTracks().hasEnabledTrack()) |
3704 audioTracks().anonymousIndexedGetter(0)->setEnabled(true); | 3733 audioTracks().anonymousIndexedGetter(0)->setEnabled(true); |
3705 | 3734 |
3706 // Select the first video track if a video track hasn't been selected yet. | 3735 // Select the first video track if a video track hasn't been selected yet. |
3707 if (videoTracks().length() > 0 && videoTracks().selectedIndex() == -1) | 3736 if (videoTracks().length() > 0 && videoTracks().selectedIndex() == -1) |
3708 videoTracks().anonymousIndexedGetter(0)->setSelected(true); | 3737 videoTracks().anonymousIndexedGetter(0)->setSelected(true); |
3709 } | 3738 } |
3710 | 3739 |
| 3740 bool HTMLMediaElement::isUserGestureRequiredForPlay() const |
| 3741 { |
| 3742 return m_userGestureRequiredForPlay; |
| 3743 } |
| 3744 |
| 3745 void HTMLMediaElement::removeUserGestureRequirement() |
| 3746 { |
| 3747 m_userGestureRequiredForPlay = false; |
| 3748 } |
| 3749 |
| 3750 void HTMLMediaElement::setInitialPlayWithoutUserGestures(bool value) |
| 3751 { |
| 3752 m_initialPlayWithoutUserGesture = value; |
| 3753 } |
| 3754 |
3711 #if ENABLE(WEB_AUDIO) | 3755 #if ENABLE(WEB_AUDIO) |
3712 void HTMLMediaElement::clearWeakMembers(Visitor* visitor) | 3756 void HTMLMediaElement::clearWeakMembers(Visitor* visitor) |
3713 { | 3757 { |
3714 if (!Heap::isHeapObjectAlive(m_audioSourceNode)) | 3758 if (!Heap::isHeapObjectAlive(m_audioSourceNode)) |
3715 audioSourceProvider().setClient(nullptr); | 3759 audioSourceProvider().setClient(nullptr); |
3716 } | 3760 } |
3717 | 3761 |
3718 void HTMLMediaElement::AudioSourceProviderImpl::wrap(WebAudioSourceProvider* pro
vider) | 3762 void HTMLMediaElement::AudioSourceProviderImpl::wrap(WebAudioSourceProvider* pro
vider) |
3719 { | 3763 { |
3720 MutexLocker locker(provideInputLock); | 3764 MutexLocker locker(provideInputLock); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3770 visitor->trace(m_client); | 3814 visitor->trace(m_client); |
3771 } | 3815 } |
3772 | 3816 |
3773 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) | 3817 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) |
3774 { | 3818 { |
3775 visitor->trace(m_client); | 3819 visitor->trace(m_client); |
3776 } | 3820 } |
3777 #endif | 3821 #endif |
3778 | 3822 |
3779 } | 3823 } |
OLD | NEW |