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;
}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
}