Commit 28290f66 authored by Emilio Cobos Álvarez's avatar Emilio Cobos Álvarez
Browse files

Bug 1754858 - Simplify screen orientation API implementation. r=smaug,m_kato,geckoview-reviewers

Make the ScreenOrientation part of the screen struct, as it should. Stop
using HAL to propagate just screen orientation updates, use the more
general screen manager.

Instead of HAL observers, add a simple observer service notification,
and clean a bunch of the code.

This will simplify bug 1754802 a bit, and is generally simpler.
Shouldn't change behavior. I've tested the events and some common
orientation locking use cases like Youtube, and they behave the same.

Differential Revision: https://phabricator.services.mozilla.com/D138477
parent 999c849e
Loading
Loading
Loading
Loading
+23 −23
Original line number Diff line number Diff line
@@ -71,12 +71,8 @@ ScreenOrientation::ScreenOrientation(nsPIDOMWindowInner* aWindow,
  MOZ_ASSERT(aWindow);
  MOZ_ASSERT(aScreen);

  hal::RegisterScreenConfigurationObserver(this);

  hal::ScreenConfiguration config;
  hal::GetCurrentScreenConfiguration(&config);
  mType = InternalOrientationToType(config.orientation());
  mAngle = config.angle();
  mAngle = aScreen->GetOrientationAngle();
  mType = InternalOrientationToType(aScreen->GetOrientationType());

  Document* doc = GetResponsibleDocument();
  BrowsingContext* bc = doc ? doc->GetBrowsingContext() : nullptr;
@@ -87,7 +83,7 @@ ScreenOrientation::ScreenOrientation(nsPIDOMWindowInner* aWindow,

ScreenOrientation::~ScreenOrientation() {
  UnlockDeviceOrientation();
  hal::UnregisterScreenConfigurationObserver(this);

  MOZ_ASSERT(!mFullscreenListener);
}

@@ -152,6 +148,8 @@ ScreenOrientation::LockOrientationTask::LockOrientationTask(

ScreenOrientation::LockOrientationTask::~LockOrientationTask() = default;

using LockOrientationPromise = MozPromise<bool, bool, false>;

bool ScreenOrientation::LockOrientationTask::OrientationLockContains(
    OrientationType aOrientationType) {
  return bool(mOrientationLock & OrientationTypeToInternal(aOrientationType));
@@ -186,7 +184,7 @@ ScreenOrientation::LockOrientationTask::Run() {
    return NS_OK;
  }

  RefPtr<MozPromise<bool, bool, false>> lockOrientationPromise =
  RefPtr<LockOrientationPromise> lockOrientationPromise =
      mScreenOrientation->LockDeviceOrientation(mOrientationLock,
                                                mIsFullscreen);

@@ -199,8 +197,7 @@ ScreenOrientation::LockOrientationTask::Run() {
  lockOrientationPromise->Then(
      GetCurrentSerialEventTarget(), __func__,
      [self = RefPtr{this}](
          const mozilla::MozPromise<bool, bool, false>::ResolveOrRejectValue&
              aValue) {
          const LockOrientationPromise::ResolveOrRejectValue& aValue) {
        if (aValue.IsResolve()) {
          return NS_OK;
        }
@@ -362,10 +359,10 @@ already_AddRefed<Promise> ScreenOrientation::LockInternal(
#endif
}

RefPtr<MozPromise<bool, bool, false>> ScreenOrientation::LockDeviceOrientation(
RefPtr<LockOrientationPromise> ScreenOrientation::LockDeviceOrientation(
    hal::ScreenOrientation aOrientation, bool aIsFullscreen) {
  if (!GetOwner()) {
    return MozPromise<bool, bool, false>::CreateAndReject(false, __func__);
    return LockOrientationPromise::CreateAndReject(false, __func__);
  }

  nsCOMPtr<EventTarget> target = GetOwner()->GetDoc();
@@ -374,7 +371,7 @@ RefPtr<MozPromise<bool, bool, false>> ScreenOrientation::LockDeviceOrientation(
  // This needs to be done before LockScreenOrientation call to make sure
  // the locking can be unlocked.
  if (aIsFullscreen && !target) {
    return MozPromise<bool, bool, false>::CreateAndReject(false, __func__);
    return LockOrientationPromise::CreateAndReject(false, __func__);
  }

  // We are fullscreen and lock has been accepted.
@@ -387,16 +384,17 @@ RefPtr<MozPromise<bool, bool, false>> ScreenOrientation::LockDeviceOrientation(
                                                 mFullscreenListener,
                                                 /* aUseCapture = */ true);
    if (NS_WARN_IF(NS_FAILED(rv))) {
      return MozPromise<bool, bool, false>::CreateAndReject(false, __func__);
      return LockOrientationPromise::CreateAndReject(false, __func__);
    }
  }

  RefPtr<MozPromise<bool, bool, false>> halPromise =
  RefPtr<LockOrientationPromise> halPromise =
      hal::LockScreenOrientation(aOrientation);
  if (halPromise == nullptr) {
    return MozPromise<bool, bool, false>::CreateAndReject(false, __func__);
  if (!halPromise) {
    return LockOrientationPromise::CreateAndReject(false, __func__);
  }

  mTriedToLockDeviceOrientation = true;
  return halPromise;
}

@@ -405,7 +403,10 @@ void ScreenOrientation::Unlock(ErrorResult& aRv) {
}

void ScreenOrientation::UnlockDeviceOrientation() {
  if (mTriedToLockDeviceOrientation) {
    hal::UnlockScreenOrientation();
    mTriedToLockDeviceOrientation = false;
  }

  if (!mFullscreenListener || !GetOwner()) {
    mFullscreenListener = nullptr;
@@ -413,8 +414,7 @@ void ScreenOrientation::UnlockDeviceOrientation() {
  }

  // Remove event listener in case of fullscreen lock.
  nsCOMPtr<EventTarget> target = GetOwner()->GetDoc();
  if (target) {
  if (nsCOMPtr<EventTarget> target = GetOwner()->GetDoc()) {
    target->RemoveSystemEventListener(u"fullscreenchange"_ns,
                                      mFullscreenListener,
                                      /* useCapture */ true);
@@ -505,7 +505,7 @@ Document* ScreenOrientation::GetResponsibleDocument() const {
  return owner->GetDoc();
}

void ScreenOrientation::Notify(const hal::ScreenConfiguration& aConfiguration) {
void ScreenOrientation::MaybeChanged() {
  if (ShouldResistFingerprinting()) {
    return;
  }
@@ -516,7 +516,7 @@ void ScreenOrientation::Notify(const hal::ScreenConfiguration& aConfiguration) {
    return;
  }

  hal::ScreenOrientation orientation = aConfiguration.orientation();
  hal::ScreenOrientation orientation = mScreen->GetOrientationType();
  if (orientation != hal::ScreenOrientation::PortraitPrimary &&
      orientation != hal::ScreenOrientation::PortraitSecondary &&
      orientation != hal::ScreenOrientation::LandscapePrimary &&
@@ -529,7 +529,7 @@ void ScreenOrientation::Notify(const hal::ScreenConfiguration& aConfiguration) {
  }

  OrientationType previousOrientation = mType;
  mAngle = aConfiguration.angle();
  mAngle = mScreen->GetOrientationAngle();
  mType = InternalOrientationToType(orientation);

  DebugOnly<nsresult> rv;
+12 −7
Original line number Diff line number Diff line
@@ -20,9 +20,7 @@ namespace dom {

class Promise;

class ScreenOrientation final
    : public DOMEventTargetHelper,
      public mozilla::hal::ScreenConfigurationObserver {
class ScreenOrientation final : public DOMEventTargetHelper {
  // nsScreen has deprecated API that shares implementation.
  friend class ::nsScreen;

@@ -33,6 +31,9 @@ class ScreenOrientation final

  IMPL_EVENT_HANDLER(change)

  // Called when the orientation may have changed.
  void MaybeChanged();

  ScreenOrientation(nsPIDOMWindowInner* aWindow, nsScreen* aScreen);

  already_AddRefed<Promise> Lock(OrientationLockType aOrientation,
@@ -49,11 +50,9 @@ class ScreenOrientation final
  OrientationType GetType(CallerType aCallerType, ErrorResult& aRv) const;
  uint16_t GetAngle(CallerType aCallerType, ErrorResult& aRv) const;

  virtual JSObject* WrapObject(JSContext* aCx,
  JSObject* WrapObject(JSContext* aCx,
                       JS::Handle<JSObject*> aGivenProto) override;

  void Notify(const mozilla::hal::ScreenConfiguration& aConfiguration) override;

  static void UpdateActiveOrientationLock(hal::ScreenOrientation aOrientation);
  static void AbortInProcessOrientationPromises(
      BrowsingContext* aBrowsingContext);
@@ -103,6 +102,12 @@ class ScreenOrientation final
  RefPtr<VisibleEventListener> mVisibleListener;
  OrientationType mType;
  uint16_t mAngle;
  // Whether we've tried to call into hal to lock the device orientation. This
  // is needed because you don't want calling UnlockDeviceOrientation() during
  // shutdown to initialize PHal if it hasn't been initialized earlier. Also,
  // makes sense (there's no reason destroying a ScreenOrientation object from a
  // different window should remove the orientation lock).
  bool mTriedToLockDeviceOrientation = false;
};

}  // namespace dom
+0 −52
Original line number Diff line number Diff line
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "WindowOrientationObserver.h"

#include "nsGlobalWindow.h"
#include "mozilla/Hal.h"

using namespace mozilla::dom;

/**
 * This class is used by nsGlobalWindowInner to implement window.orientation
 * and window.onorientationchange. This class is defined in its own file
 * because Hal.h pulls in windows.h and can't be included from
 * nsGlobalWindow.cpp
 */
WindowOrientationObserver::WindowOrientationObserver(
    nsGlobalWindowInner* aGlobalWindow)
    : mWindow(aGlobalWindow) {
  MOZ_ASSERT(aGlobalWindow);
  hal::RegisterScreenConfigurationObserver(this);

  hal::ScreenConfiguration config;
  hal::GetCurrentScreenConfiguration(&config);
  mAngle = config.angle();
}

WindowOrientationObserver::~WindowOrientationObserver() {
  hal::UnregisterScreenConfigurationObserver(this);
}

void WindowOrientationObserver::Notify(
    const mozilla::hal::ScreenConfiguration& aConfiguration) {
  uint16_t currentAngle = aConfiguration.angle();
  if (mAngle != currentAngle && mWindow->IsCurrentInnerWindow()) {
    mAngle = currentAngle;
    mWindow->GetOuterWindow()->DispatchCustomEvent(u"orientationchange"_ns);
  }
}

/* static */
int16_t WindowOrientationObserver::OrientationAngle() {
  hal::ScreenConfiguration config;
  hal::GetCurrentScreenConfiguration(&config);
  int16_t angle = static_cast<int16_t>(config.angle());
  // config.angle() returns 0, 90, 180 or 270.
  // window.orientation returns -90, 0, 90 or 180.
  return angle <= 180 ? angle : angle - 360;
}
+0 −34
Original line number Diff line number Diff line
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef mozilla_dom_WindowOrientationObserver_h
#define mozilla_dom_WindowOrientationObserver_h

#include "mozilla/HalScreenConfiguration.h"

class nsGlobalWindowInner;

namespace mozilla {
namespace dom {

class WindowOrientationObserver final
    : public mozilla::hal::ScreenConfigurationObserver {
 public:
  explicit WindowOrientationObserver(nsGlobalWindowInner* aGlobalWindow);
  ~WindowOrientationObserver();
  void Notify(const mozilla::hal::ScreenConfiguration& aConfiguration) override;
  static int16_t OrientationAngle();

 private:
  // Weak pointer, instance is owned by mWindow.
  nsGlobalWindowInner* MOZ_NON_OWNING_REF mWindow;
  uint16_t mAngle;
};

}  // namespace dom
}  // namespace mozilla

#endif  // mozilla_dom_WindowOrientationObserver_h
+0 −2
Original line number Diff line number Diff line
@@ -286,7 +286,6 @@ EXPORTS.mozilla.dom += [
    "ViewportMetaData.h",
    "VisualViewport.h",
    "WindowFeatures.h",
    "WindowOrientationObserver.h",
    "WindowProxyHolder.h",
]

@@ -464,7 +463,6 @@ UNIFIED_SOURCES += [
    "WindowDestroyedEvent.cpp",
    "WindowFeatures.cpp",
    "WindowNamedPropertiesHandler.cpp",
    "WindowOrientationObserver.cpp",
    "XPathGenerator.cpp",
]

Loading