void ScreenOrientation::Notify(const hal::ScreenConfiguration& aConfiguration) { if (ShouldResistFingerprinting()) { return; } nsIDocument* doc = GetResponsibleDocument(); if (!doc) { return; } ScreenOrientationInternal orientation = aConfiguration.orientation(); if (orientation != eScreenOrientation_PortraitPrimary && orientation != eScreenOrientation_PortraitSecondary && orientation != eScreenOrientation_LandscapePrimary && orientation != eScreenOrientation_LandscapeSecondary) { // The platform may notify of some other values from // an orientation lock, but we only care about real // changes to screen orientation which result in one of // the values we care about. return; } OrientationType previousOrientation = mType; mAngle = aConfiguration.angle(); mType = InternalOrientationToType(orientation); nsresult rv; if (mScreen && mType != previousOrientation) { // Use of mozorientationchange is deprecated. rv = mScreen->DispatchTrustedEvent(NS_LITERAL_STRING("mozorientationchange")); NS_WARN_IF(NS_FAILED(rv)); } if (doc->Hidden() && !mVisibleListener) { mVisibleListener = new VisibleEventListener(); rv = doc->AddSystemEventListener(NS_LITERAL_STRING("visibilitychange"), mVisibleListener, /* useCapture = */ true); NS_WARN_IF(NS_FAILED(rv)); return; } if (mType != doc->CurrentOrientationType()) { doc->SetCurrentOrientation(mType, mAngle); Promise* pendingPromise = doc->GetOrientationPendingPromise(); if (pendingPromise) { pendingPromise->MaybeResolve(JS::UndefinedHandleValue); doc->SetOrientationPendingPromise(nullptr); } nsCOMPtr<nsIRunnable> runnable = NewRunnableMethod(this, &ScreenOrientation::DispatchChangeEvent); rv = NS_DispatchToMainThread(runnable); NS_WARN_IF(NS_FAILED(rv)); } }
NS_IMETHODIMP ScreenOrientation::VisibleEventListener::HandleEvent(nsIDOMEvent* aEvent) { // Document may have become visible, if the page is visible, run the steps // following the "now visible algorithm" as specified. nsCOMPtr<EventTarget> target = aEvent->InternalDOMEvent()->GetCurrentTarget(); MOZ_ASSERT(target); nsCOMPtr<nsIDocument> doc = do_QueryInterface(target); if (!doc || doc->Hidden()) { return NS_OK; } auto* win = nsGlobalWindow::Cast(doc->GetInnerWindow()); if (!win) { return NS_OK; } ErrorResult rv; nsScreen* screen = win->GetScreen(rv); if (NS_WARN_IF(rv.Failed())) { return rv.StealNSResult(); } MOZ_ASSERT(screen); ScreenOrientation* orientation = screen->Orientation(); MOZ_ASSERT(orientation); rv = target->RemoveSystemEventListener(NS_LITERAL_STRING("visibilitychange"), this, true); if (NS_WARN_IF(rv.Failed())) { return rv.StealNSResult(); } if (doc->CurrentOrientationType() != orientation->DeviceType()) { doc->SetCurrentOrientation(orientation->DeviceType(), orientation->DeviceAngle()); Promise* pendingPromise = doc->GetOrientationPendingPromise(); if (pendingPromise) { pendingPromise->MaybeResolve(JS::UndefinedHandleValue); doc->SetOrientationPendingPromise(nullptr); } nsCOMPtr<nsIRunnable> runnable = NewRunnableMethod(orientation, &ScreenOrientation::DispatchChangeEvent); rv = NS_DispatchToMainThread(runnable); if (NS_WARN_IF(rv.Failed())) { return rv.StealNSResult(); } } return NS_OK; }
void AudioContext::OnStateChanged(void* aPromise, AudioContextState aNewState) { MOZ_ASSERT(NS_IsMainThread()); // This can happen if close() was called right after creating the // AudioContext, before the context has switched to "running". if (mAudioContextState == AudioContextState::Closed && aNewState == AudioContextState::Running && !aPromise) { return; } #ifndef WIN32 // Bug 1170547 MOZ_ASSERT((mAudioContextState == AudioContextState::Suspended && aNewState == AudioContextState::Running) || (mAudioContextState == AudioContextState::Running && aNewState == AudioContextState::Suspended) || (mAudioContextState == AudioContextState::Running && aNewState == AudioContextState::Closed) || (mAudioContextState == AudioContextState::Suspended && aNewState == AudioContextState::Closed) || (mAudioContextState == aNewState), "Invalid AudioContextState transition"); #endif // WIN32 MOZ_ASSERT( mIsOffline || aPromise || aNewState == AudioContextState::Running, "We should have a promise here if this is a real-time AudioContext." "Or this is the first time we switch to \"running\"."); if (aPromise) { Promise* promise = reinterpret_cast<Promise*>(aPromise); promise->MaybeResolve(JS::UndefinedHandleValue); DebugOnly<bool> rv = mPromiseGripArray.RemoveElement(promise); MOZ_ASSERT(rv, "Promise wasn't in the grip array?"); } if (mAudioContextState != aNewState) { RefPtr<OnStateChangeTask> onStateChangeTask = new OnStateChangeTask(this); NS_DispatchToMainThread(onStateChangeTask); } mAudioContextState = aNewState; }
void AudioContext::OnStateChanged(void* aPromise, AudioContextState aNewState) { MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT((mAudioContextState == AudioContextState::Suspended && aNewState == AudioContextState::Running) || (mAudioContextState == AudioContextState::Running && aNewState == AudioContextState::Suspended) || (mAudioContextState == AudioContextState::Running && aNewState == AudioContextState::Closed) || (mAudioContextState == AudioContextState::Suspended && aNewState == AudioContextState::Closed) || (mAudioContextState == aNewState), "Invalid AudioContextState transition"); MOZ_ASSERT( mIsOffline || aPromise || aNewState == AudioContextState::Running, "We should have a promise here if this is a real-time AudioContext." "Or this is the first time we switch to \"running\"."); if (aPromise) { Promise* promise = reinterpret_cast<Promise*>(aPromise); promise->MaybeResolve(JS::UndefinedHandleValue); DebugOnly<bool> rv = mPromiseGripArray.RemoveElement(promise); MOZ_ASSERT(rv, "Promise wasn't in the grip array?"); } if (mAudioContextState != aNewState) { nsRefPtr<OnStateChangeTask> onStateChangeTask = new OnStateChangeTask(this); NS_DispatchToMainThread(onStateChangeTask); } mAudioContextState = aNewState; }