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); DebugOnly<nsresult> rv; if (mScreen && mType != previousOrientation) { // Use of mozorientationchange is deprecated. rv = mScreen->DispatchTrustedEvent(NS_LITERAL_STRING("mozorientationchange")); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "DispatchTrustedEvent failed"); } if (doc->Hidden() && !mVisibleListener) { mVisibleListener = new VisibleEventListener(); rv = doc->AddSystemEventListener(NS_LITERAL_STRING("visibilitychange"), mVisibleListener, /* useCapture = */ true); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "AddSystemEventListener failed"); return; } if (mType != doc->CurrentOrientationType()) { doc->SetCurrentOrientation(mType, mAngle); Promise* pendingPromise = doc->GetOrientationPendingPromise(); if (pendingPromise) { pendingPromise->MaybeResolveWithUndefined(); doc->SetOrientationPendingPromise(nullptr); } nsCOMPtr<nsIRunnable> runnable = NewRunnableMethod(this, &ScreenOrientation::DispatchChangeEvent); rv = NS_DispatchToMainThread(runnable); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "NS_DispatchToMainThread failed"); } }
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(CallerType::System)) { doc->SetCurrentOrientation(orientation->DeviceType(CallerType::System), orientation->DeviceAngle(CallerType::System)); Promise* pendingPromise = doc->GetOrientationPendingPromise(); if (pendingPromise) { pendingPromise->MaybeResolveWithUndefined(); 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; } // This can happen if this is called in reaction to a // MediaStreamGraph shutdown, and a AudioContext was being // suspended at the same time, for example if a page was being // closed. if (mAudioContextState == AudioContextState::Closed && aNewState == AudioContextState::Suspended) { return; } #ifndef WIN32 // Bug 1170547 #ifndef XP_MACOSX #ifdef DEBUG if (!((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))) { fprintf(stderr, "Invalid transition: mAudioContextState: %d -> aNewState %d\n", static_cast<int>(mAudioContextState), static_cast<int>(aNewState)); MOZ_ASSERT(false); } #endif // DEBUG #endif // XP_MACOSX #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->MaybeResolveWithUndefined(); 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; }