mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-02 22:37:50 +00:00
Bug 1409985 - Don't fire DOMEvent during StableState. r=smaug
This commit is contained in:
parent
89df96b890
commit
6115852e16
@ -5829,6 +5829,14 @@ nsContentUtils::RunInMetastableState(already_AddRefed<nsIRunnable> aRunnable)
|
||||
CycleCollectedJSContext::Get()->RunInMetastableState(Move(aRunnable));
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool
|
||||
nsContentUtils::IsInStableOrMetaStableState()
|
||||
{
|
||||
MOZ_ASSERT(CycleCollectedJSContext::Get(), "Must be on a script thread!");
|
||||
return CycleCollectedJSContext::Get()->IsInStableOrMetaStableState();
|
||||
}
|
||||
|
||||
/* static */
|
||||
nsISerialEventTarget*
|
||||
nsContentUtils::GetStableStateEventTarget()
|
||||
|
@ -1972,6 +1972,11 @@ public:
|
||||
*/
|
||||
static void RunInMetastableState(already_AddRefed<nsIRunnable> aRunnable);
|
||||
|
||||
/**
|
||||
* Returns true if we are doing StableState/MetastableState.
|
||||
*/
|
||||
static bool IsInStableOrMetaStableState();
|
||||
|
||||
/**
|
||||
* Returns a nsISerialEventTarget which will run any event dispatched to it
|
||||
* once the event loop has reached a "stable state". Runnables dispatched to
|
||||
|
@ -601,6 +601,10 @@ EventDispatcher::Dispatch(nsISupports* aTarget,
|
||||
NS_ENSURE_TRUE(aEvent->mMessage || !aDOMEvent || aTargets,
|
||||
NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
|
||||
// Events shall not be fired while we are in stable state to prevent anything
|
||||
// visible from the scripts.
|
||||
MOZ_ASSERT(!nsContentUtils::IsInStableOrMetaStableState());
|
||||
|
||||
#ifdef MOZ_TASK_TRACER
|
||||
if (MOZ_UNLIKELY(mozilla::tasktracer::IsStartLogging())) {
|
||||
nsAutoCString eventType;
|
||||
|
@ -158,7 +158,18 @@ class MediaDecoder::BackgroundVideoDecodingPermissionObserver final :
|
||||
if (observerService) {
|
||||
observerService->AddObserver(this, "unselected-tab-hover", false);
|
||||
mIsRegisteredForEvent = true;
|
||||
EnableEvent();
|
||||
if (nsContentUtils::IsInStableOrMetaStableState()) {
|
||||
// Events shall not be fired synchronously to prevent anything visible
|
||||
// from the scripts while we are in stable state.
|
||||
if (nsCOMPtr<nsIDocument> doc = GetOwnerDoc()) {
|
||||
doc->Dispatch(TaskCategory::Other,
|
||||
NewRunnableMethod(
|
||||
"MediaDecoder::BackgroundVideoDecodingPermissionObserver::EnableEvent",
|
||||
this, &MediaDecoder::BackgroundVideoDecodingPermissionObserver::EnableEvent));
|
||||
}
|
||||
} else {
|
||||
EnableEvent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -170,7 +181,18 @@ class MediaDecoder::BackgroundVideoDecodingPermissionObserver final :
|
||||
mIsRegisteredForEvent = false;
|
||||
mDecoder->mIsBackgroundVideoDecodingAllowed = false;
|
||||
mDecoder->UpdateVideoDecodeMode();
|
||||
DisableEvent();
|
||||
if (nsContentUtils::IsInStableOrMetaStableState()) {
|
||||
// Events shall not be fired synchronously to prevent anything visible
|
||||
// from the scripts while we are in stable state.
|
||||
if (nsCOMPtr<nsIDocument> doc = GetOwnerDoc()) {
|
||||
doc->Dispatch(TaskCategory::Other,
|
||||
NewRunnableMethod(
|
||||
"MediaDecoder::BackgroundVideoDecodingPermissionObserver::DisableEvent",
|
||||
this, &MediaDecoder::BackgroundVideoDecodingPermissionObserver::DisableEvent));
|
||||
}
|
||||
} else {
|
||||
DisableEvent();
|
||||
}
|
||||
}
|
||||
}
|
||||
private:
|
||||
|
@ -61,18 +61,35 @@ public:
|
||||
switch (event) {
|
||||
case MediaStreamGraphEvent::EVENT_FINISHED:
|
||||
{
|
||||
RefPtr<SynthStreamListener> self = this;
|
||||
if (!mStarted) {
|
||||
mStarted = true;
|
||||
aGraph->DispatchToMainThreadAfterStreamStateUpdate(
|
||||
NewRunnableMethod("dom::SynthStreamListener::DoNotifyStarted",
|
||||
this,
|
||||
&SynthStreamListener::DoNotifyStarted));
|
||||
NS_NewRunnableFunction(
|
||||
"dom::SynthStreamListener::NotifyEvent",
|
||||
[self] {
|
||||
// "start" event will be fired in DoNotifyStarted() which is
|
||||
// not allowed in stable state, so we do it asynchronously in
|
||||
// next run.
|
||||
NS_DispatchToMainThread(NewRunnableMethod(
|
||||
"dom::SynthStreamListener::DoNotifyStarted",
|
||||
self,
|
||||
&SynthStreamListener::DoNotifyStarted));
|
||||
}));
|
||||
}
|
||||
|
||||
aGraph->DispatchToMainThreadAfterStreamStateUpdate(
|
||||
NewRunnableMethod("dom::SynthStreamListener::DoNotifyFinished",
|
||||
this,
|
||||
&SynthStreamListener::DoNotifyFinished));
|
||||
NS_NewRunnableFunction(
|
||||
"dom::SynthStreamListener::NotifyEvent",
|
||||
[self] {
|
||||
// "end" event will be fired in DoNotifyFinished() which is
|
||||
// not allowed in stable state, so we do it asynchronously in
|
||||
// next run.
|
||||
NS_DispatchToMainThread(NewRunnableMethod(
|
||||
"dom::SynthStreamListener::DoNotifyFinished",
|
||||
self,
|
||||
&SynthStreamListener::DoNotifyFinished));
|
||||
}));
|
||||
}
|
||||
break;
|
||||
case MediaStreamGraphEvent::EVENT_REMOVED:
|
||||
@ -89,10 +106,19 @@ public:
|
||||
{
|
||||
if (aBlocked == MediaStreamListener::UNBLOCKED && !mStarted) {
|
||||
mStarted = true;
|
||||
RefPtr<SynthStreamListener> self = this;
|
||||
aGraph->DispatchToMainThreadAfterStreamStateUpdate(
|
||||
NewRunnableMethod("dom::SynthStreamListener::DoNotifyStarted",
|
||||
this,
|
||||
&SynthStreamListener::DoNotifyStarted));
|
||||
NS_NewRunnableFunction(
|
||||
"dom::SynthStreamListener::NotifyBlockingChanged",
|
||||
[self] {
|
||||
// "start" event will be fired in DoNotifyStarted() which is
|
||||
// not allowed in stable state, so we do it asynchronously in
|
||||
// next run.
|
||||
NS_DispatchToMainThread(NewRunnableMethod(
|
||||
"dom::SynthStreamListener::DoNotifyStarted",
|
||||
self,
|
||||
&SynthStreamListener::DoNotifyStarted));
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -242,6 +242,11 @@ public:
|
||||
|
||||
void DispatchMicroTaskRunnable(already_AddRefed<MicroTaskRunnable> aRunnable);
|
||||
|
||||
bool IsInStableOrMetaStableState()
|
||||
{
|
||||
return mDoingStableStates;
|
||||
}
|
||||
|
||||
// Storage for watching rejected promises waiting for some client to
|
||||
// consume their rejection.
|
||||
// Promises in this list have been rejected in the last turn of the
|
||||
|
Loading…
x
Reference in New Issue
Block a user