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

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

Issue 2154303002: Reland: Measure whether muted videos that started playing with play() become visible at some point (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebased Created 4 years, 4 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 26 matching lines...) Expand all
37 #include "core/dom/ElementTraversal.h" 37 #include "core/dom/ElementTraversal.h"
38 #include "core/dom/ElementVisibilityObserver.h" 38 #include "core/dom/ElementVisibilityObserver.h"
39 #include "core/dom/Fullscreen.h" 39 #include "core/dom/Fullscreen.h"
40 #include "core/dom/shadow/ShadowRoot.h" 40 #include "core/dom/shadow/ShadowRoot.h"
41 #include "core/events/Event.h" 41 #include "core/events/Event.h"
42 #include "core/frame/FrameView.h" 42 #include "core/frame/FrameView.h"
43 #include "core/frame/LocalFrame.h" 43 #include "core/frame/LocalFrame.h"
44 #include "core/frame/Settings.h" 44 #include "core/frame/Settings.h"
45 #include "core/frame/UseCounter.h" 45 #include "core/frame/UseCounter.h"
46 #include "core/frame/csp/ContentSecurityPolicy.h" 46 #include "core/frame/csp/ContentSecurityPolicy.h"
47 #include "core/html/AutoplayUmaHelper.h"
47 #include "core/html/HTMLMediaSource.h" 48 #include "core/html/HTMLMediaSource.h"
48 #include "core/html/HTMLSourceElement.h" 49 #include "core/html/HTMLSourceElement.h"
49 #include "core/html/HTMLTrackElement.h" 50 #include "core/html/HTMLTrackElement.h"
50 #include "core/html/MediaError.h" 51 #include "core/html/MediaError.h"
51 #include "core/html/MediaFragmentURIParser.h" 52 #include "core/html/MediaFragmentURIParser.h"
52 #include "core/html/TimeRanges.h" 53 #include "core/html/TimeRanges.h"
53 #include "core/html/shadow/MediaControls.h" 54 #include "core/html/shadow/MediaControls.h"
54 #include "core/html/track/AudioTrack.h" 55 #include "core/html/track/AudioTrack.h"
55 #include "core/html/track/AudioTrackList.h" 56 #include "core/html/track/AudioTrackList.h"
56 #include "core/html/track/AutomaticTrackSelection.h" 57 #include "core/html/track/AutomaticTrackSelection.h"
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 case WebMediaPlayer::PreloadMetaData: 275 case WebMediaPlayer::PreloadMetaData:
275 return "metadata"; 276 return "metadata";
276 case WebMediaPlayer::PreloadAuto: 277 case WebMediaPlayer::PreloadAuto:
277 return "auto"; 278 return "auto";
278 } 279 }
279 280
280 NOTREACHED(); 281 NOTREACHED();
281 return String(); 282 return String();
282 } 283 }
283 284
284 // These values are used for histograms. Do not reorder.
285 enum AutoplaySource {
286 // Autoplay comes from HTMLMediaElement `autoplay` attribute.
287 AutoplaySourceAttribute = 0,
288 // Autoplay comes from `play()` method.
289 AutoplaySourceMethod = 1,
290 // This enum value must be last.
291 NumberOfAutoplaySources = 2,
292 };
293
294 } // anonymous namespace 285 } // anonymous namespace
295 286
296 class HTMLMediaElement::AutoplayHelperClientImpl : 287 class HTMLMediaElement::AutoplayHelperClientImpl :
297 public AutoplayExperimentHelper::Client { 288 public AutoplayExperimentHelper::Client {
298 289
299 public: 290 public:
300 static AutoplayHelperClientImpl* create(HTMLMediaElement* element) 291 static AutoplayHelperClientImpl* create(HTMLMediaElement* element)
301 { 292 {
302 return new AutoplayHelperClientImpl(element); 293 return new AutoplayHelperClientImpl(element);
303 } 294 }
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 , m_playingRemotely(false) 432 , m_playingRemotely(false)
442 , m_inOverlayFullscreenVideo(false) 433 , m_inOverlayFullscreenVideo(false)
443 , m_audioTracks(AudioTrackList::create(*this)) 434 , m_audioTracks(AudioTrackList::create(*this))
444 , m_videoTracks(VideoTrackList::create(*this)) 435 , m_videoTracks(VideoTrackList::create(*this))
445 , m_textTracks(nullptr) 436 , m_textTracks(nullptr)
446 , m_playPromiseResolveTask(CancellableTaskFactory::create(this, &HTMLMediaEl ement::resolveScheduledPlayPromises)) 437 , m_playPromiseResolveTask(CancellableTaskFactory::create(this, &HTMLMediaEl ement::resolveScheduledPlayPromises))
447 , m_playPromiseRejectTask(CancellableTaskFactory::create(this, &HTMLMediaEle ment::rejectScheduledPlayPromises)) 438 , m_playPromiseRejectTask(CancellableTaskFactory::create(this, &HTMLMediaEle ment::rejectScheduledPlayPromises))
448 , m_audioSourceNode(nullptr) 439 , m_audioSourceNode(nullptr)
449 , m_autoplayHelperClient(AutoplayHelperClientImpl::create(this)) 440 , m_autoplayHelperClient(AutoplayHelperClientImpl::create(this))
450 , m_autoplayHelper(AutoplayExperimentHelper::create(m_autoplayHelperClient.g et())) 441 , m_autoplayHelper(AutoplayExperimentHelper::create(m_autoplayHelperClient.g et()))
442 , m_autoplayUmaHelper(AutoplayUmaHelper::create(this))
451 , m_remotePlaybackClient(nullptr) 443 , m_remotePlaybackClient(nullptr)
452 , m_autoplayVisibilityObserver(nullptr) 444 , m_autoplayVisibilityObserver(nullptr)
453 { 445 {
454 ThreadState::current()->registerPreFinalizer(this); 446 ThreadState::current()->registerPreFinalizer(this);
455 447
456 BLINK_MEDIA_LOG << "HTMLMediaElement(" << (void*)this << ")"; 448 BLINK_MEDIA_LOG << "HTMLMediaElement(" << (void*)this << ")";
457 449
458 // If any experiment is enabled, then we want to enable a user gesture by 450 // If any experiment is enabled, then we want to enable a user gesture by
459 // default, otherwise the experiment does nothing. 451 // default, otherwise the experiment does nothing.
460 if ((document.settings() && document.settings()->mediaPlaybackRequiresUserGe sture()) 452 if ((document.settings() && document.settings()->mediaPlaybackRequiresUserGe sture())
(...skipping 29 matching lines...) Expand all
490 // doesn't get dispatched during the object destruction. 482 // doesn't get dispatched during the object destruction.
491 // See Document::isDelayingLoadEvent(). 483 // See Document::isDelayingLoadEvent().
492 // Also see http://crbug.com/275223 for more details. 484 // Also see http://crbug.com/275223 for more details.
493 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking(); 485 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking();
494 } 486 }
495 487
496 void HTMLMediaElement::didMoveToNewDocument(Document& oldDocument) 488 void HTMLMediaElement::didMoveToNewDocument(Document& oldDocument)
497 { 489 {
498 BLINK_MEDIA_LOG << "didMoveToNewDocument(" << (void*)this << ")"; 490 BLINK_MEDIA_LOG << "didMoveToNewDocument(" << (void*)this << ")";
499 491
492 m_autoplayUmaHelper->didMoveToNewDocument(oldDocument);
500 // If any experiment is enabled, then we want to enable a user gesture by 493 // If any experiment is enabled, then we want to enable a user gesture by
501 // default, otherwise the experiment does nothing. 494 // default, otherwise the experiment does nothing.
502 bool oldDocumentRequiresUserGesture = (oldDocument.settings() && oldDocument .settings()->mediaPlaybackRequiresUserGesture()) 495 bool oldDocumentRequiresUserGesture = (oldDocument.settings() && oldDocument .settings()->mediaPlaybackRequiresUserGesture())
503 || m_autoplayHelper->isExperimentEnabled(); 496 || m_autoplayHelper->isExperimentEnabled();
504 bool newDocumentRequiresUserGesture = (document().settings() && document().s ettings()->mediaPlaybackRequiresUserGesture()) 497 bool newDocumentRequiresUserGesture = (document().settings() && document().s ettings()->mediaPlaybackRequiresUserGesture())
505 || m_autoplayHelper->isExperimentEnabled(); 498 || m_autoplayHelper->isExperimentEnabled();
506 if (newDocumentRequiresUserGesture && !oldDocumentRequiresUserGesture) { 499 if (newDocumentRequiresUserGesture && !oldDocumentRequiresUserGesture) {
507 m_lockedPendingUserGesture = true; 500 m_lockedPendingUserGesture = true;
508 } 501 }
509 502
(...skipping 1130 matching lines...) Expand 10 before | Expand all | Expand 10 after
1640 1633
1641 if (m_readyState == kHaveEnoughData && oldState < kHaveEnoughData && tracksA reReady) { 1634 if (m_readyState == kHaveEnoughData && oldState < kHaveEnoughData && tracksA reReady) {
1642 if (oldState <= kHaveCurrentData) { 1635 if (oldState <= kHaveCurrentData) {
1643 scheduleEvent(EventTypeNames::canplay); 1636 scheduleEvent(EventTypeNames::canplay);
1644 if (isPotentiallyPlaying) 1637 if (isPotentiallyPlaying)
1645 scheduleNotifyPlaying(); 1638 scheduleNotifyPlaying();
1646 } 1639 }
1647 1640
1648 // Check for autoplay, and record metrics about it if needed. 1641 // Check for autoplay, and record metrics about it if needed.
1649 if (shouldAutoplay(RecordMetricsBehavior::DoRecord)) { 1642 if (shouldAutoplay(RecordMetricsBehavior::DoRecord)) {
1650 recordAutoplaySourceMetric(AutoplaySourceAttribute); 1643 m_autoplayUmaHelper->onAutoplayInitiated(AutoplaySource::Attribute);
1651 1644
1652 // If the autoplay experiment says that it's okay to play now, 1645 // If the autoplay experiment says that it's okay to play now,
1653 // then don't require a user gesture. 1646 // then don't require a user gesture.
1654 m_autoplayHelper->becameReadyToPlay(); 1647 m_autoplayHelper->becameReadyToPlay();
1655 1648
1656 if (!isGestureNeededForPlayback()) { 1649 if (!isGestureNeededForPlayback()) {
1657 if (isHTMLVideoElement() && muted() && RuntimeEnabledFeatures::a utoplayMutedVideosEnabled()) { 1650 if (isHTMLVideoElement() && muted() && RuntimeEnabledFeatures::a utoplayMutedVideosEnabled()) {
1658 // We might end up in a situation where the previous 1651 // We might end up in a situation where the previous
1659 // observer didn't had time to fire yet. We can avoid 1652 // observer didn't had time to fire yet. We can avoid
1660 // creating a new one in this case. 1653 // creating a new one in this case.
(...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after
2093 return promise; 2086 return promise;
2094 } 2087 }
2095 2088
2096 Nullable<ExceptionCode> HTMLMediaElement::play() 2089 Nullable<ExceptionCode> HTMLMediaElement::play()
2097 { 2090 {
2098 BLINK_MEDIA_LOG << "play(" << (void*)this << ")"; 2091 BLINK_MEDIA_LOG << "play(" << (void*)this << ")";
2099 2092
2100 m_autoplayHelper->playMethodCalled(); 2093 m_autoplayHelper->playMethodCalled();
2101 2094
2102 if (!UserGestureIndicator::processingUserGesture()) { 2095 if (!UserGestureIndicator::processingUserGesture()) {
2103 recordAutoplaySourceMetric(AutoplaySourceMethod); 2096 m_autoplayUmaHelper->onAutoplayInitiated(AutoplaySource::Method);
2104 if (isGestureNeededForPlayback()) { 2097 if (isGestureNeededForPlayback()) {
2105 // If playback is deferred, then don't start playback but don't 2098 // If playback is deferred, then don't start playback but don't
2106 // fail yet either. 2099 // fail yet either.
2107 if (m_autoplayHelper->isPlaybackDeferred()) 2100 if (m_autoplayHelper->isPlaybackDeferred())
2108 return nullptr; 2101 return nullptr;
2109 2102
2110 // If we're already playing, then this play would do nothing anyway. 2103 // If we're already playing, then this play would do nothing anyway.
2111 // Call playInternal to handle scheduling the promise resolution. 2104 // Call playInternal to handle scheduling the promise resolution.
2112 if (!m_paused) { 2105 if (!m_paused) {
2113 playInternal(); 2106 playInternal();
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
2308 2301
2309 updateVolume(); 2302 updateVolume();
2310 2303
2311 scheduleEvent(EventTypeNames::volumechange); 2304 scheduleEvent(EventTypeNames::volumechange);
2312 2305
2313 // If an element autoplayed while muted, it needs to be unlocked to unmute, 2306 // If an element autoplayed while muted, it needs to be unlocked to unmute,
2314 // otherwise, it will be paused. 2307 // otherwise, it will be paused.
2315 if (wasAutoplayingMuted) { 2308 if (wasAutoplayingMuted) {
2316 if (isGestureNeededForPlayback()) { 2309 if (isGestureNeededForPlayback()) {
2317 pause(); 2310 pause();
2318 recordAutoplayUnmuteStatus(AutoplayUnmuteActionFailure); 2311 m_autoplayUmaHelper->recordAutoplayUnmuteStatus(AutoplayUnmuteAction Status::Failure);
2319 } else { 2312 } else {
2320 recordAutoplayUnmuteStatus(AutoplayUnmuteActionSuccess); 2313 m_autoplayUmaHelper->recordAutoplayUnmuteStatus(AutoplayUnmuteAction Status::Success);
2321 } 2314 }
2322 } 2315 }
2323 } 2316 }
2324 2317
2325 void HTMLMediaElement::updateVolume() 2318 void HTMLMediaElement::updateVolume()
2326 { 2319 {
2327 if (webMediaPlayer()) 2320 if (webMediaPlayer())
2328 webMediaPlayer()->setVolume(effectiveMediaVolume()); 2321 webMediaPlayer()->setVolume(effectiveMediaVolume());
2329 2322
2330 if (mediaControls()) 2323 if (mediaControls())
(...skipping 1333 matching lines...) Expand 10 before | Expand all | Expand 10 after
3664 visitor->trace(m_videoTracks); 3657 visitor->trace(m_videoTracks);
3665 visitor->trace(m_cueTimeline); 3658 visitor->trace(m_cueTimeline);
3666 visitor->trace(m_textTracks); 3659 visitor->trace(m_textTracks);
3667 visitor->trace(m_textTracksWhenResourceSelectionBegan); 3660 visitor->trace(m_textTracksWhenResourceSelectionBegan);
3668 visitor->trace(m_playPromiseResolvers); 3661 visitor->trace(m_playPromiseResolvers);
3669 visitor->trace(m_playPromiseResolveList); 3662 visitor->trace(m_playPromiseResolveList);
3670 visitor->trace(m_playPromiseRejectList); 3663 visitor->trace(m_playPromiseRejectList);
3671 visitor->trace(m_audioSourceProvider); 3664 visitor->trace(m_audioSourceProvider);
3672 visitor->trace(m_autoplayHelperClient); 3665 visitor->trace(m_autoplayHelperClient);
3673 visitor->trace(m_autoplayHelper); 3666 visitor->trace(m_autoplayHelper);
3667 visitor->trace(m_autoplayUmaHelper);
3674 visitor->trace(m_srcObject); 3668 visitor->trace(m_srcObject);
3675 visitor->trace(m_autoplayVisibilityObserver); 3669 visitor->trace(m_autoplayVisibilityObserver);
3676 visitor->template registerWeakMembers<HTMLMediaElement, &HTMLMediaElement::c learWeakMembers>(this); 3670 visitor->template registerWeakMembers<HTMLMediaElement, &HTMLMediaElement::c learWeakMembers>(this);
3677 Supplementable<HTMLMediaElement>::trace(visitor); 3671 Supplementable<HTMLMediaElement>::trace(visitor);
3678 HTMLElement::trace(visitor); 3672 HTMLElement::trace(visitor);
3679 ActiveDOMObject::trace(visitor); 3673 ActiveDOMObject::trace(visitor);
3680 } 3674 }
3681 3675
3682 DEFINE_TRACE_WRAPPERS(HTMLMediaElement) 3676 DEFINE_TRACE_WRAPPERS(HTMLMediaElement)
3683 { 3677 {
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
3884 { 3878 {
3885 if (isHTMLVideoElement()) { 3879 if (isHTMLVideoElement()) {
3886 DEFINE_STATIC_LOCAL(EnumerationHistogram, histogram, ("Media.Controls.Sh ow.Video", MediaControlsShowMax)); 3880 DEFINE_STATIC_LOCAL(EnumerationHistogram, histogram, ("Media.Controls.Sh ow.Video", MediaControlsShowMax));
3887 return histogram; 3881 return histogram;
3888 } 3882 }
3889 3883
3890 DEFINE_STATIC_LOCAL(EnumerationHistogram, histogram, ("Media.Controls.Show.A udio", MediaControlsShowMax)); 3884 DEFINE_STATIC_LOCAL(EnumerationHistogram, histogram, ("Media.Controls.Show.A udio", MediaControlsShowMax));
3891 return histogram; 3885 return histogram;
3892 } 3886 }
3893 3887
3894 void HTMLMediaElement::recordAutoplaySourceMetric(int source)
3895 {
3896 DEFINE_STATIC_LOCAL(EnumerationHistogram, videoHistogram, ("Media.Video.Auto play", NumberOfAutoplaySources));
3897 DEFINE_STATIC_LOCAL(EnumerationHistogram, mutedVideoHistogram, ("Media.Video .Autoplay.Muted", NumberOfAutoplaySources));
3898 DEFINE_STATIC_LOCAL(EnumerationHistogram, audioHistogram, ("Media.Audio.Auto play", NumberOfAutoplaySources));
3899
3900 if (isHTMLVideoElement()) {
3901 videoHistogram.count(source);
3902 if (muted())
3903 mutedVideoHistogram.count(source);
3904 } else {
3905 audioHistogram.count(source);
3906 }
3907 }
3908
3909 void HTMLMediaElement::recordAutoplayUnmuteStatus(AutoplayUnmuteActionStatus sta tus)
3910 {
3911 DEFINE_STATIC_LOCAL(EnumerationHistogram, autoplayUnmuteHistogram, ("Media.V ideo.Autoplay.Muted.UnmuteAction", AutoplayUnmuteActionMax));
3912
3913 autoplayUnmuteHistogram.count(status);
3914 }
3915
3916 void HTMLMediaElement::onVisibilityChangedForAutoplay(bool isVisible) 3888 void HTMLMediaElement::onVisibilityChangedForAutoplay(bool isVisible)
3917 { 3889 {
3918 if (!isVisible) 3890 if (!isVisible)
3919 return; 3891 return;
3920 3892
3921 if (shouldAutoplay()) { 3893 if (shouldAutoplay()) {
3922 m_paused = false; 3894 m_paused = false;
3923 invalidateCachedTime(); 3895 invalidateCachedTime();
3924 scheduleEvent(EventTypeNames::play); 3896 scheduleEvent(EventTypeNames::play);
3925 scheduleNotifyPlaying(); 3897 scheduleNotifyPlaying();
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
4041 4013
4042 IntRect HTMLMediaElement::AutoplayHelperClientImpl::absoluteBoundingBoxRect() co nst 4014 IntRect HTMLMediaElement::AutoplayHelperClientImpl::absoluteBoundingBoxRect() co nst
4043 { 4015 {
4044 IntRect result; 4016 IntRect result;
4045 if (LayoutObject* object = m_element->layoutObject()) 4017 if (LayoutObject* object = m_element->layoutObject())
4046 result = object->absoluteBoundingBoxRect(); 4018 result = object->absoluteBoundingBoxRect();
4047 return result; 4019 return result;
4048 } 4020 }
4049 4021
4050 } // namespace blink 4022 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/html/HTMLMediaElement.h ('k') | third_party/WebKit/Source/core/html/OWNERS » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698