Bug 1222980 - Dispatch |QueueLoadFromSourceTask| to main thread. And end the synchronous section and asynchronously await a stable state when the src is not set. r=jwwang.

Dispatch |QueueLoadFromSourceTask| to main thread to make sure the task will be executed later than loadstart event. And when the src get errors, we need to end the synchronous section.

MozReview-Commit-ID: EQ0jVIMnqoZ
This commit is contained in:
ctai
2016-12-13 15:45:59 +08:00
parent b39e140646
commit 3b19d8d6b5
2 changed files with 36 additions and 8 deletions

View File

@@ -1726,12 +1726,20 @@ public:
void HTMLMediaElement::RunInStableState(nsIRunnable* aRunnable)
{
if (mShuttingDown) {
return;
}
nsCOMPtr<nsIRunnable> event = new nsSyncSection(this, aRunnable);
nsContentUtils::RunInStableState(event.forget());
}
void HTMLMediaElement::QueueLoadFromSourceTask()
{
if (!mIsLoadingFromSourceChildren || mShuttingDown) {
return;
}
ChangeDelayLoadStatus(true);
ChangeNetworkState(nsIDOMHTMLMediaElement::NETWORK_LOADING);
RefPtr<Runnable> r = NewRunnableMethod(this, &HTMLMediaElement::LoadFromSourceChildren);
@@ -2068,6 +2076,18 @@ void HTMLMediaElement::NotifyMediaStreamTracksAvailable(DOMMediaStream* aStream)
mWatchManager.ManualNotify(&HTMLMediaElement::UpdateReadyStateInternal);
}
void HTMLMediaElement::DealWithFailedElement(nsIContent* aSourceElement)
{
if (mShuttingDown) {
return;
}
DispatchAsyncSourceError(aSourceElement);
nsCOMPtr<nsIRunnable> event =
NewRunnableMethod(this, &HTMLMediaElement::QueueLoadFromSourceTask);
NS_DispatchToMainThread(event);
}
void
HTMLMediaElement::NotifyOutputTrackStopped(DOMMediaStream* aOwningStream,
TrackID aDestinationTrackID)
@@ -2125,8 +2145,8 @@ void HTMLMediaElement::LoadFromSourceChildren()
nsAutoString src;
if (!child->GetAttr(kNameSpaceID_None, nsGkAtoms::src, src)) {
ReportLoadError("MediaLoadSourceMissingSrc");
DispatchAsyncSourceError(child);
continue;
DealWithFailedElement(child);
return;
}
// If we have a type attribute, it must be a supported type.
@@ -2137,20 +2157,20 @@ void HTMLMediaElement::LoadFromSourceChildren()
diagnostics.StoreFormatDiagnostics(
OwnerDoc(), type, canPlay != CANPLAY_NO, __func__);
if (canPlay == CANPLAY_NO) {
DispatchAsyncSourceError(child);
const char16_t* params[] = { type.get(), src.get() };
ReportLoadError("MediaLoadUnsupportedTypeAttribute", params, ArrayLength(params));
continue;
DealWithFailedElement(child);
return;
}
}
nsAutoString media;
HTMLSourceElement *childSrc = HTMLSourceElement::FromContent(child);
MOZ_ASSERT(childSrc, "Expect child to be HTMLSourceElement");
if (childSrc && !childSrc->MatchesCurrentMedia()) {
DispatchAsyncSourceError(child);
const char16_t* params[] = { media.get(), src.get() };
ReportLoadError("MediaLoadSourceMediaNotMatched", params, ArrayLength(params));
continue;
DealWithFailedElement(child);
return;
}
LOG(LogLevel::Debug, ("%p Trying load from <source>=%s type=%s media=%s", this,
NS_ConvertUTF16toUTF8(src).get(), NS_ConvertUTF16toUTF8(type).get(),
@@ -2159,10 +2179,10 @@ void HTMLMediaElement::LoadFromSourceChildren()
nsCOMPtr<nsIURI> uri;
NewURIFromString(src, getter_AddRefs(uri));
if (!uri) {
DispatchAsyncSourceError(child);
const char16_t* params[] = { src.get() };
ReportLoadError("MediaLoadInvalidURI", params, ArrayLength(params));
continue;
DealWithFailedElement(child);
return;
}
RemoveMediaElementFromURITable();