| 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" | |
| 48 #include "core/html/HTMLMediaSource.h" | 47 #include "core/html/HTMLMediaSource.h" |
| 49 #include "core/html/HTMLSourceElement.h" | 48 #include "core/html/HTMLSourceElement.h" |
| 50 #include "core/html/HTMLTrackElement.h" | 49 #include "core/html/HTMLTrackElement.h" |
| 51 #include "core/html/MediaError.h" | 50 #include "core/html/MediaError.h" |
| 52 #include "core/html/MediaFragmentURIParser.h" | 51 #include "core/html/MediaFragmentURIParser.h" |
| 53 #include "core/html/TimeRanges.h" | 52 #include "core/html/TimeRanges.h" |
| 54 #include "core/html/shadow/MediaControls.h" | 53 #include "core/html/shadow/MediaControls.h" |
| 55 #include "core/html/track/AudioTrack.h" | 54 #include "core/html/track/AudioTrack.h" |
| 56 #include "core/html/track/AudioTrackList.h" | 55 #include "core/html/track/AudioTrackList.h" |
| 57 #include "core/html/track/AutomaticTrackSelection.h" | 56 #include "core/html/track/AutomaticTrackSelection.h" |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 274 case WebMediaPlayer::PreloadMetaData: | 273 case WebMediaPlayer::PreloadMetaData: |
| 275 return "metadata"; | 274 return "metadata"; |
| 276 case WebMediaPlayer::PreloadAuto: | 275 case WebMediaPlayer::PreloadAuto: |
| 277 return "auto"; | 276 return "auto"; |
| 278 } | 277 } |
| 279 | 278 |
| 280 NOTREACHED(); | 279 NOTREACHED(); |
| 281 return String(); | 280 return String(); |
| 282 } | 281 } |
| 283 | 282 |
| 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 |
| 284 } // anonymous namespace | 293 } // anonymous namespace |
| 285 | 294 |
| 286 class HTMLMediaElement::AutoplayHelperClientImpl : | 295 class HTMLMediaElement::AutoplayHelperClientImpl : |
| 287 public AutoplayExperimentHelper::Client { | 296 public AutoplayExperimentHelper::Client { |
| 288 | 297 |
| 289 public: | 298 public: |
| 290 static AutoplayHelperClientImpl* create(HTMLMediaElement* element) | 299 static AutoplayHelperClientImpl* create(HTMLMediaElement* element) |
| 291 { | 300 { |
| 292 return new AutoplayHelperClientImpl(element); | 301 return new AutoplayHelperClientImpl(element); |
| 293 } | 302 } |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 431 , m_playingRemotely(false) | 440 , m_playingRemotely(false) |
| 432 , m_inOverlayFullscreenVideo(false) | 441 , m_inOverlayFullscreenVideo(false) |
| 433 , m_audioTracks(AudioTrackList::create(*this)) | 442 , m_audioTracks(AudioTrackList::create(*this)) |
| 434 , m_videoTracks(VideoTrackList::create(*this)) | 443 , m_videoTracks(VideoTrackList::create(*this)) |
| 435 , m_textTracks(nullptr) | 444 , m_textTracks(nullptr) |
| 436 , m_playPromiseResolveTask(CancellableTaskFactory::create(this, &HTMLMediaEl
ement::resolveScheduledPlayPromises)) | 445 , m_playPromiseResolveTask(CancellableTaskFactory::create(this, &HTMLMediaEl
ement::resolveScheduledPlayPromises)) |
| 437 , m_playPromiseRejectTask(CancellableTaskFactory::create(this, &HTMLMediaEle
ment::rejectScheduledPlayPromises)) | 446 , m_playPromiseRejectTask(CancellableTaskFactory::create(this, &HTMLMediaEle
ment::rejectScheduledPlayPromises)) |
| 438 , m_audioSourceNode(nullptr) | 447 , m_audioSourceNode(nullptr) |
| 439 , m_autoplayHelperClient(AutoplayHelperClientImpl::create(this)) | 448 , m_autoplayHelperClient(AutoplayHelperClientImpl::create(this)) |
| 440 , m_autoplayHelper(AutoplayExperimentHelper::create(m_autoplayHelperClient.g
et())) | 449 , m_autoplayHelper(AutoplayExperimentHelper::create(m_autoplayHelperClient.g
et())) |
| 441 , m_autoplayUmaHelper(AutoplayUmaHelper::create(this)) | |
| 442 , m_remotePlaybackClient(nullptr) | 450 , m_remotePlaybackClient(nullptr) |
| 443 , m_autoplayVisibilityObserver(nullptr) | 451 , m_autoplayVisibilityObserver(nullptr) |
| 444 { | 452 { |
| 445 ThreadState::current()->registerPreFinalizer(this); | 453 ThreadState::current()->registerPreFinalizer(this); |
| 446 | 454 |
| 447 MEDIA_LOG << "HTMLMediaElement(" << (void*)this << ")"; | 455 MEDIA_LOG << "HTMLMediaElement(" << (void*)this << ")"; |
| 448 | 456 |
| 449 // If any experiment is enabled, then we want to enable a user gesture by | 457 // If any experiment is enabled, then we want to enable a user gesture by |
| 450 // default, otherwise the experiment does nothing. | 458 // default, otherwise the experiment does nothing. |
| 451 if ((document.settings() && document.settings()->mediaPlaybackRequiresUserGe
sture()) | 459 if ((document.settings() && document.settings()->mediaPlaybackRequiresUserGe
sture()) |
| (...skipping 23 matching lines...) Expand all Loading... |
| 475 closeMediaSource(); | 483 closeMediaSource(); |
| 476 | 484 |
| 477 // Destroying the player may cause a resource load to be canceled, | 485 // Destroying the player may cause a resource load to be canceled, |
| 478 // which could result in LocalDOMWindow::dispatchWindowLoadEvent() being | 486 // which could result in LocalDOMWindow::dispatchWindowLoadEvent() being |
| 479 // called via ResourceFetch::didLoadResource(), then | 487 // called via ResourceFetch::didLoadResource(), then |
| 480 // FrameLoader::checkCompleted(). But it's guaranteed that the load event | 488 // FrameLoader::checkCompleted(). But it's guaranteed that the load event |
| 481 // doesn't get dispatched during the object destruction. | 489 // doesn't get dispatched during the object destruction. |
| 482 // See Document::isDelayingLoadEvent(). | 490 // See Document::isDelayingLoadEvent(). |
| 483 // Also see http://crbug.com/275223 for more details. | 491 // Also see http://crbug.com/275223 for more details. |
| 484 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking(); | 492 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking(); |
| 485 | |
| 486 m_autoplayUmaHelper->onElementDestroyed(); | |
| 487 } | 493 } |
| 488 | 494 |
| 489 void HTMLMediaElement::didMoveToNewDocument(Document& oldDocument) | 495 void HTMLMediaElement::didMoveToNewDocument(Document& oldDocument) |
| 490 { | 496 { |
| 491 MEDIA_LOG << "didMoveToNewDocument(" << (void*)this << ")"; | 497 MEDIA_LOG << "didMoveToNewDocument(" << (void*)this << ")"; |
| 492 | 498 |
| 493 // If any experiment is enabled, then we want to enable a user gesture by | 499 // If any experiment is enabled, then we want to enable a user gesture by |
| 494 // default, otherwise the experiment does nothing. | 500 // default, otherwise the experiment does nothing. |
| 495 bool oldDocumentRequiresUserGesture = (oldDocument.settings() && oldDocument
.settings()->mediaPlaybackRequiresUserGesture()) | 501 bool oldDocumentRequiresUserGesture = (oldDocument.settings() && oldDocument
.settings()->mediaPlaybackRequiresUserGesture()) |
| 496 || m_autoplayHelper->isExperimentEnabled(); | 502 || m_autoplayHelper->isExperimentEnabled(); |
| (...skipping 1116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1613 | 1619 |
| 1614 if (m_readyState == HAVE_ENOUGH_DATA && oldState < HAVE_ENOUGH_DATA && track
sAreReady) { | 1620 if (m_readyState == HAVE_ENOUGH_DATA && oldState < HAVE_ENOUGH_DATA && track
sAreReady) { |
| 1615 if (oldState <= HAVE_CURRENT_DATA) { | 1621 if (oldState <= HAVE_CURRENT_DATA) { |
| 1616 scheduleEvent(EventTypeNames::canplay); | 1622 scheduleEvent(EventTypeNames::canplay); |
| 1617 if (isPotentiallyPlaying) | 1623 if (isPotentiallyPlaying) |
| 1618 scheduleNotifyPlaying(); | 1624 scheduleNotifyPlaying(); |
| 1619 } | 1625 } |
| 1620 | 1626 |
| 1621 // Check for autoplay, and record metrics about it if needed. | 1627 // Check for autoplay, and record metrics about it if needed. |
| 1622 if (shouldAutoplay(RecordMetricsBehavior::DoRecord)) { | 1628 if (shouldAutoplay(RecordMetricsBehavior::DoRecord)) { |
| 1623 m_autoplayUmaHelper->onAutoplayInitiated(AutoplaySource::Attribute); | 1629 recordAutoplaySourceMetric(AutoplaySourceAttribute); |
| 1624 | 1630 |
| 1625 // If the autoplay experiment says that it's okay to play now, | 1631 // If the autoplay experiment says that it's okay to play now, |
| 1626 // then don't require a user gesture. | 1632 // then don't require a user gesture. |
| 1627 m_autoplayHelper->becameReadyToPlay(); | 1633 m_autoplayHelper->becameReadyToPlay(); |
| 1628 | 1634 |
| 1629 if (!isGestureNeededForPlayback()) { | 1635 if (!isGestureNeededForPlayback()) { |
| 1630 if (isHTMLVideoElement() && muted() && RuntimeEnabledFeatures::a
utoplayMutedVideosEnabled()) { | 1636 if (isHTMLVideoElement() && muted() && RuntimeEnabledFeatures::a
utoplayMutedVideosEnabled()) { |
| 1631 // We might end up in a situation where the previous | 1637 // We might end up in a situation where the previous |
| 1632 // observer didn't had time to fire yet. We can avoid | 1638 // observer didn't had time to fire yet. We can avoid |
| 1633 // creating a new one in this case. | 1639 // creating a new one in this case. |
| (...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2068 return promise; | 2074 return promise; |
| 2069 } | 2075 } |
| 2070 | 2076 |
| 2071 Nullable<ExceptionCode> HTMLMediaElement::play() | 2077 Nullable<ExceptionCode> HTMLMediaElement::play() |
| 2072 { | 2078 { |
| 2073 MEDIA_LOG << "play(" << (void*)this << ")"; | 2079 MEDIA_LOG << "play(" << (void*)this << ")"; |
| 2074 | 2080 |
| 2075 m_autoplayHelper->playMethodCalled(); | 2081 m_autoplayHelper->playMethodCalled(); |
| 2076 | 2082 |
| 2077 if (!UserGestureIndicator::processingUserGesture()) { | 2083 if (!UserGestureIndicator::processingUserGesture()) { |
| 2078 m_autoplayUmaHelper->onAutoplayInitiated(AutoplaySource::Method); | 2084 recordAutoplaySourceMetric(AutoplaySourceMethod); |
| 2079 if (isGestureNeededForPlayback()) { | 2085 if (isGestureNeededForPlayback()) { |
| 2080 // If playback is deferred, then don't start playback but don't | 2086 // If playback is deferred, then don't start playback but don't |
| 2081 // fail yet either. | 2087 // fail yet either. |
| 2082 if (m_autoplayHelper->isPlaybackDeferred()) | 2088 if (m_autoplayHelper->isPlaybackDeferred()) |
| 2083 return nullptr; | 2089 return nullptr; |
| 2084 | 2090 |
| 2085 // If we're already playing, then this play would do nothing anyway. | 2091 // If we're already playing, then this play would do nothing anyway. |
| 2086 // Call playInternal to handle scheduling the promise resolution. | 2092 // Call playInternal to handle scheduling the promise resolution. |
| 2087 if (!m_paused) { | 2093 if (!m_paused) { |
| 2088 playInternal(); | 2094 playInternal(); |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2293 else | 2299 else |
| 2294 Platform::current()->recordAction(UserMetricsAction("Media_Playback_Mute
_Off")); | 2300 Platform::current()->recordAction(UserMetricsAction("Media_Playback_Mute
_Off")); |
| 2295 | 2301 |
| 2296 scheduleEvent(EventTypeNames::volumechange); | 2302 scheduleEvent(EventTypeNames::volumechange); |
| 2297 | 2303 |
| 2298 // If an element autoplayed while muted, it needs to be unlocked to unmute, | 2304 // If an element autoplayed while muted, it needs to be unlocked to unmute, |
| 2299 // otherwise, it will be paused. | 2305 // otherwise, it will be paused. |
| 2300 if (wasAutoplayingMuted) { | 2306 if (wasAutoplayingMuted) { |
| 2301 if (isGestureNeededForPlayback()) { | 2307 if (isGestureNeededForPlayback()) { |
| 2302 pause(); | 2308 pause(); |
| 2303 m_autoplayUmaHelper->recordAutoplayUnmuteStatus(AutoplayUnmuteAction
Status::Failure); | 2309 recordAutoplayUnmuteStatus(AutoplayUnmuteActionFailure); |
| 2304 } else { | 2310 } else { |
| 2305 m_autoplayUmaHelper->recordAutoplayUnmuteStatus(AutoplayUnmuteAction
Status::Success); | 2311 recordAutoplayUnmuteStatus(AutoplayUnmuteActionSuccess); |
| 2306 } | 2312 } |
| 2307 } | 2313 } |
| 2308 } | 2314 } |
| 2309 | 2315 |
| 2310 void HTMLMediaElement::updateVolume() | 2316 void HTMLMediaElement::updateVolume() |
| 2311 { | 2317 { |
| 2312 if (webMediaPlayer()) | 2318 if (webMediaPlayer()) |
| 2313 webMediaPlayer()->setVolume(effectiveMediaVolume()); | 2319 webMediaPlayer()->setVolume(effectiveMediaVolume()); |
| 2314 | 2320 |
| 2315 if (mediaControls()) | 2321 if (mediaControls()) |
| (...skipping 1337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3653 visitor->trace(m_videoTracks); | 3659 visitor->trace(m_videoTracks); |
| 3654 visitor->trace(m_cueTimeline); | 3660 visitor->trace(m_cueTimeline); |
| 3655 visitor->trace(m_textTracks); | 3661 visitor->trace(m_textTracks); |
| 3656 visitor->trace(m_textTracksWhenResourceSelectionBegan); | 3662 visitor->trace(m_textTracksWhenResourceSelectionBegan); |
| 3657 visitor->trace(m_playPromiseResolvers); | 3663 visitor->trace(m_playPromiseResolvers); |
| 3658 visitor->trace(m_playPromiseResolveList); | 3664 visitor->trace(m_playPromiseResolveList); |
| 3659 visitor->trace(m_playPromiseRejectList); | 3665 visitor->trace(m_playPromiseRejectList); |
| 3660 visitor->trace(m_audioSourceProvider); | 3666 visitor->trace(m_audioSourceProvider); |
| 3661 visitor->trace(m_autoplayHelperClient); | 3667 visitor->trace(m_autoplayHelperClient); |
| 3662 visitor->trace(m_autoplayHelper); | 3668 visitor->trace(m_autoplayHelper); |
| 3663 visitor->trace(m_autoplayUmaHelper); | |
| 3664 visitor->trace(m_srcObject); | 3669 visitor->trace(m_srcObject); |
| 3665 visitor->trace(m_autoplayVisibilityObserver); | 3670 visitor->trace(m_autoplayVisibilityObserver); |
| 3666 visitor->template registerWeakMembers<HTMLMediaElement, &HTMLMediaElement::c
learWeakMembers>(this); | 3671 visitor->template registerWeakMembers<HTMLMediaElement, &HTMLMediaElement::c
learWeakMembers>(this); |
| 3667 Supplementable<HTMLMediaElement>::trace(visitor); | 3672 Supplementable<HTMLMediaElement>::trace(visitor); |
| 3668 HTMLElement::trace(visitor); | 3673 HTMLElement::trace(visitor); |
| 3669 ActiveDOMObject::trace(visitor); | 3674 ActiveDOMObject::trace(visitor); |
| 3670 } | 3675 } |
| 3671 | 3676 |
| 3672 DEFINE_TRACE_WRAPPERS(HTMLMediaElement) | 3677 DEFINE_TRACE_WRAPPERS(HTMLMediaElement) |
| 3673 { | 3678 { |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3874 { | 3879 { |
| 3875 if (isHTMLVideoElement()) { | 3880 if (isHTMLVideoElement()) { |
| 3876 DEFINE_STATIC_LOCAL(EnumerationHistogram, histogram, ("Media.Controls.Sh
ow.Video", MediaControlsShowMax)); | 3881 DEFINE_STATIC_LOCAL(EnumerationHistogram, histogram, ("Media.Controls.Sh
ow.Video", MediaControlsShowMax)); |
| 3877 return histogram; | 3882 return histogram; |
| 3878 } | 3883 } |
| 3879 | 3884 |
| 3880 DEFINE_STATIC_LOCAL(EnumerationHistogram, histogram, ("Media.Controls.Show.A
udio", MediaControlsShowMax)); | 3885 DEFINE_STATIC_LOCAL(EnumerationHistogram, histogram, ("Media.Controls.Show.A
udio", MediaControlsShowMax)); |
| 3881 return histogram; | 3886 return histogram; |
| 3882 } | 3887 } |
| 3883 | 3888 |
| 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 |
| 3884 void HTMLMediaElement::onVisibilityChangedForAutoplay(bool isVisible) | 3911 void HTMLMediaElement::onVisibilityChangedForAutoplay(bool isVisible) |
| 3885 { | 3912 { |
| 3886 if (!isVisible) | 3913 if (!isVisible) |
| 3887 return; | 3914 return; |
| 3888 | 3915 |
| 3889 if (shouldAutoplay()) { | 3916 if (shouldAutoplay()) { |
| 3890 m_paused = false; | 3917 m_paused = false; |
| 3891 invalidateCachedTime(); | 3918 invalidateCachedTime(); |
| 3892 scheduleEvent(EventTypeNames::play); | 3919 scheduleEvent(EventTypeNames::play); |
| 3893 scheduleNotifyPlaying(); | 3920 scheduleNotifyPlaying(); |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4006 | 4033 |
| 4007 IntRect HTMLMediaElement::AutoplayHelperClientImpl::absoluteBoundingBoxRect() co
nst | 4034 IntRect HTMLMediaElement::AutoplayHelperClientImpl::absoluteBoundingBoxRect() co
nst |
| 4008 { | 4035 { |
| 4009 IntRect result; | 4036 IntRect result; |
| 4010 if (LayoutObject* object = m_element->layoutObject()) | 4037 if (LayoutObject* object = m_element->layoutObject()) |
| 4011 result = object->absoluteBoundingBoxRect(); | 4038 result = object->absoluteBoundingBoxRect(); |
| 4012 return result; | 4039 return result; |
| 4013 } | 4040 } |
| 4014 | 4041 |
| 4015 } // namespace blink | 4042 } // namespace blink |
| OLD | NEW |