Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(443)

Side by Side Diff: Source/core/html/HTMLMediaElement.cpp

Issue 1179223002: Implement autoplay gesture override experiment. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: applied changes that were uploaded on another CL Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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(true)) {
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
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
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(bool recordMetrics)
1898 {
1899 if (m_autoplaying && m_paused && autoplay()) {
1900 if (recordMetrics)
1901 autoplayMediaEncountered();
1902
1903 if (document().isSandboxed(SandboxAutomaticFeatures)) {
1904 if (recordMetrics)
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
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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698