haikuwebkit/LayoutTests/media/video-source-moved.html

206 lines
9.2 KiB
HTML
Raw Permalink Normal View History

2010-10-19 Eric Carlson <eric.carlson@apple.com> Reviewed by Darin Adler. https://bugs.webkit.org/show_bug.cgi?id=46763 CRASH in WebCore::ThreadTimers::sharedTimerFiredInternal Fix crashes caused by moving and deleting <source> element(s) of active media element. Tests: media/video-source-moved.html media/video-source-removed.html * html/HTMLMediaElement.cpp: (WebCore::HTMLMediaElement::HTMLMediaElement): Add logging. Initialize selectNextSourceChild. (WebCore::HTMLMediaElement::~HTMLMediaElement): Ditto. (WebCore::HTMLMediaElement::insertedIntoDocument): Ditto. (WebCore::HTMLMediaElement::removedFromDocument): Ditto. (WebCore::HTMLMediaElement::scheduleLoad): Ditto. (WebCore::HTMLMediaElement::setNetworkState): Deal with m_currentSourceNode being null when the media engine signals a failure by skipping the error message and continuing as usual. (WebCore::HTMLMediaElement::setVolume): Fix logging typo. (WebCore::HTMLMediaElement::havePotentialSourceChild): Save and restore m_nextChildNodeToConsider around call to selectNextSourceChild because they are both significant. (WebCore::HTMLMediaElement::selectNextSourceChild): Use m_nextChildNodeToConsider to pick the first node to consider. Bail immediately if it signals that we have already processed every <source> node. Stach the node following the current source element in m_nextChildNodeToConsider so we can resume the search even if m_currentSourceNode is removed while it is being processed. (WebCore::HTMLMediaElement::sourceWasAdded): New, move logic from HTMLSourceElement::insertedIntoTree here and correct it to deal with a <source> node being inserted immediately after the current <source> node and a new <source> node being inserted at the end of the list after all candidates have failed. (WebCore::HTMLMediaElement::sourceWillBeRemoved): New, deal with current source node and next potential node being removed. * html/HTMLMediaElement.h: (WebCore::HTMLMediaElement::sourceChildEndOfListValue): New, define sentinal value used to indicate that all nodes have been processed. * html/HTMLSourceElement.cpp: (WebCore::HTMLSourceElement::HTMLSourceElement): Add logging. (WebCore::HTMLSourceElement::insertedIntoTree): Call mediaElement->sourceWasAdded instead of having logic here. (WebCore::HTMLSourceElement::willRemove): New, call mediaElement->sourceWillBeRemoved (WebCore::HTMLSourceElement::scheduleErrorEvent): Add logging. (WebCore::HTMLSourceElement::cancelPendingErrorEvent): Add logging. * html/HTMLSourceElement.h: 2010-10-19 Eric Carlson <eric.carlson@apple.com> Reviewed by Darin Adler. https://bugs.webkit.org/show_bug.cgi?id=46763 CRASH in WebCore::ThreadTimers::sharedTimerFiredInternal Test moving and deleting <source> element(s) of active <video>. * media/media-file.js: (mimeTypeForExtension): New, added to make it possible to set 'type' attribute on <source>. * media/video-source-moved-expected.txt: Added. * media/video-source-moved.html: Added. * media/video-source-removed-expected.txt: Added. * media/video-source-removed.html: Added. Canonical link: https://commits.webkit.org/60625@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@70063 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2010-10-19 16:43:37 +00:00
<!doctype HTML>
<html>
<head>
<title>moving &lt;source&gt; element test</title>
2011-02-24 Victoria Kirst <vrk@google.com> Reviewed by Mihai Parparita. [chromium] Move media-file.js and video-test.js back to media/ for UILayoutTests https://bugs.webkit.org/show_bug.cgi?id=55089 Media's UILayoutTests rely on video-test.js and media-file.js to be in the media/ folder. * http/tests/media/pdf-served-as-pdf.html: * http/tests/media/reload-after-dialog.html: * http/tests/media/remove-while-loading.html: * http/tests/media/text-served-as-text.html: * http/tests/media/video-buffered.html: * http/tests/media/video-cancel-load.html: * http/tests/media/video-cookie.html: * http/tests/media/video-error-abort.html: * http/tests/media/video-load-twice.html: * http/tests/media/video-play-stall-seek.html: * http/tests/media/video-play-stall.html: * http/tests/media/video-play-suspend.html: * http/tests/media/video-referer.html: * http/tests/media/video-seekable-stall.html: * http/tests/media/video-served-as-text.html: * media/adopt-node-crash.html: * media/audio-constructor-preload.html: * media/audio-constructor-src.html: * media/audio-constructor.html: * media/audio-controls-rendering.html: * media/audio-data-url.html: * media/audio-delete-while-slider-thumb-clicked.html: * media/audio-delete-while-step-button-clicked.html: * media/audio-mpeg-supported.html: * media/audio-mpeg4-supported.html: * media/audio-play-event.html: * media/before-load-member-access.html: * media/broken-video.html: * media/constructors.html: * media/context-menu-actions.html: * media/controls-after-reload.html: * media/controls-css-overload.html: * media/controls-drag-timebar.html: * media/controls-right-click-on-timebar.html: * media/controls-strict.html: * media/controls-styling.html: * media/controls-without-preload.html: * media/event-attributes.html: * media/invalid-media-url-crash.html: * media/media-can-play-mpeg-audio.html: * media/media-can-play-mpeg4-video.html: * media/media-can-play-octet-stream.html: * media/media-can-play-ogg.html: * media/media-can-play-wav-audio.html: * media/media-captions.html: * media/media-constants.html: * media/media-file.js: Renamed from LayoutTests/http/tests/media/media-file.js. * media/media-fullscreen-inline.html: * media/media-fullscreen-not-in-document.html: * media/media-load-event.html: * media/media-startTime.html: * media/remove-from-document-no-load.html: * media/remove-from-document.html: * media/restore-from-page-cache.html: * media/unsupported-rtsp.html: * media/unsupported-tracks.html: * media/video-append-source.html: * media/video-aspect-ratio.html: * media/video-autoplay.html: * media/video-buffered.html: * media/video-can-play-type.html: * media/video-canvas-alpha.html: * media/video-canvas-source.html: * media/video-click-dblckick-standalone.html: * media/video-controls-rendering.html: * media/video-controls-transformed.html: * media/video-controls-visible-audio-only.html: * media/video-controls-zoomed.html: * media/video-controls.html: * media/video-currentTime-delay.html: * media/video-currentTime-set.html: * media/video-currentTime-set2.html: * media/video-currentTime.html: * media/video-delay-load-event.html: * media/video-display-aspect-ratio.html: * media/video-display-none-crash.html: * media/video-display-toggle.html: * media/video-does-not-loop.html: * media/video-dom-autoplay.html: * media/video-dom-preload.html: * media/video-dom-src.html: * media/video-duration-known-after-eos.html: * media/video-error-does-not-exist.html: * media/video-frame-accurate-seek.html: * media/video-layer-crash.html: * media/video-load-networkState.html: * media/video-load-readyState.html: * media/video-loop.html: * media/video-muted.html: * media/video-no-audio.html: * media/video-no-autoplay.html: * media/video-pause-empty-events.html: * media/video-pause-immediately.html: * media/video-play-empty-events.html: * media/video-play-pause-events.html: * media/video-play-pause-exception.html: * media/video-played-collapse.html: * media/video-played-ranges-1.html: * media/video-played-reset.html: * media/video-poster-delayed.html: * media/video-poster-scale.html: * media/video-poster.html: * media/video-preload.html: * media/video-replaces-poster.html: * media/video-reverse-play-duration.html: * media/video-seek-by-small-increment.html: * media/video-seek-no-src-exception.html: * media/video-seek-past-end-paused.html: * media/video-seek-past-end-playing.html: * media/video-seekable.html: * media/video-seeking.html: * media/video-size-intrinsic-scale.html: * media/video-size.html: * media/video-source-error-no-candidate.html: * media/video-source-error.html: * media/video-source-inserted.html: * media/video-source-media.html: * media/video-source-moved.html: * media/video-source-none-supported.html: * media/video-source-removed.html: * media/video-source-type-params.html: * media/video-source-type.html: * media/video-source.html: * media/video-src-change.html: * media/video-src-invalid-remove.html: * media/video-src-none.html: * media/video-src-plus-source.html: * media/video-src-remove.html: * media/video-src-set.html: * media/video-src-source.html: * media/video-src.html: * media/video-test.js: Renamed from LayoutTests/http/tests/media/video-test.js. * media/video-timeupdate-during-playback.html: * media/video-timeupdate-reverse-play.html: * media/video-transformed.html: * media/video-volume-slider.html: * media/video-volume.html: * media/video-width-height.html: * media/video-zoom-controls.html: * media/video-zoom.html: 2011-02-24 Victoria Kirst <vrk@google.com> Reviewed by Mihai Parparita. [chromium] Move media-file.js and video-test.js back to media/ for UILayoutTests https://bugs.webkit.org/show_bug.cgi?id=55089 This adds an alias into the media/ directory so that http/tests/media tests can access the media resources when running in an httpd process. * Scripts/webkitperl/httpd.pm: * Scripts/webkitpy/layout_tests/port/apache_http_server.py: * Scripts/webkitpy/layout_tests/port/http_server.py: Canonical link: https://commits.webkit.org/69549@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@79630 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2011-02-24 23:10:46 +00:00
<script src=video-test.js></script>
<script src=media-file.js></script>
2010-10-19 Eric Carlson <eric.carlson@apple.com> Reviewed by Darin Adler. https://bugs.webkit.org/show_bug.cgi?id=46763 CRASH in WebCore::ThreadTimers::sharedTimerFiredInternal Fix crashes caused by moving and deleting <source> element(s) of active media element. Tests: media/video-source-moved.html media/video-source-removed.html * html/HTMLMediaElement.cpp: (WebCore::HTMLMediaElement::HTMLMediaElement): Add logging. Initialize selectNextSourceChild. (WebCore::HTMLMediaElement::~HTMLMediaElement): Ditto. (WebCore::HTMLMediaElement::insertedIntoDocument): Ditto. (WebCore::HTMLMediaElement::removedFromDocument): Ditto. (WebCore::HTMLMediaElement::scheduleLoad): Ditto. (WebCore::HTMLMediaElement::setNetworkState): Deal with m_currentSourceNode being null when the media engine signals a failure by skipping the error message and continuing as usual. (WebCore::HTMLMediaElement::setVolume): Fix logging typo. (WebCore::HTMLMediaElement::havePotentialSourceChild): Save and restore m_nextChildNodeToConsider around call to selectNextSourceChild because they are both significant. (WebCore::HTMLMediaElement::selectNextSourceChild): Use m_nextChildNodeToConsider to pick the first node to consider. Bail immediately if it signals that we have already processed every <source> node. Stach the node following the current source element in m_nextChildNodeToConsider so we can resume the search even if m_currentSourceNode is removed while it is being processed. (WebCore::HTMLMediaElement::sourceWasAdded): New, move logic from HTMLSourceElement::insertedIntoTree here and correct it to deal with a <source> node being inserted immediately after the current <source> node and a new <source> node being inserted at the end of the list after all candidates have failed. (WebCore::HTMLMediaElement::sourceWillBeRemoved): New, deal with current source node and next potential node being removed. * html/HTMLMediaElement.h: (WebCore::HTMLMediaElement::sourceChildEndOfListValue): New, define sentinal value used to indicate that all nodes have been processed. * html/HTMLSourceElement.cpp: (WebCore::HTMLSourceElement::HTMLSourceElement): Add logging. (WebCore::HTMLSourceElement::insertedIntoTree): Call mediaElement->sourceWasAdded instead of having logic here. (WebCore::HTMLSourceElement::willRemove): New, call mediaElement->sourceWillBeRemoved (WebCore::HTMLSourceElement::scheduleErrorEvent): Add logging. (WebCore::HTMLSourceElement::cancelPendingErrorEvent): Add logging. * html/HTMLSourceElement.h: 2010-10-19 Eric Carlson <eric.carlson@apple.com> Reviewed by Darin Adler. https://bugs.webkit.org/show_bug.cgi?id=46763 CRASH in WebCore::ThreadTimers::sharedTimerFiredInternal Test moving and deleting <source> element(s) of active <video>. * media/media-file.js: (mimeTypeForExtension): New, added to make it possible to set 'type' attribute on <source>. * media/video-source-moved-expected.txt: Added. * media/video-source-moved.html: Added. * media/video-source-removed-expected.txt: Added. * media/video-source-removed.html: Added. Canonical link: https://commits.webkit.org/60625@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@70063 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2010-10-19 16:43:37 +00:00
<script>
var testInfo =
{
current : -1,
tests :
[
{ fcn : moveToEnd, errorCount : 0, moved : null, done : false, iteration : 1},
{ fcn : moveToEnd, errorCount : 0, moved : null, done : false, iteration : 2},
{ fcn : moveToEnd, errorCount : 0, moved : null, done : false, iteration : 3},
{ fcn : moveEarlier, errorCount : 0, moved : null, iteration : 1 },
{ fcn : moveEarlier, errorCount : 0, moved : null, iteration : 2 },
{ fcn : moveEarlier, errorCount : 0, moved : null, iteration : 3 },
{ fcn : moveEarlier, errorCount : 0, moved : null, iteration : 4 }
]
};
function findCurrentSourceElement()
{
var sources = video.getElementsByTagName('source');
var currentSrc = video.currentSrc;
var ndx;
for (ndx = 0; ndx < sources.length; ++ndx) {
if (sources[ndx].src == currentSrc)
break;
}
if (ndx >= sources.length) {
failTest(currentSrc + " not found in &lt;source&gt; list");
return null;
}
return sources[ndx];
}
function moveEarlier(test, event)
{
if (test.done)
return;
switch (++test.errorCount)
{
case 1:
// Do nothing on the first error event
break;
case 2:
var current = findCurrentSourceElement();
switch (test.iteration)
{
case 1:
consoleWrite("Moving <b>current<" + "/b> &lt;source&gt; element to beginning of list, it should not be processed again.");
test.moved = video.removeChild(current);
break;
case 2:
consoleWrite("Moving <b>next<" + "/b> &lt;source&gt; element to beginning of list, it should never processed.");
test.moved = video.removeChild(current.nextSibling);
break;
case 3:
consoleWrite("&lt;span&gt; inserted after <b>current<" + "/b> &lt;source&gt; element before it is removed, processing should proceed normally.");
var span = document.createElement("span")
span.appendChild(document.createTextNode("Your browser doesn't support HTML5 video!"));
video.insertBefore(span, current.nextSibling);
test.moved = video.removeChild(current);
break;
case 4:
consoleWrite("&lt;span&gt; inserted after <b>next<" + "/b> &lt;source&gt; element before it is removed, processing should proceed normally.");
var span = document.createElement("span")
span.appendChild(document.createTextNode("Your browser doesn't support HTML5 video!"));
video.insertBefore(span, current.nextSibling.nextSibling);
test.moved = video.removeChild(current.nextSibling);
break;
default:
failTest("Malformed test data!");
break;
}
testExpected(test.moved, null, '!=');
video.insertBefore(test.moved, video.firstChild);
break;
default:
// We should never get an error for the element we moved.
if (event.target == test.moved) {
failTest("Error fired for &lt;source&gt; moved to beginning of list.");
test.done = true;
return;
} else if (!event.target.nextSibling) {
logResult(true, "&lt;source&gt; moved was not processed");
setTimeout(configureNextTest, 100);
}
break;
}
}
function moveToEnd(test, event)
{
switch (++test.errorCount)
{
case 1:
// Do nothing on the first error event
break;
case 2:
var current = findCurrentSourceElement();
switch (test.iteration)
{
case 1:
consoleWrite("Moving <b>previous<" + "/b> &lt;source&gt; element to end of list, it should be processed again.");
test.moved = video.removeChild(current.previousSibling);
break;
case 2:
consoleWrite("Moving <b>current<" + "/b> &lt;source&gt; element, it should be processed again.");
test.moved = video.removeChild(current);
break;
case 3:
consoleWrite("Moving <b>next<" + "/b> &lt;source&gt; element, it should be processed again.");
test.moved = video.removeChild(current.nextSibling);
break;
default:
failTest("Malformed test data!");
break;
}
testExpected(test.moved, null, '!=');
video.appendChild(test.moved);
break;
default:
if (event.target == test.moved) {
logResult(true, "&lt;source&gt; moved was processed a second time.");
setTimeout(configureNextTest, 100);
} else if (!event.target.nextSibling) {
// We should never reach the end of the source list since the tests stops
// when the error fires for the moved element.
failTest("Error never fired for &lt;source&gt; moved!");
}
break;
}
}
function runOneTest(evt)
{
var test = testInfo.tests[testInfo.current];
test.fcn(test, evt);
}
function addSource(index)
{
var source = document.createElement('source');
source.src = findMediaFile("video", index + "-" + Date.now());
source.type = mimeTypeForExtension(source.src.split('.').pop());
2010-10-19 Eric Carlson <eric.carlson@apple.com> Reviewed by Darin Adler. https://bugs.webkit.org/show_bug.cgi?id=46763 CRASH in WebCore::ThreadTimers::sharedTimerFiredInternal Fix crashes caused by moving and deleting <source> element(s) of active media element. Tests: media/video-source-moved.html media/video-source-removed.html * html/HTMLMediaElement.cpp: (WebCore::HTMLMediaElement::HTMLMediaElement): Add logging. Initialize selectNextSourceChild. (WebCore::HTMLMediaElement::~HTMLMediaElement): Ditto. (WebCore::HTMLMediaElement::insertedIntoDocument): Ditto. (WebCore::HTMLMediaElement::removedFromDocument): Ditto. (WebCore::HTMLMediaElement::scheduleLoad): Ditto. (WebCore::HTMLMediaElement::setNetworkState): Deal with m_currentSourceNode being null when the media engine signals a failure by skipping the error message and continuing as usual. (WebCore::HTMLMediaElement::setVolume): Fix logging typo. (WebCore::HTMLMediaElement::havePotentialSourceChild): Save and restore m_nextChildNodeToConsider around call to selectNextSourceChild because they are both significant. (WebCore::HTMLMediaElement::selectNextSourceChild): Use m_nextChildNodeToConsider to pick the first node to consider. Bail immediately if it signals that we have already processed every <source> node. Stach the node following the current source element in m_nextChildNodeToConsider so we can resume the search even if m_currentSourceNode is removed while it is being processed. (WebCore::HTMLMediaElement::sourceWasAdded): New, move logic from HTMLSourceElement::insertedIntoTree here and correct it to deal with a <source> node being inserted immediately after the current <source> node and a new <source> node being inserted at the end of the list after all candidates have failed. (WebCore::HTMLMediaElement::sourceWillBeRemoved): New, deal with current source node and next potential node being removed. * html/HTMLMediaElement.h: (WebCore::HTMLMediaElement::sourceChildEndOfListValue): New, define sentinal value used to indicate that all nodes have been processed. * html/HTMLSourceElement.cpp: (WebCore::HTMLSourceElement::HTMLSourceElement): Add logging. (WebCore::HTMLSourceElement::insertedIntoTree): Call mediaElement->sourceWasAdded instead of having logic here. (WebCore::HTMLSourceElement::willRemove): New, call mediaElement->sourceWillBeRemoved (WebCore::HTMLSourceElement::scheduleErrorEvent): Add logging. (WebCore::HTMLSourceElement::cancelPendingErrorEvent): Add logging. * html/HTMLSourceElement.h: 2010-10-19 Eric Carlson <eric.carlson@apple.com> Reviewed by Darin Adler. https://bugs.webkit.org/show_bug.cgi?id=46763 CRASH in WebCore::ThreadTimers::sharedTimerFiredInternal Test moving and deleting <source> element(s) of active <video>. * media/media-file.js: (mimeTypeForExtension): New, added to make it possible to set 'type' attribute on <source>. * media/video-source-moved-expected.txt: Added. * media/video-source-moved.html: Added. * media/video-source-removed-expected.txt: Added. * media/video-source-removed.html: Added. Canonical link: https://commits.webkit.org/60625@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@70063 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2010-10-19 16:43:37 +00:00
video.appendChild(source);
}
function runNextTest()
{
consoleWrite("");
if (++testInfo.current >= testInfo.tests.length) {
consoleWrite("PASS<br>");
endTest();
return;
}
testInfo.errorCount = 0;
video = mediaElement = document.createElement('video');
document.body.appendChild(video);
// Add a bunch of source elements with bogus urls because we want to rearrange elements
// after the media engine begins processing sources, and we can't predict the delay
// between when the media element fires an 'error' event and our handler is called,
// but we need to guarantee that there are <source> elements that haven't been processed
// when we run the test.
for (var ndx = 1; ndx <= 10; ndx++)
addSource(ndx);
}
function configureNextTest()
{
var videos = document.querySelectorAll('video');
for (var ndx = 0; ndx < videos.length; ++ndx)
videos[ndx].parentNode.removeChild(videos[ndx]);
video = mediaElement = null;
setTimeout(runNextTest, 100);
}
function setup()
{
document.addEventListener("error", runOneTest, true);
configureNextTest();
}
</script>
</head>
<body>
<div>Test to make sure a &lt;source&gt; moved after the media element begins processing
is handled correctly.</div>
<script>setup()</script>
</body>
</html>