| 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 26 matching lines...) Expand all Loading... |
| 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 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 case WebMediaPlayer::PreloadMetaData: | 274 case WebMediaPlayer::PreloadMetaData: |
| 274 return "metadata"; | 275 return "metadata"; |
| 275 case WebMediaPlayer::PreloadAuto: | 276 case WebMediaPlayer::PreloadAuto: |
| 276 return "auto"; | 277 return "auto"; |
| 277 } | 278 } |
| 278 | 279 |
| 279 NOTREACHED(); | 280 NOTREACHED(); |
| 280 return String(); | 281 return String(); |
| 281 } | 282 } |
| 282 | 283 |
| 283 // These values are used for histograms. Do not reorder. | |
| 284 enum AutoplaySource { | |
| 285 // Autoplay comes from HTMLMediaElement `autoplay` attribute. | |
| 286 AutoplaySourceAttribute = 0, | |
| 287 // Autoplay comes from `play()` method. | |
| 288 AutoplaySourceMethod = 1, | |
| 289 // This enum value must be last. | |
| 290 NumberOfAutoplaySources = 2, | |
| 291 }; | |
| 292 | |
| 293 } // anonymous namespace | 284 } // anonymous namespace |
| 294 | 285 |
| 295 class HTMLMediaElement::AutoplayHelperClientImpl : | 286 class HTMLMediaElement::AutoplayHelperClientImpl : |
| 296 public AutoplayExperimentHelper::Client { | 287 public AutoplayExperimentHelper::Client { |
| 297 | 288 |
| 298 public: | 289 public: |
| 299 static AutoplayHelperClientImpl* create(HTMLMediaElement* element) | 290 static AutoplayHelperClientImpl* create(HTMLMediaElement* element) |
| 300 { | 291 { |
| 301 return new AutoplayHelperClientImpl(element); | 292 return new AutoplayHelperClientImpl(element); |
| 302 } | 293 } |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 440 , m_playingRemotely(false) | 431 , m_playingRemotely(false) |
| 441 , m_inOverlayFullscreenVideo(false) | 432 , m_inOverlayFullscreenVideo(false) |
| 442 , m_audioTracks(AudioTrackList::create(*this)) | 433 , m_audioTracks(AudioTrackList::create(*this)) |
| 443 , m_videoTracks(VideoTrackList::create(*this)) | 434 , m_videoTracks(VideoTrackList::create(*this)) |
| 444 , m_textTracks(nullptr) | 435 , m_textTracks(nullptr) |
| 445 , m_playPromiseResolveTask(CancellableTaskFactory::create(this, &HTMLMediaEl
ement::resolveScheduledPlayPromises)) | 436 , m_playPromiseResolveTask(CancellableTaskFactory::create(this, &HTMLMediaEl
ement::resolveScheduledPlayPromises)) |
| 446 , m_playPromiseRejectTask(CancellableTaskFactory::create(this, &HTMLMediaEle
ment::rejectScheduledPlayPromises)) | 437 , m_playPromiseRejectTask(CancellableTaskFactory::create(this, &HTMLMediaEle
ment::rejectScheduledPlayPromises)) |
| 447 , m_audioSourceNode(nullptr) | 438 , m_audioSourceNode(nullptr) |
| 448 , m_autoplayHelperClient(AutoplayHelperClientImpl::create(this)) | 439 , m_autoplayHelperClient(AutoplayHelperClientImpl::create(this)) |
| 449 , m_autoplayHelper(AutoplayExperimentHelper::create(m_autoplayHelperClient.g
et())) | 440 , m_autoplayHelper(AutoplayExperimentHelper::create(m_autoplayHelperClient.g
et())) |
| 441 , m_autoplayUmaHelper(AutoplayUmaHelper::create(this)) |
| 450 , m_remotePlaybackClient(nullptr) | 442 , m_remotePlaybackClient(nullptr) |
| 451 , m_autoplayVisibilityObserver(nullptr) | 443 , m_autoplayVisibilityObserver(nullptr) |
| 452 { | 444 { |
| 453 ThreadState::current()->registerPreFinalizer(this); | 445 ThreadState::current()->registerPreFinalizer(this); |
| 454 | 446 |
| 455 MEDIA_LOG << "HTMLMediaElement(" << (void*)this << ")"; | 447 MEDIA_LOG << "HTMLMediaElement(" << (void*)this << ")"; |
| 456 | 448 |
| 457 // If any experiment is enabled, then we want to enable a user gesture by | 449 // If any experiment is enabled, then we want to enable a user gesture by |
| 458 // default, otherwise the experiment does nothing. | 450 // default, otherwise the experiment does nothing. |
| 459 if ((document.settings() && document.settings()->mediaPlaybackRequiresUserGe
sture()) | 451 if ((document.settings() && document.settings()->mediaPlaybackRequiresUserGe
sture()) |
| (...skipping 1159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1619 | 1611 |
| 1620 if (m_readyState == HAVE_ENOUGH_DATA && oldState < HAVE_ENOUGH_DATA && track
sAreReady) { | 1612 if (m_readyState == HAVE_ENOUGH_DATA && oldState < HAVE_ENOUGH_DATA && track
sAreReady) { |
| 1621 if (oldState <= HAVE_CURRENT_DATA) { | 1613 if (oldState <= HAVE_CURRENT_DATA) { |
| 1622 scheduleEvent(EventTypeNames::canplay); | 1614 scheduleEvent(EventTypeNames::canplay); |
| 1623 if (isPotentiallyPlaying) | 1615 if (isPotentiallyPlaying) |
| 1624 scheduleNotifyPlaying(); | 1616 scheduleNotifyPlaying(); |
| 1625 } | 1617 } |
| 1626 | 1618 |
| 1627 // Check for autoplay, and record metrics about it if needed. | 1619 // Check for autoplay, and record metrics about it if needed. |
| 1628 if (shouldAutoplay(RecordMetricsBehavior::DoRecord)) { | 1620 if (shouldAutoplay(RecordMetricsBehavior::DoRecord)) { |
| 1629 recordAutoplaySourceMetric(AutoplaySourceAttribute); | 1621 m_autoplayUmaHelper->onAutoplayInitiated(AutoplaySource::Attribute); |
| 1630 | 1622 |
| 1631 // If the autoplay experiment says that it's okay to play now, | 1623 // If the autoplay experiment says that it's okay to play now, |
| 1632 // then don't require a user gesture. | 1624 // then don't require a user gesture. |
| 1633 m_autoplayHelper->becameReadyToPlay(); | 1625 m_autoplayHelper->becameReadyToPlay(); |
| 1634 | 1626 |
| 1635 if (!isGestureNeededForPlayback()) { | 1627 if (!isGestureNeededForPlayback()) { |
| 1636 if (isHTMLVideoElement() && muted() && RuntimeEnabledFeatures::a
utoplayMutedVideosEnabled()) { | 1628 if (isHTMLVideoElement() && muted() && RuntimeEnabledFeatures::a
utoplayMutedVideosEnabled()) { |
| 1637 // We might end up in a situation where the previous | 1629 // We might end up in a situation where the previous |
| 1638 // observer didn't had time to fire yet. We can avoid | 1630 // observer didn't had time to fire yet. We can avoid |
| 1639 // creating a new one in this case. | 1631 // creating a new one in this case. |
| (...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2074 return promise; | 2066 return promise; |
| 2075 } | 2067 } |
| 2076 | 2068 |
| 2077 Nullable<ExceptionCode> HTMLMediaElement::play() | 2069 Nullable<ExceptionCode> HTMLMediaElement::play() |
| 2078 { | 2070 { |
| 2079 MEDIA_LOG << "play(" << (void*)this << ")"; | 2071 MEDIA_LOG << "play(" << (void*)this << ")"; |
| 2080 | 2072 |
| 2081 m_autoplayHelper->playMethodCalled(); | 2073 m_autoplayHelper->playMethodCalled(); |
| 2082 | 2074 |
| 2083 if (!UserGestureIndicator::processingUserGesture()) { | 2075 if (!UserGestureIndicator::processingUserGesture()) { |
| 2084 recordAutoplaySourceMetric(AutoplaySourceMethod); | 2076 m_autoplayUmaHelper->onAutoplayInitiated(AutoplaySource::Method); |
| 2085 if (isGestureNeededForPlayback()) { | 2077 if (isGestureNeededForPlayback()) { |
| 2086 // If playback is deferred, then don't start playback but don't | 2078 // If playback is deferred, then don't start playback but don't |
| 2087 // fail yet either. | 2079 // fail yet either. |
| 2088 if (m_autoplayHelper->isPlaybackDeferred()) | 2080 if (m_autoplayHelper->isPlaybackDeferred()) |
| 2089 return nullptr; | 2081 return nullptr; |
| 2090 | 2082 |
| 2091 // If we're already playing, then this play would do nothing anyway. | 2083 // If we're already playing, then this play would do nothing anyway. |
| 2092 // Call playInternal to handle scheduling the promise resolution. | 2084 // Call playInternal to handle scheduling the promise resolution. |
| 2093 if (!m_paused) { | 2085 if (!m_paused) { |
| 2094 playInternal(); | 2086 playInternal(); |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2299 else | 2291 else |
| 2300 Platform::current()->recordAction(UserMetricsAction("Media_Playback_Mute
_Off")); | 2292 Platform::current()->recordAction(UserMetricsAction("Media_Playback_Mute
_Off")); |
| 2301 | 2293 |
| 2302 scheduleEvent(EventTypeNames::volumechange); | 2294 scheduleEvent(EventTypeNames::volumechange); |
| 2303 | 2295 |
| 2304 // If an element autoplayed while muted, it needs to be unlocked to unmute, | 2296 // If an element autoplayed while muted, it needs to be unlocked to unmute, |
| 2305 // otherwise, it will be paused. | 2297 // otherwise, it will be paused. |
| 2306 if (wasAutoplayingMuted) { | 2298 if (wasAutoplayingMuted) { |
| 2307 if (isGestureNeededForPlayback()) { | 2299 if (isGestureNeededForPlayback()) { |
| 2308 pause(); | 2300 pause(); |
| 2309 recordAutoplayUnmuteStatus(AutoplayUnmuteActionFailure); | 2301 m_autoplayUmaHelper->recordAutoplayUnmuteStatus(AutoplayUnmuteAction
Status::Failure); |
| 2310 } else { | 2302 } else { |
| 2311 recordAutoplayUnmuteStatus(AutoplayUnmuteActionSuccess); | 2303 m_autoplayUmaHelper->recordAutoplayUnmuteStatus(AutoplayUnmuteAction
Status::Success); |
| 2312 } | 2304 } |
| 2313 } | 2305 } |
| 2314 } | 2306 } |
| 2315 | 2307 |
| 2316 void HTMLMediaElement::updateVolume() | 2308 void HTMLMediaElement::updateVolume() |
| 2317 { | 2309 { |
| 2318 if (webMediaPlayer()) | 2310 if (webMediaPlayer()) |
| 2319 webMediaPlayer()->setVolume(effectiveMediaVolume()); | 2311 webMediaPlayer()->setVolume(effectiveMediaVolume()); |
| 2320 | 2312 |
| 2321 if (mediaControls()) | 2313 if (mediaControls()) |
| (...skipping 1337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3659 visitor->trace(m_videoTracks); | 3651 visitor->trace(m_videoTracks); |
| 3660 visitor->trace(m_cueTimeline); | 3652 visitor->trace(m_cueTimeline); |
| 3661 visitor->trace(m_textTracks); | 3653 visitor->trace(m_textTracks); |
| 3662 visitor->trace(m_textTracksWhenResourceSelectionBegan); | 3654 visitor->trace(m_textTracksWhenResourceSelectionBegan); |
| 3663 visitor->trace(m_playPromiseResolvers); | 3655 visitor->trace(m_playPromiseResolvers); |
| 3664 visitor->trace(m_playPromiseResolveList); | 3656 visitor->trace(m_playPromiseResolveList); |
| 3665 visitor->trace(m_playPromiseRejectList); | 3657 visitor->trace(m_playPromiseRejectList); |
| 3666 visitor->trace(m_audioSourceProvider); | 3658 visitor->trace(m_audioSourceProvider); |
| 3667 visitor->trace(m_autoplayHelperClient); | 3659 visitor->trace(m_autoplayHelperClient); |
| 3668 visitor->trace(m_autoplayHelper); | 3660 visitor->trace(m_autoplayHelper); |
| 3661 visitor->trace(m_autoplayUmaHelper); |
| 3669 visitor->trace(m_srcObject); | 3662 visitor->trace(m_srcObject); |
| 3670 visitor->trace(m_autoplayVisibilityObserver); | 3663 visitor->trace(m_autoplayVisibilityObserver); |
| 3671 visitor->template registerWeakMembers<HTMLMediaElement, &HTMLMediaElement::c
learWeakMembers>(this); | 3664 visitor->template registerWeakMembers<HTMLMediaElement, &HTMLMediaElement::c
learWeakMembers>(this); |
| 3672 Supplementable<HTMLMediaElement>::trace(visitor); | 3665 Supplementable<HTMLMediaElement>::trace(visitor); |
| 3673 HTMLElement::trace(visitor); | 3666 HTMLElement::trace(visitor); |
| 3674 ActiveDOMObject::trace(visitor); | 3667 ActiveDOMObject::trace(visitor); |
| 3675 } | 3668 } |
| 3676 | 3669 |
| 3677 DEFINE_TRACE_WRAPPERS(HTMLMediaElement) | 3670 DEFINE_TRACE_WRAPPERS(HTMLMediaElement) |
| 3678 { | 3671 { |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3879 { | 3872 { |
| 3880 if (isHTMLVideoElement()) { | 3873 if (isHTMLVideoElement()) { |
| 3881 DEFINE_STATIC_LOCAL(EnumerationHistogram, histogram, ("Media.Controls.Sh
ow.Video", MediaControlsShowMax)); | 3874 DEFINE_STATIC_LOCAL(EnumerationHistogram, histogram, ("Media.Controls.Sh
ow.Video", MediaControlsShowMax)); |
| 3882 return histogram; | 3875 return histogram; |
| 3883 } | 3876 } |
| 3884 | 3877 |
| 3885 DEFINE_STATIC_LOCAL(EnumerationHistogram, histogram, ("Media.Controls.Show.A
udio", MediaControlsShowMax)); | 3878 DEFINE_STATIC_LOCAL(EnumerationHistogram, histogram, ("Media.Controls.Show.A
udio", MediaControlsShowMax)); |
| 3886 return histogram; | 3879 return histogram; |
| 3887 } | 3880 } |
| 3888 | 3881 |
| 3889 void HTMLMediaElement::recordAutoplaySourceMetric(int source) | |
| 3890 { | |
| 3891 DEFINE_STATIC_LOCAL(EnumerationHistogram, videoHistogram, ("Media.Video.Auto
play", NumberOfAutoplaySources)); | |
| 3892 DEFINE_STATIC_LOCAL(EnumerationHistogram, mutedVideoHistogram, ("Media.Video
.Autoplay.Muted", NumberOfAutoplaySources)); | |
| 3893 DEFINE_STATIC_LOCAL(EnumerationHistogram, audioHistogram, ("Media.Audio.Auto
play", NumberOfAutoplaySources)); | |
| 3894 | |
| 3895 if (isHTMLVideoElement()) { | |
| 3896 videoHistogram.count(source); | |
| 3897 if (muted()) | |
| 3898 mutedVideoHistogram.count(source); | |
| 3899 } else { | |
| 3900 audioHistogram.count(source); | |
| 3901 } | |
| 3902 } | |
| 3903 | |
| 3904 void HTMLMediaElement::recordAutoplayUnmuteStatus(AutoplayUnmuteActionStatus sta
tus) | |
| 3905 { | |
| 3906 DEFINE_STATIC_LOCAL(EnumerationHistogram, autoplayUnmuteHistogram, ("Media.V
ideo.Autoplay.Muted.UnmuteAction", AutoplayUnmuteActionMax)); | |
| 3907 | |
| 3908 autoplayUnmuteHistogram.count(status); | |
| 3909 } | |
| 3910 | |
| 3911 void HTMLMediaElement::onVisibilityChangedForAutoplay(bool isVisible) | 3882 void HTMLMediaElement::onVisibilityChangedForAutoplay(bool isVisible) |
| 3912 { | 3883 { |
| 3913 if (!isVisible) | 3884 if (!isVisible) |
| 3914 return; | 3885 return; |
| 3915 | 3886 |
| 3916 if (shouldAutoplay()) { | 3887 if (shouldAutoplay()) { |
| 3917 m_paused = false; | 3888 m_paused = false; |
| 3918 invalidateCachedTime(); | 3889 invalidateCachedTime(); |
| 3919 scheduleEvent(EventTypeNames::play); | 3890 scheduleEvent(EventTypeNames::play); |
| 3920 scheduleNotifyPlaying(); | 3891 scheduleNotifyPlaying(); |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4033 | 4004 |
| 4034 IntRect HTMLMediaElement::AutoplayHelperClientImpl::absoluteBoundingBoxRect() co
nst | 4005 IntRect HTMLMediaElement::AutoplayHelperClientImpl::absoluteBoundingBoxRect() co
nst |
| 4035 { | 4006 { |
| 4036 IntRect result; | 4007 IntRect result; |
| 4037 if (LayoutObject* object = m_element->layoutObject()) | 4008 if (LayoutObject* object = m_element->layoutObject()) |
| 4038 result = object->absoluteBoundingBoxRect(); | 4009 result = object->absoluteBoundingBoxRect(); |
| 4039 return result; | 4010 return result; |
| 4040 } | 4011 } |
| 4041 | 4012 |
| 4042 } // namespace blink | 4013 } // namespace blink |
| OLD | NEW |