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 11 matching lines...) Expand all Loading... | |
| 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 24 */ | 24 */ |
| 25 | 25 |
| 26 #include "core/html/HTMLMediaElement.h" | 26 #include "core/html/HTMLMediaElement.h" |
| 27 | 27 |
| 28 #include "bindings/core/v8/ExceptionState.h" | 28 #include "bindings/core/v8/ExceptionState.h" |
| 29 #include "bindings/core/v8/ExceptionStatePlaceholder.h" | 29 #include "bindings/core/v8/ExceptionStatePlaceholder.h" |
| 30 #include "bindings/core/v8/ScriptController.h" | 30 #include "bindings/core/v8/ScriptController.h" |
| 31 #include "bindings/core/v8/ScriptEventListener.h" | 31 #include "bindings/core/v8/ScriptEventListener.h" |
| 32 #include "bindings/core/v8/ScriptPromiseResolver.h" | |
| 32 #include "core/HTMLNames.h" | 33 #include "core/HTMLNames.h" |
| 33 #include "core/css/MediaList.h" | 34 #include "core/css/MediaList.h" |
| 34 #include "core/dom/Attribute.h" | 35 #include "core/dom/Attribute.h" |
| 35 #include "core/dom/ElementTraversal.h" | 36 #include "core/dom/ElementTraversal.h" |
| 36 #include "core/dom/ExceptionCode.h" | |
| 37 #include "core/dom/Fullscreen.h" | 37 #include "core/dom/Fullscreen.h" |
| 38 #include "core/dom/shadow/ShadowRoot.h" | 38 #include "core/dom/shadow/ShadowRoot.h" |
| 39 #include "core/events/Event.h" | 39 #include "core/events/Event.h" |
| 40 #include "core/frame/LocalFrame.h" | 40 #include "core/frame/LocalFrame.h" |
| 41 #include "core/frame/Settings.h" | 41 #include "core/frame/Settings.h" |
| 42 #include "core/frame/UseCounter.h" | 42 #include "core/frame/UseCounter.h" |
| 43 #include "core/frame/csp/ContentSecurityPolicy.h" | 43 #include "core/frame/csp/ContentSecurityPolicy.h" |
| 44 #include "core/html/HTMLMediaSource.h" | 44 #include "core/html/HTMLMediaSource.h" |
| 45 #include "core/html/HTMLSourceElement.h" | 45 #include "core/html/HTMLSourceElement.h" |
| 46 #include "core/html/HTMLTrackElement.h" | 46 #include "core/html/HTMLTrackElement.h" |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 332 , m_processingPreferenceChange(false) | 332 , m_processingPreferenceChange(false) |
| 333 , m_remoteRoutesAvailable(false) | 333 , m_remoteRoutesAvailable(false) |
| 334 , m_playingRemotely(false) | 334 , m_playingRemotely(false) |
| 335 , m_isFinalizing(false) | 335 , m_isFinalizing(false) |
| 336 , m_initialPlayWithoutUserGesture(false) | 336 , m_initialPlayWithoutUserGesture(false) |
| 337 , m_autoplayMediaCounted(false) | 337 , m_autoplayMediaCounted(false) |
| 338 , m_inOverlayFullscreenVideo(false) | 338 , m_inOverlayFullscreenVideo(false) |
| 339 , m_audioTracks(AudioTrackList::create(*this)) | 339 , m_audioTracks(AudioTrackList::create(*this)) |
| 340 , m_videoTracks(VideoTrackList::create(*this)) | 340 , m_videoTracks(VideoTrackList::create(*this)) |
| 341 , m_textTracks(nullptr) | 341 , m_textTracks(nullptr) |
| 342 , m_playPromiseResolveTask(CancellableTaskFactory::create(this, &HTMLMediaEl ement::resolvePlayPromises)) | |
| 343 , m_playPromiseRejectTask(CancellableTaskFactory::create(this, &HTMLMediaEle ment::rejectPlayPromises)) | |
| 342 , m_audioSourceNode(nullptr) | 344 , m_audioSourceNode(nullptr) |
| 343 , m_autoplayHelper(*this) | 345 , m_autoplayHelper(*this) |
| 344 { | 346 { |
| 345 #if ENABLE(OILPAN) | 347 #if ENABLE(OILPAN) |
| 346 ThreadState::current()->registerPreFinalizer(this); | 348 ThreadState::current()->registerPreFinalizer(this); |
| 347 #endif | 349 #endif |
| 348 ASSERT(RuntimeEnabledFeatures::mediaEnabled()); | 350 ASSERT(RuntimeEnabledFeatures::mediaEnabled()); |
| 349 | 351 |
| 350 WTF_LOG(Media, "HTMLMediaElement::HTMLMediaElement(%p)", this); | 352 WTF_LOG(Media, "HTMLMediaElement::HTMLMediaElement(%p)", this); |
| 351 | 353 |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 431 // is-finalizing state, which is explicitly checked for if the | 433 // is-finalizing state, which is explicitly checked for if the |
| 432 // player tries to access the media element during shutdown. | 434 // player tries to access the media element during shutdown. |
| 433 // | 435 // |
| 434 // FIXME: Oilpan: move the media player to the heap instead and | 436 // FIXME: Oilpan: move the media player to the heap instead and |
| 435 // avoid having to finalize it from here; this whole #if block | 437 // avoid having to finalize it from here; this whole #if block |
| 436 // could then be removed (along with the state bit it depends on.) | 438 // could then be removed (along with the state bit it depends on.) |
| 437 // crbug.com/378229 | 439 // crbug.com/378229 |
| 438 m_isFinalizing = true; | 440 m_isFinalizing = true; |
| 439 | 441 |
| 440 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking(); | 442 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking(); |
| 443 | |
| 444 m_playPromiseResolveTask->cancel(); | |
|
philipj_slow
2016/02/25 14:06:48
Are you sure that this is needed? I see no other c
mlamouri (slow - plz ping)
2016/02/25 14:40:06
It's used by FrameView::dispose(). Though, I'm not
| |
| 445 m_playPromiseRejectTask->cancel(); | |
| 441 } | 446 } |
| 442 #endif | 447 #endif |
| 443 | 448 |
| 444 void HTMLMediaElement::didMoveToNewDocument(Document& oldDocument) | 449 void HTMLMediaElement::didMoveToNewDocument(Document& oldDocument) |
| 445 { | 450 { |
| 446 WTF_LOG(Media, "HTMLMediaElement::didMoveToNewDocument(%p)", this); | 451 WTF_LOG(Media, "HTMLMediaElement::didMoveToNewDocument(%p)", this); |
| 447 | 452 |
| 448 if (m_shouldDelayLoadEvent) { | 453 if (m_shouldDelayLoadEvent) { |
| 449 document().incrementLoadEventDelayCount(); | 454 document().incrementLoadEventDelayCount(); |
| 450 // Note: Keeping the load event delay count increment on oldDocument tha t was added | 455 // Note: Keeping the load event delay count increment on oldDocument tha t was added |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 726 m_displayMode = Unknown; | 731 m_displayMode = Unknown; |
| 727 | 732 |
| 728 // 1 - Abort any already-running instance of the resource selection algorith m for this element. | 733 // 1 - Abort any already-running instance of the resource selection algorith m for this element. |
| 729 m_loadState = WaitingForSource; | 734 m_loadState = WaitingForSource; |
| 730 m_currentSourceNode = nullptr; | 735 m_currentSourceNode = nullptr; |
| 731 | 736 |
| 732 // 2 - If there are any tasks from the media element's media element event t ask source in | 737 // 2 - If there are any tasks from the media element's media element event t ask source in |
| 733 // one of the task queues, then remove those tasks. | 738 // one of the task queues, then remove those tasks. |
| 734 cancelPendingEventsAndCallbacks(); | 739 cancelPendingEventsAndCallbacks(); |
| 735 | 740 |
| 741 rejectPlayPromises(AbortError, "The play() request was interrupted by a new load request."); | |
| 742 | |
| 736 // 3 - If the media element's networkState is set to NETWORK_LOADING or NETW ORK_IDLE, queue | 743 // 3 - If the media element's networkState is set to NETWORK_LOADING or NETW ORK_IDLE, queue |
| 737 // a task to fire a simple event named abort at the media element. | 744 // a task to fire a simple event named abort at the media element. |
| 738 if (m_networkState == NETWORK_LOADING || m_networkState == NETWORK_IDLE) | 745 if (m_networkState == NETWORK_LOADING || m_networkState == NETWORK_IDLE) |
| 739 scheduleEvent(EventTypeNames::abort); | 746 scheduleEvent(EventTypeNames::abort); |
| 740 | 747 |
| 741 resetMediaPlayerAndMediaSource(); | 748 resetMediaPlayerAndMediaSource(); |
| 742 | 749 |
| 743 // 4 - If the media element's networkState is not set to NETWORK_EMPTY, then run these substeps | 750 // 4 - If the media element's networkState is not set to NETWORK_EMPTY, then run these substeps |
| 744 if (m_networkState != NETWORK_EMPTY) { | 751 if (m_networkState != NETWORK_EMPTY) { |
| 745 // 4.1 - Queue a task to fire a simple event named emptied at the media element. | 752 // 4.1 - Queue a task to fire a simple event named emptied at the media element. |
| (...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1238 } | 1245 } |
| 1239 | 1246 |
| 1240 void HTMLMediaElement::noneSupported() | 1247 void HTMLMediaElement::noneSupported() |
| 1241 { | 1248 { |
| 1242 WTF_LOG(Media, "HTMLMediaElement::noneSupported(%p)", this); | 1249 WTF_LOG(Media, "HTMLMediaElement::noneSupported(%p)", this); |
| 1243 | 1250 |
| 1244 stopPeriodicTimers(); | 1251 stopPeriodicTimers(); |
| 1245 m_loadState = WaitingForSource; | 1252 m_loadState = WaitingForSource; |
| 1246 m_currentSourceNode = nullptr; | 1253 m_currentSourceNode = nullptr; |
| 1247 | 1254 |
| 1248 // 4.8.10.5 | 1255 // 4.8.13.5 |
| 1249 // 6 - Reaching this step indicates that the media resource failed to load o r that the given | 1256 // The dedicated media source failure steps are the following steps: |
| 1250 // URL could not be resolved. In one atomic operation, run the following ste ps: | |
| 1251 | 1257 |
| 1252 // 6.1 - Set the error attribute to a new MediaError object whose code attri bute is set to | 1258 // 1 - Set the error attribute to a new MediaError object whose code attribu te is set to |
| 1253 // MEDIA_ERR_SRC_NOT_SUPPORTED. | 1259 // MEDIA_ERR_SRC_NOT_SUPPORTED. |
| 1254 m_error = MediaError::create(MediaError::MEDIA_ERR_SRC_NOT_SUPPORTED); | 1260 m_error = MediaError::create(MediaError::MEDIA_ERR_SRC_NOT_SUPPORTED); |
| 1255 | 1261 |
| 1256 // 6.2 - Forget the media element's media-resource-specific text tracks. | 1262 // 2 - Forget the media element's media-resource-specific text tracks. |
| 1257 forgetResourceSpecificTracks(); | 1263 forgetResourceSpecificTracks(); |
| 1258 | 1264 |
| 1259 // 6.3 - Set the element's networkState attribute to the NETWORK_NO_SOURCE v alue. | 1265 // 3 - Set the element's networkState attribute to the NETWORK_NO_SOURCE val ue. |
| 1260 setNetworkState(NETWORK_NO_SOURCE); | 1266 setNetworkState(NETWORK_NO_SOURCE); |
| 1261 | 1267 |
| 1262 // 7 - Queue a task to fire a simple event named error at the media element. | 1268 // 4 - Set the element's show poster flag to true. |
| 1269 updateDisplayState(); | |
| 1270 | |
| 1271 // 5 - Fire a simple event named error at the media element. | |
| 1263 scheduleEvent(EventTypeNames::error); | 1272 scheduleEvent(EventTypeNames::error); |
| 1264 | 1273 |
| 1274 // 6 - Reject pending play promises with NotSupportedError. | |
| 1275 scheduleRejectPlayPromises(NotSupportedError); | |
| 1276 | |
| 1265 closeMediaSource(); | 1277 closeMediaSource(); |
| 1266 | 1278 |
| 1267 // 8 - Set the element's delaying-the-load-event flag to false. This stops d elaying the load event. | 1279 // 7 - Set the element's delaying-the-load-event flag to false. This stops d elaying the load event. |
| 1268 setShouldDelayLoadEvent(false); | 1280 setShouldDelayLoadEvent(false); |
| 1269 | 1281 |
| 1270 // 9 - Abort these steps. Until the load() method is invoked or the src attr ibute is changed, | |
| 1271 // the element won't attempt to load another resource. | |
| 1272 | |
| 1273 updateDisplayState(); | |
| 1274 | |
| 1275 if (layoutObject()) | 1282 if (layoutObject()) |
| 1276 layoutObject()->updateFromElement(); | 1283 layoutObject()->updateFromElement(); |
| 1277 } | 1284 } |
| 1278 | 1285 |
| 1279 void HTMLMediaElement::mediaEngineError(MediaError* err) | 1286 void HTMLMediaElement::mediaEngineError(MediaError* err) |
| 1280 { | 1287 { |
| 1281 ASSERT(m_readyState >= HAVE_METADATA); | 1288 ASSERT(m_readyState >= HAVE_METADATA); |
| 1282 WTF_LOG(Media, "HTMLMediaElement::mediaEngineError(%p, %d)", this, static_ca st<int>(err->code())); | 1289 WTF_LOG(Media, "HTMLMediaElement::mediaEngineError(%p, %d)", this, static_ca st<int>(err->code())); |
| 1283 | 1290 |
| 1284 // 1 - The user agent should cancel the fetching process. | 1291 // 1 - The user agent should cancel the fetching process. |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 1302 m_currentSourceNode = nullptr; | 1309 m_currentSourceNode = nullptr; |
| 1303 } | 1310 } |
| 1304 | 1311 |
| 1305 void HTMLMediaElement::cancelPendingEventsAndCallbacks() | 1312 void HTMLMediaElement::cancelPendingEventsAndCallbacks() |
| 1306 { | 1313 { |
| 1307 WTF_LOG(Media, "HTMLMediaElement::cancelPendingEventsAndCallbacks(%p)", this ); | 1314 WTF_LOG(Media, "HTMLMediaElement::cancelPendingEventsAndCallbacks(%p)", this ); |
| 1308 m_asyncEventQueue->cancelAllEvents(); | 1315 m_asyncEventQueue->cancelAllEvents(); |
| 1309 | 1316 |
| 1310 for (HTMLSourceElement* source = Traversal<HTMLSourceElement>::firstChild(*t his); source; source = Traversal<HTMLSourceElement>::nextSibling(*source)) | 1317 for (HTMLSourceElement* source = Traversal<HTMLSourceElement>::firstChild(*t his); source; source = Traversal<HTMLSourceElement>::nextSibling(*source)) |
| 1311 source->cancelPendingErrorEvent(); | 1318 source->cancelPendingErrorEvent(); |
| 1319 | |
| 1320 m_playPromiseResolveTask->cancel(); | |
| 1321 m_playPromiseRejectTask->cancel(); | |
| 1312 } | 1322 } |
| 1313 | 1323 |
| 1314 void HTMLMediaElement::networkStateChanged() | 1324 void HTMLMediaElement::networkStateChanged() |
| 1315 { | 1325 { |
| 1316 setNetworkState(webMediaPlayer()->networkState()); | 1326 setNetworkState(webMediaPlayer()->networkState()); |
| 1317 } | 1327 } |
| 1318 | 1328 |
| 1319 void HTMLMediaElement::mediaLoadingFailed(WebMediaPlayer::NetworkState error) | 1329 void HTMLMediaElement::mediaLoadingFailed(WebMediaPlayer::NetworkState error) |
| 1320 { | 1330 { |
| 1321 stopPeriodicTimers(); | 1331 stopPeriodicTimers(); |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1513 m_haveFiredLoadedData = true; | 1523 m_haveFiredLoadedData = true; |
| 1514 shouldUpdateDisplayState = true; | 1524 shouldUpdateDisplayState = true; |
| 1515 scheduleEvent(EventTypeNames::loadeddata); | 1525 scheduleEvent(EventTypeNames::loadeddata); |
| 1516 setShouldDelayLoadEvent(false); | 1526 setShouldDelayLoadEvent(false); |
| 1517 } | 1527 } |
| 1518 | 1528 |
| 1519 bool isPotentiallyPlaying = potentiallyPlaying(); | 1529 bool isPotentiallyPlaying = potentiallyPlaying(); |
| 1520 if (m_readyState == HAVE_FUTURE_DATA && oldState <= HAVE_CURRENT_DATA && tra cksAreReady) { | 1530 if (m_readyState == HAVE_FUTURE_DATA && oldState <= HAVE_CURRENT_DATA && tra cksAreReady) { |
| 1521 scheduleEvent(EventTypeNames::canplay); | 1531 scheduleEvent(EventTypeNames::canplay); |
| 1522 if (isPotentiallyPlaying) | 1532 if (isPotentiallyPlaying) |
| 1523 scheduleEvent(EventTypeNames::playing); | 1533 scheduleNotifyPlaying(); |
| 1524 shouldUpdateDisplayState = true; | 1534 shouldUpdateDisplayState = true; |
| 1525 } | 1535 } |
| 1526 | 1536 |
| 1527 if (m_readyState == HAVE_ENOUGH_DATA && oldState < HAVE_ENOUGH_DATA && track sAreReady) { | 1537 if (m_readyState == HAVE_ENOUGH_DATA && oldState < HAVE_ENOUGH_DATA && track sAreReady) { |
| 1528 if (oldState <= HAVE_CURRENT_DATA) { | 1538 if (oldState <= HAVE_CURRENT_DATA) { |
| 1529 scheduleEvent(EventTypeNames::canplay); | 1539 scheduleEvent(EventTypeNames::canplay); |
| 1530 if (isPotentiallyPlaying) | 1540 if (isPotentiallyPlaying) |
| 1531 scheduleEvent(EventTypeNames::playing); | 1541 scheduleNotifyPlaying(); |
| 1532 } | 1542 } |
| 1533 | 1543 |
| 1534 // Check for autoplay, and record metrics about it if needed. | 1544 // Check for autoplay, and record metrics about it if needed. |
| 1535 if (shouldAutoplay(RecordMetricsBehavior::DoRecord)) { | 1545 if (shouldAutoplay(RecordMetricsBehavior::DoRecord)) { |
| 1536 // If the autoplay experiment says that it's okay to play now, | 1546 // If the autoplay experiment says that it's okay to play now, |
| 1537 // then don't require a user gesture. | 1547 // then don't require a user gesture. |
| 1538 m_autoplayHelper.becameReadyToPlay(); | 1548 m_autoplayHelper.becameReadyToPlay(); |
| 1539 | 1549 |
| 1540 if (!m_userGestureRequiredForPlay) { | 1550 if (!m_userGestureRequiredForPlay) { |
| 1541 m_paused = false; | 1551 m_paused = false; |
| 1542 invalidateCachedTime(); | 1552 invalidateCachedTime(); |
| 1543 scheduleEvent(EventTypeNames::play); | 1553 scheduleEvent(EventTypeNames::play); |
| 1544 scheduleEvent(EventTypeNames::playing); | 1554 scheduleNotifyPlaying(); |
| 1545 m_autoplaying = false; | 1555 m_autoplaying = false; |
| 1546 } | 1556 } |
| 1547 } | 1557 } |
| 1548 | 1558 |
| 1549 scheduleEvent(EventTypeNames::canplaythrough); | 1559 scheduleEvent(EventTypeNames::canplaythrough); |
| 1550 | 1560 |
| 1551 shouldUpdateDisplayState = true; | 1561 shouldUpdateDisplayState = true; |
| 1552 } | 1562 } |
| 1553 | 1563 |
| 1554 if (shouldUpdateDisplayState) { | 1564 if (shouldUpdateDisplayState) { |
| (...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1926 // https://crbug.com/310450 | 1936 // https://crbug.com/310450 |
| 1927 UseCounter::count(document(), UseCounter::HTMLMediaElementPreloadDefault); | 1937 UseCounter::count(document(), UseCounter::HTMLMediaElementPreloadDefault); |
| 1928 return WebMediaPlayer::PreloadAuto; | 1938 return WebMediaPlayer::PreloadAuto; |
| 1929 } | 1939 } |
| 1930 | 1940 |
| 1931 WebMediaPlayer::Preload HTMLMediaElement::effectivePreloadType() const | 1941 WebMediaPlayer::Preload HTMLMediaElement::effectivePreloadType() const |
| 1932 { | 1942 { |
| 1933 return autoplay() ? WebMediaPlayer::PreloadAuto : preloadType(); | 1943 return autoplay() ? WebMediaPlayer::PreloadAuto : preloadType(); |
| 1934 } | 1944 } |
| 1935 | 1945 |
| 1936 void HTMLMediaElement::play() | 1946 ScriptPromise HTMLMediaElement::playForBindings(ScriptState* scriptState) |
| 1947 { | |
| 1948 Nullable<ExceptionCode> code = play(); | |
| 1949 if (!code.isNull()) { | |
| 1950 String message; | |
| 1951 switch (code.get()) { | |
| 1952 case NotAllowedError: | |
| 1953 message = "play() can only be initiated by a user gesture."; | |
| 1954 break; | |
| 1955 case NotSupportedError: | |
| 1956 message = "The element has no supported sources."; | |
| 1957 break; | |
| 1958 default: | |
| 1959 ASSERT_NOT_REACHED(); | |
| 1960 } | |
| 1961 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(code.get(), message)); | |
| 1962 } | |
| 1963 | |
| 1964 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; | |
| 1965 ScriptPromise promise = resolver->promise(); | |
| 1966 | |
| 1967 m_playResolvers.append(resolver); | |
| 1968 return promise; | |
| 1969 } | |
| 1970 | |
| 1971 Nullable<ExceptionCode> HTMLMediaElement::play() | |
| 1937 { | 1972 { |
| 1938 WTF_LOG(Media, "HTMLMediaElement::play(%p)", this); | 1973 WTF_LOG(Media, "HTMLMediaElement::play(%p)", this); |
| 1939 | 1974 |
| 1940 m_autoplayHelper.playMethodCalled(); | 1975 m_autoplayHelper.playMethodCalled(); |
| 1941 | 1976 |
| 1942 if (!UserGestureIndicator::processingUserGesture()) { | 1977 if (!UserGestureIndicator::processingUserGesture()) { |
| 1943 autoplayMediaEncountered(); | 1978 autoplayMediaEncountered(); |
| 1944 | 1979 |
| 1945 if (m_userGestureRequiredForPlay) { | 1980 if (m_userGestureRequiredForPlay) { |
| 1946 recordAutoplayMetric(PlayMethodFailed); | 1981 recordAutoplayMetric(PlayMethodFailed); |
| 1947 String message = ExceptionMessages::failedToExecute("play", "HTMLMed iaElement", "API can only be initiated by a user gesture."); | 1982 String message = ExceptionMessages::failedToExecute("play", "HTMLMed iaElement", "API can only be initiated by a user gesture."); |
| 1948 document().addConsoleMessage(ConsoleMessage::create(JSMessageSource, WarningMessageLevel, message)); | 1983 document().addConsoleMessage(ConsoleMessage::create(JSMessageSource, WarningMessageLevel, message)); |
| 1949 return; | 1984 return NotAllowedError; |
| 1950 } | 1985 } |
| 1951 } else if (m_userGestureRequiredForPlay) { | 1986 } else if (m_userGestureRequiredForPlay) { |
| 1952 if (m_autoplayMediaCounted) | 1987 if (m_autoplayMediaCounted) |
| 1953 recordAutoplayMetric(AutoplayManualStart); | 1988 recordAutoplayMetric(AutoplayManualStart); |
| 1954 m_userGestureRequiredForPlay = false; | 1989 m_userGestureRequiredForPlay = false; |
| 1955 } | 1990 } |
| 1956 | 1991 |
| 1992 if (m_error && m_error->code() == MediaError::MEDIA_ERR_SRC_NOT_SUPPORTED) | |
| 1993 return NotSupportedError; | |
| 1994 | |
| 1957 playInternal(); | 1995 playInternal(); |
| 1996 | |
| 1997 return nullptr; | |
| 1958 } | 1998 } |
| 1959 | 1999 |
| 1960 void HTMLMediaElement::playInternal() | 2000 void HTMLMediaElement::playInternal() |
| 1961 { | 2001 { |
| 1962 WTF_LOG(Media, "HTMLMediaElement::playInternal(%p)", this); | 2002 WTF_LOG(Media, "HTMLMediaElement::playInternal(%p)", this); |
| 1963 | 2003 |
| 1964 // Always return the buffering strategy to normal when not paused, | 2004 // Always return the buffering strategy to normal when not paused, |
| 1965 // regardless of the cause. (In contrast with aggressive buffering which is | 2005 // regardless of the cause. (In contrast with aggressive buffering which is |
| 1966 // only enabled by pause(), not pauseInternal().) | 2006 // only enabled by pause(), not pauseInternal().) |
| 1967 if (webMediaPlayer()) | 2007 if (webMediaPlayer()) |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 1978 seek(0); | 2018 seek(0); |
| 1979 | 2019 |
| 1980 if (m_paused) { | 2020 if (m_paused) { |
| 1981 m_paused = false; | 2021 m_paused = false; |
| 1982 invalidateCachedTime(); | 2022 invalidateCachedTime(); |
| 1983 scheduleEvent(EventTypeNames::play); | 2023 scheduleEvent(EventTypeNames::play); |
| 1984 | 2024 |
| 1985 if (m_readyState <= HAVE_CURRENT_DATA) | 2025 if (m_readyState <= HAVE_CURRENT_DATA) |
| 1986 scheduleEvent(EventTypeNames::waiting); | 2026 scheduleEvent(EventTypeNames::waiting); |
| 1987 else if (m_readyState >= HAVE_FUTURE_DATA) | 2027 else if (m_readyState >= HAVE_FUTURE_DATA) |
| 1988 scheduleEvent(EventTypeNames::playing); | 2028 scheduleNotifyPlaying(); |
| 2029 } else if (m_readyState >= HAVE_FUTURE_DATA) { | |
| 2030 scheduleResolvePlayPromises(); | |
| 1989 } | 2031 } |
| 2032 | |
| 1990 m_autoplaying = false; | 2033 m_autoplaying = false; |
| 1991 | 2034 |
| 1992 updatePlayState(); | 2035 updatePlayState(); |
| 1993 } | 2036 } |
| 1994 | 2037 |
| 1995 void HTMLMediaElement::autoplayMediaEncountered() | 2038 void HTMLMediaElement::autoplayMediaEncountered() |
| 1996 { | 2039 { |
| 1997 if (!m_autoplayMediaCounted) { | 2040 if (!m_autoplayMediaCounted) { |
| 1998 m_autoplayMediaCounted = true; | 2041 m_autoplayMediaCounted = true; |
| 1999 recordAutoplayMetric(AutoplayMediaFound); | 2042 recordAutoplayMetric(AutoplayMediaFound); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2034 m_autoplayHelper.pauseMethodCalled(); | 2077 m_autoplayHelper.pauseMethodCalled(); |
| 2035 | 2078 |
| 2036 m_autoplaying = false; | 2079 m_autoplaying = false; |
| 2037 | 2080 |
| 2038 if (!m_paused) { | 2081 if (!m_paused) { |
| 2039 recordMetricsIfPausing(); | 2082 recordMetricsIfPausing(); |
| 2040 | 2083 |
| 2041 m_paused = true; | 2084 m_paused = true; |
| 2042 scheduleTimeupdateEvent(false); | 2085 scheduleTimeupdateEvent(false); |
| 2043 scheduleEvent(EventTypeNames::pause); | 2086 scheduleEvent(EventTypeNames::pause); |
| 2087 scheduleRejectPlayPromises(AbortError); | |
| 2044 } | 2088 } |
| 2045 | 2089 |
| 2046 updatePlayState(); | 2090 updatePlayState(); |
| 2047 } | 2091 } |
| 2048 | 2092 |
| 2049 void HTMLMediaElement::requestRemotePlayback() | 2093 void HTMLMediaElement::requestRemotePlayback() |
| 2050 { | 2094 { |
| 2051 ASSERT(m_remoteRoutesAvailable); | 2095 ASSERT(m_remoteRoutesAvailable); |
| 2052 webMediaPlayer()->requestRemotePlayback(); | 2096 webMediaPlayer()->requestRemotePlayback(); |
| 2053 } | 2097 } |
| (...skipping 1430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3484 visitor->trace(m_asyncEventQueue); | 3528 visitor->trace(m_asyncEventQueue); |
| 3485 visitor->trace(m_error); | 3529 visitor->trace(m_error); |
| 3486 visitor->trace(m_currentSourceNode); | 3530 visitor->trace(m_currentSourceNode); |
| 3487 visitor->trace(m_nextChildNodeToConsider); | 3531 visitor->trace(m_nextChildNodeToConsider); |
| 3488 visitor->trace(m_mediaSource); | 3532 visitor->trace(m_mediaSource); |
| 3489 visitor->trace(m_audioTracks); | 3533 visitor->trace(m_audioTracks); |
| 3490 visitor->trace(m_videoTracks); | 3534 visitor->trace(m_videoTracks); |
| 3491 visitor->trace(m_cueTimeline); | 3535 visitor->trace(m_cueTimeline); |
| 3492 visitor->trace(m_textTracks); | 3536 visitor->trace(m_textTracks); |
| 3493 visitor->trace(m_textTracksWhenResourceSelectionBegan); | 3537 visitor->trace(m_textTracksWhenResourceSelectionBegan); |
| 3538 visitor->trace(m_playResolvers); | |
| 3494 visitor->trace(m_audioSourceProvider); | 3539 visitor->trace(m_audioSourceProvider); |
| 3495 visitor->template registerWeakMembers<HTMLMediaElement, &HTMLMediaElement::c learWeakMembers>(this); | 3540 visitor->template registerWeakMembers<HTMLMediaElement, &HTMLMediaElement::c learWeakMembers>(this); |
| 3496 visitor->trace(m_autoplayHelper); | 3541 visitor->trace(m_autoplayHelper); |
| 3497 HeapSupplementable<HTMLMediaElement>::trace(visitor); | 3542 HeapSupplementable<HTMLMediaElement>::trace(visitor); |
| 3498 #endif | 3543 #endif |
| 3499 HTMLElement::trace(visitor); | 3544 HTMLElement::trace(visitor); |
| 3500 ActiveDOMObject::trace(visitor); | 3545 ActiveDOMObject::trace(visitor); |
| 3501 } | 3546 } |
| 3502 | 3547 |
| 3503 void HTMLMediaElement::createPlaceholderTracksIfNecessary() | 3548 void HTMLMediaElement::createPlaceholderTracksIfNecessary() |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3561 { | 3606 { |
| 3562 m_autoplayHelper.updatePositionNotificationRegistration(); | 3607 m_autoplayHelper.updatePositionNotificationRegistration(); |
| 3563 } | 3608 } |
| 3564 | 3609 |
| 3565 // TODO(liberato): remove once autoplay gesture override experiment concludes. | 3610 // TODO(liberato): remove once autoplay gesture override experiment concludes. |
| 3566 void HTMLMediaElement::triggerAutoplayViewportCheckForTesting() | 3611 void HTMLMediaElement::triggerAutoplayViewportCheckForTesting() |
| 3567 { | 3612 { |
| 3568 m_autoplayHelper.triggerAutoplayViewportCheckForTesting(); | 3613 m_autoplayHelper.triggerAutoplayViewportCheckForTesting(); |
| 3569 } | 3614 } |
| 3570 | 3615 |
| 3616 void HTMLMediaElement::scheduleResolvePlayPromises() | |
|
philipj_slow
2016/02/25 14:06:48
Can you document here and in the reject counterpar
mlamouri (slow - plz ping)
2016/02/25 14:40:06
Done.
| |
| 3617 { | |
| 3618 if (m_playPromiseResolveTask->isPending()) | |
| 3619 return; | |
| 3620 Platform::current()->currentThread()->taskRunner()->postTask(BLINK_FROM_HERE , m_playPromiseResolveTask->cancelAndCreate()); | |
| 3621 } | |
| 3622 | |
| 3623 void HTMLMediaElement::scheduleRejectPlayPromises(ExceptionCode code) | |
| 3624 { | |
| 3625 if (m_playPromiseRejectTask->isPending()) | |
| 3626 return; | |
| 3627 // TODO(mlamouri): because cancellable tasks can't take parameters, the | |
|
philipj_slow
2016/02/25 14:06:48
Blank line to match style above?
mlamouri (slow - plz ping)
2016/02/25 14:40:06
Done. Not sure which style though.
philipj_slow
2016/02/25 15:28:30
Uh... when viewing the diff between PS10 and PS12
| |
| 3628 // error code needs to be saved. | |
| 3629 m_playPromiseErrorCode = code; | |
| 3630 Platform::current()->currentThread()->taskRunner()->postTask(BLINK_FROM_HERE , m_playPromiseRejectTask->cancelAndCreate()); | |
| 3631 } | |
| 3632 | |
| 3633 void HTMLMediaElement::scheduleNotifyPlaying() | |
| 3634 { | |
| 3635 scheduleEvent(EventTypeNames::playing); | |
| 3636 scheduleResolvePlayPromises(); | |
| 3637 } | |
| 3638 | |
| 3639 void HTMLMediaElement::resolvePlayPromises() | |
| 3640 { | |
| 3641 for (auto& resolver: m_playResolvers) | |
| 3642 resolver->resolve(); | |
| 3643 | |
| 3644 m_playResolvers.clear(); | |
| 3645 } | |
| 3646 | |
| 3647 void HTMLMediaElement::rejectPlayPromises() | |
| 3648 { | |
| 3649 // TODO(mlamouri): the message is generated based on the code because | |
| 3650 // arguments can't be passed to a cancellable task. In order to save space | |
| 3651 // used by the object, the string isn't saved. | |
| 3652 ASSERT(m_playPromiseErrorCode == AbortError || m_playPromiseErrorCode == Not SupportedError); | |
| 3653 if (m_playPromiseErrorCode == AbortError) | |
| 3654 rejectPlayPromises(AbortError, "The play() request was interrupted by a call to pause()."); | |
| 3655 else | |
| 3656 rejectPlayPromises(NotSupportedError, "Failed to load because no support ed source was found."); | |
| 3657 } | |
| 3658 | |
| 3659 void HTMLMediaElement::rejectPlayPromises(ExceptionCode code, const String& mess age) | |
| 3660 { | |
| 3661 ASSERT(code == AbortError || code == NotSupportedError); | |
| 3662 | |
| 3663 for (auto& resolver: m_playResolvers) | |
| 3664 resolver->reject(DOMException::create(code, message)); | |
| 3665 | |
| 3666 m_playResolvers.clear(); | |
| 3667 } | |
| 3668 | |
| 3571 void HTMLMediaElement::clearWeakMembers(Visitor* visitor) | 3669 void HTMLMediaElement::clearWeakMembers(Visitor* visitor) |
| 3572 { | 3670 { |
| 3573 if (!Heap::isHeapObjectAlive(m_audioSourceNode)) | 3671 if (!Heap::isHeapObjectAlive(m_audioSourceNode)) |
| 3574 audioSourceProvider().setClient(nullptr); | 3672 audioSourceProvider().setClient(nullptr); |
| 3575 } | 3673 } |
| 3576 | 3674 |
| 3577 void HTMLMediaElement::AudioSourceProviderImpl::wrap(WebAudioSourceProvider* pro vider) | 3675 void HTMLMediaElement::AudioSourceProviderImpl::wrap(WebAudioSourceProvider* pro vider) |
| 3578 { | 3676 { |
| 3579 MutexLocker locker(provideInputLock); | 3677 MutexLocker locker(provideInputLock); |
| 3580 | 3678 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3628 { | 3726 { |
| 3629 visitor->trace(m_client); | 3727 visitor->trace(m_client); |
| 3630 } | 3728 } |
| 3631 | 3729 |
| 3632 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) | 3730 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) |
| 3633 { | 3731 { |
| 3634 visitor->trace(m_client); | 3732 visitor->trace(m_client); |
| 3635 } | 3733 } |
| 3636 | 3734 |
| 3637 } // namespace blink | 3735 } // namespace blink |
| OLD | NEW |