Chromium Code Reviews| 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 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 427 , m_textTracksVisible(false) | 427 , m_textTracksVisible(false) |
| 428 , m_shouldPerformAutomaticTrackSelection(true) | 428 , m_shouldPerformAutomaticTrackSelection(true) |
| 429 , m_tracksAreReady(true) | 429 , m_tracksAreReady(true) |
| 430 , m_processingPreferenceChange(false) | 430 , m_processingPreferenceChange(false) |
| 431 , m_remoteRoutesAvailable(false) | 431 , m_remoteRoutesAvailable(false) |
| 432 , m_playingRemotely(false) | 432 , m_playingRemotely(false) |
| 433 , m_inOverlayFullscreenVideo(false) | 433 , m_inOverlayFullscreenVideo(false) |
| 434 , m_audioTracks(AudioTrackList::create(*this)) | 434 , m_audioTracks(AudioTrackList::create(*this)) |
| 435 , m_videoTracks(VideoTrackList::create(*this)) | 435 , m_videoTracks(VideoTrackList::create(*this)) |
| 436 , m_textTracks(nullptr) | 436 , m_textTracks(nullptr) |
| 437 , m_playPromiseResolveTask(CancellableTaskFactory::create(this, &HTMLMediaEl ement::resolvePlayPromises)) | 437 , m_playPromiseResolveTask(CancellableTaskFactory::create(this, &HTMLMediaEl ement::resolveScheduledPlayPromises)) |
| 438 , m_playPromiseRejectTask(CancellableTaskFactory::create(this, &HTMLMediaEle ment::rejectPlayPromises)) | 438 , m_playPromiseRejectTask(CancellableTaskFactory::create(this, &HTMLMediaEle ment::rejectScheduledPlayPromises)) |
| 439 , m_audioSourceNode(nullptr) | 439 , m_audioSourceNode(nullptr) |
| 440 , m_autoplayHelperClient(AutoplayHelperClientImpl::create(this)) | 440 , m_autoplayHelperClient(AutoplayHelperClientImpl::create(this)) |
| 441 , m_autoplayHelper(AutoplayExperimentHelper::create(m_autoplayHelperClient.g et())) | 441 , m_autoplayHelper(AutoplayExperimentHelper::create(m_autoplayHelperClient.g et())) |
| 442 , m_remotePlaybackClient(nullptr) | 442 , m_remotePlaybackClient(nullptr) |
| 443 { | 443 { |
| 444 ThreadState::current()->registerPreFinalizer(this); | 444 ThreadState::current()->registerPreFinalizer(this); |
| 445 | 445 |
| 446 DVLOG(MEDIA_LOG_LEVEL) << "HTMLMediaElement(" << (void*)this << ")"; | 446 DVLOG(MEDIA_LOG_LEVEL) << "HTMLMediaElement(" << (void*)this << ")"; |
| 447 | 447 |
| 448 // If any experiment is enabled, then we want to enable a user gesture by | 448 // If any experiment is enabled, then we want to enable a user gesture by |
| (...skipping 1565 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2014 | 2014 |
| 2015 WebMediaPlayer::Preload preload = preloadType(); | 2015 WebMediaPlayer::Preload preload = preloadType(); |
| 2016 if (m_ignorePreloadNone && preload == WebMediaPlayer::PreloadNone) | 2016 if (m_ignorePreloadNone && preload == WebMediaPlayer::PreloadNone) |
| 2017 return WebMediaPlayer::PreloadMetaData; | 2017 return WebMediaPlayer::PreloadMetaData; |
| 2018 | 2018 |
| 2019 return preload; | 2019 return preload; |
| 2020 } | 2020 } |
| 2021 | 2021 |
| 2022 ScriptPromise HTMLMediaElement::playForBindings(ScriptState* scriptState) | 2022 ScriptPromise HTMLMediaElement::playForBindings(ScriptState* scriptState) |
| 2023 { | 2023 { |
| 2024 // We have to share the same logic for internal and external callers. The | |
| 2025 // internal callers do not want to receive a Promise back but when ::play() | |
| 2026 // is called, |m_playPromiseResolvers| needs to be populated. What this code | |
| 2027 // does is to populate |m_playPromiseResolvers| before calling ::play() and | |
| 2028 // remove the Promise if ::play() failed. | |
| 2029 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; | |
| 2030 ScriptPromise promise = resolver->promise(); | |
| 2031 m_playPromiseResolvers.append(resolver); | |
| 2032 | |
| 2024 Nullable<ExceptionCode> code = play(); | 2033 Nullable<ExceptionCode> code = play(); |
| 2025 if (!code.isNull()) { | 2034 if (!code.isNull()) { |
| 2035 DCHECK(!m_playPromiseResolvers.isEmpty()); | |
| 2036 m_playPromiseResolvers.removeLast(); | |
| 2037 | |
| 2026 String message; | 2038 String message; |
| 2027 switch (code.get()) { | 2039 switch (code.get()) { |
| 2028 case NotAllowedError: | 2040 case NotAllowedError: |
| 2029 message = "play() can only be initiated by a user gesture."; | 2041 message = "play() can only be initiated by a user gesture."; |
| 2030 break; | 2042 break; |
| 2031 case NotSupportedError: | 2043 case NotSupportedError: |
| 2032 message = "The element has no supported sources."; | 2044 message = "The element has no supported sources."; |
| 2033 break; | 2045 break; |
| 2034 default: | 2046 default: |
| 2035 NOTREACHED(); | 2047 NOTREACHED(); |
| 2036 } | 2048 } |
| 2037 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(code.get(), message)); | 2049 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(code.get(), message)); |
| 2038 } | 2050 } |
| 2039 | 2051 |
| 2040 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; | |
| 2041 ScriptPromise promise = resolver->promise(); | |
| 2042 | |
| 2043 m_playResolvers.append(resolver); | |
| 2044 return promise; | 2052 return promise; |
| 2045 } | 2053 } |
| 2046 | 2054 |
| 2047 Nullable<ExceptionCode> HTMLMediaElement::play() | 2055 Nullable<ExceptionCode> HTMLMediaElement::play() |
| 2048 { | 2056 { |
| 2049 DVLOG(MEDIA_LOG_LEVEL) << "play(" << (void*)this << ")"; | 2057 DVLOG(MEDIA_LOG_LEVEL) << "play(" << (void*)this << ")"; |
| 2050 | 2058 |
| 2051 m_autoplayHelper->playMethodCalled(); | 2059 m_autoplayHelper->playMethodCalled(); |
| 2052 | 2060 |
| 2053 if (!UserGestureIndicator::processingUserGesture()) { | 2061 if (!UserGestureIndicator::processingUserGesture()) { |
| (...skipping 1541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3595 visitor->trace(m_asyncEventQueue); | 3603 visitor->trace(m_asyncEventQueue); |
| 3596 visitor->trace(m_error); | 3604 visitor->trace(m_error); |
| 3597 visitor->trace(m_currentSourceNode); | 3605 visitor->trace(m_currentSourceNode); |
| 3598 visitor->trace(m_nextChildNodeToConsider); | 3606 visitor->trace(m_nextChildNodeToConsider); |
| 3599 visitor->trace(m_mediaSource); | 3607 visitor->trace(m_mediaSource); |
| 3600 visitor->trace(m_audioTracks); | 3608 visitor->trace(m_audioTracks); |
| 3601 visitor->trace(m_videoTracks); | 3609 visitor->trace(m_videoTracks); |
| 3602 visitor->trace(m_cueTimeline); | 3610 visitor->trace(m_cueTimeline); |
| 3603 visitor->trace(m_textTracks); | 3611 visitor->trace(m_textTracks); |
| 3604 visitor->trace(m_textTracksWhenResourceSelectionBegan); | 3612 visitor->trace(m_textTracksWhenResourceSelectionBegan); |
| 3605 visitor->trace(m_playResolvers); | 3613 visitor->trace(m_playPromiseResolvers); |
| 3614 visitor->trace(m_playPromiseResolveList); | |
| 3615 visitor->trace(m_playPromiseRejectList); | |
| 3606 visitor->trace(m_audioSourceProvider); | 3616 visitor->trace(m_audioSourceProvider); |
| 3607 visitor->trace(m_autoplayHelperClient); | 3617 visitor->trace(m_autoplayHelperClient); |
| 3608 visitor->trace(m_autoplayHelper); | 3618 visitor->trace(m_autoplayHelper); |
| 3609 visitor->trace(m_srcObject); | 3619 visitor->trace(m_srcObject); |
| 3610 visitor->template registerWeakMembers<HTMLMediaElement, &HTMLMediaElement::c learWeakMembers>(this); | 3620 visitor->template registerWeakMembers<HTMLMediaElement, &HTMLMediaElement::c learWeakMembers>(this); |
| 3611 Supplementable<HTMLMediaElement>::trace(visitor); | 3621 Supplementable<HTMLMediaElement>::trace(visitor); |
| 3612 HTMLElement::trace(visitor); | 3622 HTMLElement::trace(visitor); |
| 3613 ActiveDOMObject::trace(visitor); | 3623 ActiveDOMObject::trace(visitor); |
| 3614 } | 3624 } |
| 3615 | 3625 |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3692 // TODO(liberato): remove once autoplay gesture override experiment concludes. | 3702 // TODO(liberato): remove once autoplay gesture override experiment concludes. |
| 3693 void HTMLMediaElement::triggerAutoplayViewportCheckForTesting() | 3703 void HTMLMediaElement::triggerAutoplayViewportCheckForTesting() |
| 3694 { | 3704 { |
| 3695 if (FrameView* view = document().view()) | 3705 if (FrameView* view = document().view()) |
| 3696 m_autoplayHelper->positionChanged(view->rootFrameToContents(view->comput eVisibleArea())); | 3706 m_autoplayHelper->positionChanged(view->rootFrameToContents(view->comput eVisibleArea())); |
| 3697 m_autoplayHelper->triggerAutoplayViewportCheckForTesting(); | 3707 m_autoplayHelper->triggerAutoplayViewportCheckForTesting(); |
| 3698 } | 3708 } |
| 3699 | 3709 |
| 3700 void HTMLMediaElement::scheduleResolvePlayPromises() | 3710 void HTMLMediaElement::scheduleResolvePlayPromises() |
| 3701 { | 3711 { |
| 3702 // Per spec, if there are two tasks in the queue, the first task will remove | 3712 // TODO(mlamouri): per spec, we should create a new task but we can't create |
| 3703 // all the pending promises making the second task useless unless a promise | 3713 // a new cancellable task without cancelling the previous one. There are two |
| 3704 // can be added between the first and second task being run which is not | 3714 // approaches then: cancel the previous task and create a new one with the |
| 3705 // possible at the moment. | 3715 // appended promise list or append the new promise to the current list. The |
| 3716 // former approach is prefered because it might be the less observable | |
|
fs
2016/06/06 09:13:24
Nit: preferred (also below)
mlamouri (slow - plz ping)
2016/06/06 16:00:55
Done.
| |
| 3717 // change. | |
| 3718 DCHECK(m_playPromiseResolveList.isEmpty() || m_playPromiseResolveTask->isPen ding()); | |
| 3719 if (m_playPromiseResolvers.isEmpty()) | |
| 3720 return; | |
| 3721 | |
| 3722 m_playPromiseResolveList.appendVector(m_playPromiseResolvers); | |
| 3723 m_playPromiseResolvers.clear(); | |
| 3724 | |
| 3706 if (m_playPromiseResolveTask->isPending()) | 3725 if (m_playPromiseResolveTask->isPending()) |
| 3707 return; | 3726 return; |
| 3708 | 3727 |
| 3709 Platform::current()->currentThread()->getWebTaskRunner()->postTask(BLINK_FRO M_HERE, m_playPromiseResolveTask->cancelAndCreate()); | 3728 Platform::current()->currentThread()->getWebTaskRunner()->postTask(BLINK_FRO M_HERE, m_playPromiseResolveTask->cancelAndCreate()); |
| 3710 } | 3729 } |
| 3711 | 3730 |
| 3712 void HTMLMediaElement::scheduleRejectPlayPromises(ExceptionCode code) | 3731 void HTMLMediaElement::scheduleRejectPlayPromises(ExceptionCode code) |
| 3713 { | 3732 { |
| 3714 // Per spec, if there are two tasks in the queue, the first task will remove | 3733 // TODO(mlamouri): per spec, we should create a new task but we can't create |
| 3715 // all the pending promises making the second task useless unless a promise | 3734 // a new cancellable task without cancelling the previous one. There are two |
| 3716 // can be added between the first and second task being run which is not | 3735 // approaches then: cancel the previous task and create a new one with the |
| 3717 // possible at the moment. | 3736 // appended promise list or append the new promise to the current list. The |
| 3737 // former approach is prefered because it might be the less observable | |
|
whywhat
2016/06/06 13:08:57
nit: the code seems to be doing the latter, not fo
mlamouri (slow - plz ping)
2016/06/06 16:00:55
Done.
| |
| 3738 // change. | |
| 3739 DCHECK(m_playPromiseRejectList.isEmpty() || m_playPromiseRejectTask->isPendi ng()); | |
| 3740 if (m_playPromiseResolvers.isEmpty()) | |
| 3741 return; | |
| 3742 | |
| 3743 m_playPromiseRejectList.appendVector(m_playPromiseResolvers); | |
| 3744 m_playPromiseResolvers.clear(); | |
| 3745 | |
| 3718 if (m_playPromiseRejectTask->isPending()) | 3746 if (m_playPromiseRejectTask->isPending()) |
| 3719 return; | 3747 return; |
| 3720 | 3748 |
| 3721 // TODO(mlamouri): because cancellable tasks can't take parameters, the | 3749 // TODO(mlamouri): because cancellable tasks can't take parameters, the |
| 3722 // error code needs to be saved. | 3750 // error code needs to be saved. |
| 3723 m_playPromiseErrorCode = code; | 3751 m_playPromiseErrorCode = code; |
|
whywhat
2016/06/06 13:08:57
nit: should we update the current code for the pen
| |
| 3724 Platform::current()->currentThread()->getWebTaskRunner()->postTask(BLINK_FRO M_HERE, m_playPromiseRejectTask->cancelAndCreate()); | 3752 Platform::current()->currentThread()->getWebTaskRunner()->postTask(BLINK_FRO M_HERE, m_playPromiseRejectTask->cancelAndCreate()); |
| 3725 } | 3753 } |
| 3726 | 3754 |
| 3727 void HTMLMediaElement::scheduleNotifyPlaying() | 3755 void HTMLMediaElement::scheduleNotifyPlaying() |
| 3728 { | 3756 { |
| 3729 scheduleEvent(EventTypeNames::playing); | 3757 scheduleEvent(EventTypeNames::playing); |
| 3730 scheduleResolvePlayPromises(); | 3758 scheduleResolvePlayPromises(); |
| 3731 } | 3759 } |
| 3732 | 3760 |
| 3733 void HTMLMediaElement::resolvePlayPromises() | 3761 void HTMLMediaElement::resolveScheduledPlayPromises() |
| 3734 { | 3762 { |
| 3735 for (auto& resolver: m_playResolvers) | 3763 for (auto& resolver: m_playPromiseResolveList) |
| 3736 resolver->resolve(); | 3764 resolver->resolve(); |
| 3737 | 3765 |
| 3738 m_playResolvers.clear(); | 3766 m_playPromiseResolveList.clear(); |
| 3739 } | 3767 } |
| 3740 | 3768 |
| 3741 void HTMLMediaElement::rejectPlayPromises() | 3769 void HTMLMediaElement::rejectScheduledPlayPromises() |
| 3742 { | 3770 { |
| 3743 // TODO(mlamouri): the message is generated based on the code because | 3771 // TODO(mlamouri): the message is generated based on the code because |
| 3744 // arguments can't be passed to a cancellable task. In order to save space | 3772 // arguments can't be passed to a cancellable task. In order to save space |
| 3745 // used by the object, the string isn't saved. | 3773 // used by the object, the string isn't saved. |
| 3746 DCHECK(m_playPromiseErrorCode == AbortError || m_playPromiseErrorCode == Not SupportedError); | 3774 DCHECK(m_playPromiseErrorCode == AbortError || m_playPromiseErrorCode == Not SupportedError); |
| 3747 if (m_playPromiseErrorCode == AbortError) | 3775 if (m_playPromiseErrorCode == AbortError) |
| 3748 rejectPlayPromises(AbortError, "The play() request was interrupted by a call to pause()."); | 3776 rejectPlayPromises(AbortError, "The play() request was interrupted by a call to pause()."); |
| 3749 else | 3777 else |
| 3750 rejectPlayPromises(NotSupportedError, "Failed to load because no support ed source was found."); | 3778 rejectPlayPromises(NotSupportedError, "Failed to load because no support ed source was found."); |
| 3751 } | 3779 } |
| 3752 | 3780 |
| 3753 void HTMLMediaElement::rejectPlayPromises(ExceptionCode code, const String& mess age) | 3781 void HTMLMediaElement::rejectPlayPromises(ExceptionCode code, const String& mess age) |
| 3754 { | 3782 { |
| 3783 m_playPromiseRejectList.appendVector(m_playPromiseResolvers); | |
| 3784 m_playPromiseResolvers.clear(); | |
| 3785 rejectPlayPromisesInternal(code, message); | |
| 3786 } | |
| 3787 | |
| 3788 void HTMLMediaElement::rejectPlayPromisesInternal(ExceptionCode code, const Stri ng& message) | |
|
whywhat
2016/06/06 13:08:57
nit: seems like this method could be inlined
mlamouri (slow - plz ping)
2016/06/06 16:00:55
No. I forgot to use it in `rejectScheduledPlayProm
| |
| 3789 { | |
| 3755 DCHECK(code == AbortError || code == NotSupportedError); | 3790 DCHECK(code == AbortError || code == NotSupportedError); |
| 3756 | 3791 |
| 3757 for (auto& resolver: m_playResolvers) | 3792 for (auto& resolver: m_playPromiseRejectList) |
| 3758 resolver->reject(DOMException::create(code, message)); | 3793 resolver->reject(DOMException::create(code, message)); |
| 3759 | 3794 |
| 3760 m_playResolvers.clear(); | 3795 m_playPromiseRejectList.clear(); |
| 3761 } | 3796 } |
| 3762 | 3797 |
| 3763 EnumerationHistogram& HTMLMediaElement::showControlsHistogram() const | 3798 EnumerationHistogram& HTMLMediaElement::showControlsHistogram() const |
| 3764 { | 3799 { |
| 3765 if (isHTMLVideoElement()) { | 3800 if (isHTMLVideoElement()) { |
| 3766 DEFINE_STATIC_LOCAL(EnumerationHistogram, histogram, ("Media.Controls.Sh ow.Video", MediaControlsShowMax)); | 3801 DEFINE_STATIC_LOCAL(EnumerationHistogram, histogram, ("Media.Controls.Sh ow.Video", MediaControlsShowMax)); |
| 3767 return histogram; | 3802 return histogram; |
| 3768 } | 3803 } |
| 3769 | 3804 |
| 3770 DEFINE_STATIC_LOCAL(EnumerationHistogram, histogram, ("Media.Controls.Show.A udio", MediaControlsShowMax)); | 3805 DEFINE_STATIC_LOCAL(EnumerationHistogram, histogram, ("Media.Controls.Show.A udio", MediaControlsShowMax)); |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3881 | 3916 |
| 3882 IntRect HTMLMediaElement::AutoplayHelperClientImpl::absoluteBoundingBoxRect() co nst | 3917 IntRect HTMLMediaElement::AutoplayHelperClientImpl::absoluteBoundingBoxRect() co nst |
| 3883 { | 3918 { |
| 3884 IntRect result; | 3919 IntRect result; |
| 3885 if (LayoutObject* object = m_element->layoutObject()) | 3920 if (LayoutObject* object = m_element->layoutObject()) |
| 3886 result = object->absoluteBoundingBoxRect(); | 3921 result = object->absoluteBoundingBoxRect(); |
| 3887 return result; | 3922 return result; |
| 3888 } | 3923 } |
| 3889 | 3924 |
| 3890 } // namespace blink | 3925 } // namespace blink |
| OLD | NEW |