Bug 880094 - Provide a stable state for HTMLTrackElement asynchronous functions. r=cpearce

- Removed HTMLMediaElement::AsyncAwaitStableState and exposed a new method,
HTMLMediaElement::RunInStableState, that allows any nsIRunnable to run on
the app shell and take advantage of IsCancelled() code in an nsMediaEvent.
- HTMLTrackElement now uses this to call HTMLTrackElement::LoadResource.
- Changed test_texttrackcue.html to listen for MediaElement's "loadedmetadata"
to ensure that we wait until the cues are loaded before testing and set
preload=auto to get it to pass on Android.
This commit is contained in:
Rick Eyre 2013-06-27 21:05:03 -04:00
parent 870a931fd4
commit 324b1a63c1
4 changed files with 21 additions and 16 deletions

View File

@ -321,6 +321,13 @@ public:
*/
void SetRequestHeaders(nsIHttpChannel* aChannel);
/**
* Asynchronously awaits a stable state, whereupon aRunnable runs on the main
* thread. This adds an event which run aRunnable to the appshell's list of
* sections synchronous the next time control returns to the event loop.
*/
void RunInStableState(nsIRunnable* aRunnable);
/**
* Fires a timeupdate event. If aPeriodic is true, the event will only
* be fired if we've not fired a timeupdate event (for any reason) in the

View File

@ -667,12 +667,12 @@ typedef void (HTMLMediaElement::*SyncSectionFn)();
class nsSyncSection : public nsMediaEvent
{
private:
SyncSectionFn mClosure;
nsCOMPtr<nsIRunnable> mRunnable;
public:
nsSyncSection(HTMLMediaElement* aElement,
SyncSectionFn aClosure) :
nsIRunnable* aRunnable) :
nsMediaEvent(aElement),
mClosure(aClosure)
mRunnable(aRunnable)
{
}
@ -680,20 +680,16 @@ public:
// Silently cancel if our load has been cancelled.
if (IsCancelled())
return NS_OK;
(mElement.get()->*mClosure)();
mRunnable->Run();
return NS_OK;
}
};
static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
// Asynchronously awaits a stable state, whereupon aClosure runs on the main
// thread. This adds an event which run aClosure to the appshell's list of
// sections synchronous the next time control returns to the event loop.
void AsyncAwaitStableState(HTMLMediaElement* aElement,
SyncSectionFn aClosure)
void HTMLMediaElement::RunInStableState(nsIRunnable* aRunnable)
{
nsCOMPtr<nsIRunnable> event = new nsSyncSection(aElement, aClosure);
nsCOMPtr<nsIRunnable> event = new nsSyncSection(this, aRunnable);
nsCOMPtr<nsIAppShell> appShell = do_GetService(kAppShellCID);
appShell->RunInStableState(event);
}
@ -702,7 +698,8 @@ void HTMLMediaElement::QueueLoadFromSourceTask()
{
ChangeDelayLoadStatus(true);
mNetworkState = nsIDOMHTMLMediaElement::NETWORK_LOADING;
AsyncAwaitStableState(this, &HTMLMediaElement::LoadFromSourceChildren);
RunInStableState(
NS_NewRunnableMethod(this, &HTMLMediaElement::LoadFromSourceChildren));
}
void HTMLMediaElement::QueueSelectResourceTask()
@ -712,7 +709,8 @@ void HTMLMediaElement::QueueSelectResourceTask()
return;
mHaveQueuedSelectResource = true;
mNetworkState = nsIDOMHTMLMediaElement::NETWORK_NO_SOURCE;
AsyncAwaitStableState(this, &HTMLMediaElement::SelectResourceWrapper);
RunInStableState(
NS_NewRunnableMethod(this, &HTMLMediaElement::SelectResourceWrapper));
}
/* void load (); */

View File

@ -304,7 +304,7 @@ HTMLTrackElement::BindToTree(nsIDocument* aDocument,
media->NotifyAddedSource();
LOG(PR_LOG_DEBUG, ("Track element sent notification to parent."));
nsContentUtils::AddScriptRunner(
mMediaParent->RunInStableState(
NS_NewRunnableMethod(this, &HTMLTrackElement::LoadResource));
}

View File

@ -21,13 +21,13 @@ SpecialPowers.pushPrefEnv({"set": [["media.webvtt.enabled", true]]},
function() {
var video = document.createElement("video");
video.src = "seek.webm";
video.preload = "auto";
var trackElement = document.createElement("track");
trackElement.src = "basic.vtt";
trackElement.kind = "subtitles";
document.getElementById("content").appendChild(video);
video.appendChild(trackElement);
run_tests();
function run_tests() {
video.addEventListener("loadedmetadata", function run_tests() {
// Re-que run_tests() at the end of the event loop until the track
// element has loaded its data.
if (trackElement.readyState == 1) {
@ -116,7 +116,7 @@ SpecialPowers.pushPrefEnv({"set": [["media.webvtt.enabled", true]]},
todo_is(cueList.length, 4, "Cue list length should be 4.");
SimpleTest.finish();
}
});
}
);