| 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 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 { | 291 { |
| 292 return new AutoplayHelperClientImpl(element); | 292 return new AutoplayHelperClientImpl(element); |
| 293 } | 293 } |
| 294 | 294 |
| 295 virtual ~AutoplayHelperClientImpl(); | 295 virtual ~AutoplayHelperClientImpl(); |
| 296 | 296 |
| 297 using RecordMetricsBehavior = HTMLMediaElement::RecordMetricsBehavior; | 297 using RecordMetricsBehavior = HTMLMediaElement::RecordMetricsBehavior; |
| 298 | 298 |
| 299 double currentTime() const override { return m_element->currentTime(); } | 299 double currentTime() const override { return m_element->currentTime(); } |
| 300 double duration() const override { return m_element->duration(); } | 300 double duration() const override { return m_element->duration(); } |
| 301 bool paused() const override { return m_element->paused(); } |
| 301 bool ended() const override { return m_element->ended(); } | 302 bool ended() const override { return m_element->ended(); } |
| 302 bool muted() const override { return m_element->muted(); } | 303 bool muted() const override { return m_element->muted(); } |
| 303 void setMuted(bool muted) override { m_element->setMuted(muted); } | 304 void setMuted(bool muted) override { m_element->setMuted(muted); } |
| 304 void playInternal() override { m_element->playInternal(); } | 305 void playInternal() override { m_element->playInternal(); } |
| 305 bool isUserGestureRequiredForPlay() const override { return m_element->isUse
rGestureRequiredForPlay(); } | 306 bool isLockedPendingUserGesture() const override { return m_element->isLocke
dPendingUserGesture(); } |
| 306 void removeUserGestureRequirement() override { m_element->removeUserGestureR
equirement(); } | 307 void unlockUserGesture() override { m_element->unlockUserGesture(); } |
| 307 void recordAutoplayMetric(AutoplayMetrics metric) override { m_element->reco
rdAutoplayMetric(metric); } | 308 void recordAutoplayMetric(AutoplayMetrics metric) override { m_element->reco
rdAutoplayMetric(metric); } |
| 308 bool shouldAutoplay() override | 309 bool shouldAutoplay() override |
| 309 { | 310 { |
| 310 return m_element->shouldAutoplay(RecordMetricsBehavior::DoNotRecord); | 311 return m_element->shouldAutoplay(RecordMetricsBehavior::DoNotRecord); |
| 311 } | 312 } |
| 312 bool isHTMLVideoElement() const override { return m_element->isHTMLVideoElem
ent(); } | 313 bool isHTMLVideoElement() const override { return m_element->isHTMLVideoElem
ent(); } |
| 313 bool isHTMLAudioElement() const override { return m_element->isHTMLAudioElem
ent(); } | 314 bool isHTMLAudioElement() const override { return m_element->isHTMLAudioElem
ent(); } |
| 314 | 315 |
| 315 // Document | 316 // Document |
| 316 bool isLegacyViewportType() override; | 317 bool isLegacyViewportType() override; |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 405 , m_lastTimeUpdateEventMovieTime(0) | 406 , m_lastTimeUpdateEventMovieTime(0) |
| 406 , m_defaultPlaybackStartPosition(0) | 407 , m_defaultPlaybackStartPosition(0) |
| 407 , m_loadState(WaitingForSource) | 408 , m_loadState(WaitingForSource) |
| 408 , m_deferredLoadState(NotDeferred) | 409 , m_deferredLoadState(NotDeferred) |
| 409 , m_deferredLoadTimer(this, &HTMLMediaElement::deferredLoadTimerFired) | 410 , m_deferredLoadTimer(this, &HTMLMediaElement::deferredLoadTimerFired) |
| 410 , m_webLayer(nullptr) | 411 , m_webLayer(nullptr) |
| 411 , m_displayMode(Unknown) | 412 , m_displayMode(Unknown) |
| 412 , m_cachedTime(std::numeric_limits<double>::quiet_NaN()) | 413 , m_cachedTime(std::numeric_limits<double>::quiet_NaN()) |
| 413 , m_fragmentEndTime(std::numeric_limits<double>::quiet_NaN()) | 414 , m_fragmentEndTime(std::numeric_limits<double>::quiet_NaN()) |
| 414 , m_pendingActionFlags(0) | 415 , m_pendingActionFlags(0) |
| 415 , m_userGestureRequiredForPlay(false) | 416 , m_lockedPendingUserGesture(false) |
| 416 , m_playing(false) | 417 , m_playing(false) |
| 417 , m_shouldDelayLoadEvent(false) | 418 , m_shouldDelayLoadEvent(false) |
| 418 , m_haveFiredLoadedData(false) | 419 , m_haveFiredLoadedData(false) |
| 419 , m_autoplaying(true) | 420 , m_autoplaying(true) |
| 420 , m_muted(false) | 421 , m_muted(false) |
| 421 , m_paused(true) | 422 , m_paused(true) |
| 422 , m_seeking(false) | 423 , m_seeking(false) |
| 423 , m_sentStalledEvent(false) | 424 , m_sentStalledEvent(false) |
| 424 , m_ignorePreloadNone(false) | 425 , m_ignorePreloadNone(false) |
| 425 , m_textTracksVisible(false) | 426 , m_textTracksVisible(false) |
| (...skipping 14 matching lines...) Expand all Loading... |
| 440 , m_remotePlaybackClient(nullptr) | 441 , m_remotePlaybackClient(nullptr) |
| 441 { | 442 { |
| 442 ThreadState::current()->registerPreFinalizer(this); | 443 ThreadState::current()->registerPreFinalizer(this); |
| 443 | 444 |
| 444 WTF_LOG(Media, "HTMLMediaElement::HTMLMediaElement(%p)", this); | 445 WTF_LOG(Media, "HTMLMediaElement::HTMLMediaElement(%p)", this); |
| 445 | 446 |
| 446 // If any experiment is enabled, then we want to enable a user gesture by | 447 // If any experiment is enabled, then we want to enable a user gesture by |
| 447 // default, otherwise the experiment does nothing. | 448 // default, otherwise the experiment does nothing. |
| 448 if ((document.settings() && document.settings()->mediaPlaybackRequiresUserGe
sture()) | 449 if ((document.settings() && document.settings()->mediaPlaybackRequiresUserGe
sture()) |
| 449 || m_autoplayHelper->isExperimentEnabled()) { | 450 || m_autoplayHelper->isExperimentEnabled()) { |
| 450 m_userGestureRequiredForPlay = true; | 451 m_lockedPendingUserGesture = true; |
| 451 } | 452 } |
| 452 | 453 |
| 453 setHasCustomStyleCallbacks(); | 454 setHasCustomStyleCallbacks(); |
| 454 addElementToDocumentMap(this, &document); | 455 addElementToDocumentMap(this, &document); |
| 455 | 456 |
| 456 UseCounter::count(document, UseCounter::HTMLMediaElement); | 457 UseCounter::count(document, UseCounter::HTMLMediaElement); |
| 457 } | 458 } |
| 458 | 459 |
| 459 HTMLMediaElement::~HTMLMediaElement() | 460 HTMLMediaElement::~HTMLMediaElement() |
| 460 { | 461 { |
| (...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1006 updateVolume(); | 1007 updateVolume(); |
| 1007 | 1008 |
| 1008 ASSERT(!m_mediaSource); | 1009 ASSERT(!m_mediaSource); |
| 1009 | 1010 |
| 1010 bool attemptLoad = true; | 1011 bool attemptLoad = true; |
| 1011 | 1012 |
| 1012 bool isStreamOrBlobUrl = source.isMediaStream() || url.protocolIs(mediaSourc
eBlobProtocol); | 1013 bool isStreamOrBlobUrl = source.isMediaStream() || url.protocolIs(mediaSourc
eBlobProtocol); |
| 1013 if (isStreamOrBlobUrl) { | 1014 if (isStreamOrBlobUrl) { |
| 1014 bool isMediaStream = source.isMediaStream() || (source.isURL() && isMedi
aStreamURL(url.getString())); | 1015 bool isMediaStream = source.isMediaStream() || (source.isURL() && isMedi
aStreamURL(url.getString())); |
| 1015 if (isMediaStream) { | 1016 if (isMediaStream) { |
| 1016 m_autoplayHelper->removeUserGestureRequirement(GesturelessPlaybackEn
abledByStream); | 1017 m_autoplayHelper->unlockUserGesture(GesturelessPlaybackEnabledByStre
am); |
| 1017 } else { | 1018 } else { |
| 1018 m_mediaSource = HTMLMediaSource::lookup(url.getString()); | 1019 m_mediaSource = HTMLMediaSource::lookup(url.getString()); |
| 1019 | 1020 |
| 1020 if (m_mediaSource) { | 1021 if (m_mediaSource) { |
| 1021 if (!m_mediaSource->attachToElement(this)) { | 1022 if (!m_mediaSource->attachToElement(this)) { |
| 1022 // Forget our reference to the MediaSource, so we leave it a
lone | 1023 // Forget our reference to the MediaSource, so we leave it a
lone |
| 1023 // while processing remainder of load failure. | 1024 // while processing remainder of load failure. |
| 1024 m_mediaSource = nullptr; | 1025 m_mediaSource = nullptr; |
| 1025 attemptLoad = false; | 1026 attemptLoad = false; |
| 1026 } | 1027 } |
| (...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1613 if (isPotentiallyPlaying) | 1614 if (isPotentiallyPlaying) |
| 1614 scheduleNotifyPlaying(); | 1615 scheduleNotifyPlaying(); |
| 1615 } | 1616 } |
| 1616 | 1617 |
| 1617 // Check for autoplay, and record metrics about it if needed. | 1618 // Check for autoplay, and record metrics about it if needed. |
| 1618 if (shouldAutoplay(RecordMetricsBehavior::DoRecord)) { | 1619 if (shouldAutoplay(RecordMetricsBehavior::DoRecord)) { |
| 1619 // If the autoplay experiment says that it's okay to play now, | 1620 // If the autoplay experiment says that it's okay to play now, |
| 1620 // then don't require a user gesture. | 1621 // then don't require a user gesture. |
| 1621 m_autoplayHelper->becameReadyToPlay(); | 1622 m_autoplayHelper->becameReadyToPlay(); |
| 1622 | 1623 |
| 1623 if (!m_userGestureRequiredForPlay) { | 1624 if (!isGestureNeededForPlayback()) { |
| 1624 m_paused = false; | 1625 m_paused = false; |
| 1625 invalidateCachedTime(); | 1626 invalidateCachedTime(); |
| 1626 scheduleEvent(EventTypeNames::play); | 1627 scheduleEvent(EventTypeNames::play); |
| 1627 scheduleNotifyPlaying(); | 1628 scheduleNotifyPlaying(); |
| 1628 m_autoplaying = false; | 1629 m_autoplaying = false; |
| 1629 } | 1630 } |
| 1630 } | 1631 } |
| 1631 | 1632 |
| 1632 scheduleEvent(EventTypeNames::canplaythrough); | 1633 scheduleEvent(EventTypeNames::canplaythrough); |
| 1633 | 1634 |
| (...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2039 return promise; | 2040 return promise; |
| 2040 } | 2041 } |
| 2041 | 2042 |
| 2042 Nullable<ExceptionCode> HTMLMediaElement::play() | 2043 Nullable<ExceptionCode> HTMLMediaElement::play() |
| 2043 { | 2044 { |
| 2044 WTF_LOG(Media, "HTMLMediaElement::play(%p)", this); | 2045 WTF_LOG(Media, "HTMLMediaElement::play(%p)", this); |
| 2045 | 2046 |
| 2046 m_autoplayHelper->playMethodCalled(); | 2047 m_autoplayHelper->playMethodCalled(); |
| 2047 | 2048 |
| 2048 if (!UserGestureIndicator::processingUserGesture()) { | 2049 if (!UserGestureIndicator::processingUserGesture()) { |
| 2049 if (m_userGestureRequiredForPlay) { | 2050 if (isGestureNeededForPlayback()) { |
| 2051 // If playback is deferred, then don't start playback but don't |
| 2052 // fail yet either. |
| 2053 if (m_autoplayHelper->isPlaybackDeferred()) |
| 2054 return nullptr; |
| 2055 |
| 2056 // If we're already playing, then this play would do nothing anyway. |
| 2057 // Call playInternal to handle scheduling the promise resolution. |
| 2058 if (!m_paused) { |
| 2059 playInternal(); |
| 2060 return nullptr; |
| 2061 } |
| 2062 |
| 2050 recordAutoplayMetric(PlayMethodFailed); | 2063 recordAutoplayMetric(PlayMethodFailed); |
| 2051 String message = ExceptionMessages::failedToExecute("play", "HTMLMed
iaElement", "API can only be initiated by a user gesture."); | 2064 String message = ExceptionMessages::failedToExecute("play", "HTMLMed
iaElement", "API can only be initiated by a user gesture."); |
| 2052 document().addConsoleMessage(ConsoleMessage::create(JSMessageSource,
WarningMessageLevel, message)); | 2065 document().addConsoleMessage(ConsoleMessage::create(JSMessageSource,
WarningMessageLevel, message)); |
| 2053 return NotAllowedError; | 2066 return NotAllowedError; |
| 2054 } | 2067 } |
| 2055 } else { | 2068 } else { |
| 2056 UserGestureIndicator::utilizeUserGesture(); | 2069 UserGestureIndicator::utilizeUserGesture(); |
| 2057 // We ask the helper to remove the gesture requirement for us, so that | 2070 // We ask the helper to remove the gesture requirement for us, so that |
| 2058 // it can record the reason. | 2071 // it can record the reason. |
| 2059 Platform::current()->recordAction(UserMetricsAction("Media_Play_WithGest
ure")); | 2072 Platform::current()->recordAction(UserMetricsAction("Media_Play_WithGest
ure")); |
| 2060 m_autoplayHelper->removeUserGestureRequirement(GesturelessPlaybackEnable
dByPlayMethod); | 2073 m_autoplayHelper->unlockUserGesture(GesturelessPlaybackEnabledByPlayMeth
od); |
| 2061 } | 2074 } |
| 2062 | 2075 |
| 2063 if (m_error && m_error->code() == MediaError::MEDIA_ERR_SRC_NOT_SUPPORTED) | 2076 if (m_error && m_error->code() == MediaError::MEDIA_ERR_SRC_NOT_SUPPORTED) |
| 2064 return NotSupportedError; | 2077 return NotSupportedError; |
| 2065 | 2078 |
| 2066 playInternal(); | 2079 playInternal(); |
| 2067 | 2080 |
| 2068 return nullptr; | 2081 return nullptr; |
| 2069 } | 2082 } |
| 2070 | 2083 |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2233 | 2246 |
| 2234 void HTMLMediaElement::setMuted(bool muted) | 2247 void HTMLMediaElement::setMuted(bool muted) |
| 2235 { | 2248 { |
| 2236 WTF_LOG(Media, "HTMLMediaElement::setMuted(%p, %s)", this, boolString(muted)
); | 2249 WTF_LOG(Media, "HTMLMediaElement::setMuted(%p, %s)", this, boolString(muted)
); |
| 2237 | 2250 |
| 2238 if (m_muted == muted) | 2251 if (m_muted == muted) |
| 2239 return; | 2252 return; |
| 2240 | 2253 |
| 2241 m_muted = muted; | 2254 m_muted = muted; |
| 2242 | 2255 |
| 2243 m_autoplayHelper->mutedChanged(); | |
| 2244 | |
| 2245 updateVolume(); | 2256 updateVolume(); |
| 2246 | 2257 |
| 2247 if (muted) | 2258 if (muted) |
| 2248 Platform::current()->recordAction(UserMetricsAction("Media_Playback_Mute
_On")); | 2259 Platform::current()->recordAction(UserMetricsAction("Media_Playback_Mute
_On")); |
| 2249 else | 2260 else |
| 2250 Platform::current()->recordAction(UserMetricsAction("Media_Playback_Mute
_Off")); | 2261 Platform::current()->recordAction(UserMetricsAction("Media_Playback_Mute
_Off")); |
| 2251 | 2262 |
| 2252 scheduleEvent(EventTypeNames::volumechange); | 2263 scheduleEvent(EventTypeNames::volumechange); |
| 2253 } | 2264 } |
| 2254 | 2265 |
| (...skipping 1389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3644 | 3655 |
| 3645 // Enable the first audio track if an audio track hasn't been enabled yet. | 3656 // Enable the first audio track if an audio track hasn't been enabled yet. |
| 3646 if (audioTracks().length() > 0 && !audioTracks().hasEnabledTrack()) | 3657 if (audioTracks().length() > 0 && !audioTracks().hasEnabledTrack()) |
| 3647 audioTracks().anonymousIndexedGetter(0)->setEnabled(true); | 3658 audioTracks().anonymousIndexedGetter(0)->setEnabled(true); |
| 3648 | 3659 |
| 3649 // Select the first video track if a video track hasn't been selected yet. | 3660 // Select the first video track if a video track hasn't been selected yet. |
| 3650 if (videoTracks().length() > 0 && videoTracks().selectedIndex() == -1) | 3661 if (videoTracks().length() > 0 && videoTracks().selectedIndex() == -1) |
| 3651 videoTracks().anonymousIndexedGetter(0)->setSelected(true); | 3662 videoTracks().anonymousIndexedGetter(0)->setSelected(true); |
| 3652 } | 3663 } |
| 3653 | 3664 |
| 3654 bool HTMLMediaElement::isUserGestureRequiredForPlay() const | 3665 bool HTMLMediaElement::isLockedPendingUserGesture() const |
| 3655 { | 3666 { |
| 3656 return m_userGestureRequiredForPlay; | 3667 return m_lockedPendingUserGesture; |
| 3657 } | 3668 } |
| 3658 | 3669 |
| 3659 void HTMLMediaElement::removeUserGestureRequirement() | 3670 void HTMLMediaElement::unlockUserGesture() |
| 3660 { | 3671 { |
| 3661 m_userGestureRequiredForPlay = false; | 3672 m_lockedPendingUserGesture = false; |
| 3673 } |
| 3674 |
| 3675 bool HTMLMediaElement::isGestureNeededForPlayback() const |
| 3676 { |
| 3677 return m_lockedPendingUserGesture |
| 3678 && !m_autoplayHelper->isGestureRequirementOverridden(); |
| 3662 } | 3679 } |
| 3663 | 3680 |
| 3664 void HTMLMediaElement::setNetworkState(NetworkState state) | 3681 void HTMLMediaElement::setNetworkState(NetworkState state) |
| 3665 { | 3682 { |
| 3666 if (m_networkState != state) { | 3683 if (m_networkState != state) { |
| 3667 m_networkState = state; | 3684 m_networkState = state; |
| 3668 if (MediaControls* controls = mediaControls()) | 3685 if (MediaControls* controls = mediaControls()) |
| 3669 controls->networkStateChanged(); | 3686 controls->networkStateChanged(); |
| 3670 } | 3687 } |
| 3671 } | 3688 } |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3866 | 3883 |
| 3867 IntRect HTMLMediaElement::AutoplayHelperClientImpl::absoluteBoundingBoxRect() co
nst | 3884 IntRect HTMLMediaElement::AutoplayHelperClientImpl::absoluteBoundingBoxRect() co
nst |
| 3868 { | 3885 { |
| 3869 IntRect result; | 3886 IntRect result; |
| 3870 if (LayoutObject* object = m_element->layoutObject()) | 3887 if (LayoutObject* object = m_element->layoutObject()) |
| 3871 result = object->absoluteBoundingBoxRect(); | 3888 result = object->absoluteBoundingBoxRect(); |
| 3872 return result; | 3889 return result; |
| 3873 } | 3890 } |
| 3874 | 3891 |
| 3875 } // namespace blink | 3892 } // namespace blink |
| OLD | NEW |