LCOV - code coverage report
Current view: top level - dom/base - ScreenOrientation.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 22 295 7.5 %
Date: 2017-07-14 16:53:18 Functions: 5 45 11.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* This Source Code Form is subject to the terms of the Mozilla Public
       2             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       3             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       4             : 
       5             : #include "ScreenOrientation.h"
       6             : #include "nsIDeviceSensors.h"
       7             : #include "nsIDocShell.h"
       8             : #include "nsIDocument.h"
       9             : #include "nsGlobalWindow.h"
      10             : #include "nsSandboxFlags.h"
      11             : #include "nsScreen.h"
      12             : 
      13             : #include "mozilla/DOMEventTargetHelper.h"
      14             : #include "mozilla/Hal.h"
      15             : #include "mozilla/Preferences.h"
      16             : 
      17             : #include "mozilla/dom/Promise.h"
      18             : #include "nsContentUtils.h"
      19             : 
      20             : using namespace mozilla;
      21             : using namespace mozilla::dom;
      22             : 
      23           0 : NS_IMPL_CYCLE_COLLECTION_INHERITED(ScreenOrientation,
      24             :                                    DOMEventTargetHelper,
      25             :                                    mScreen);
      26             : 
      27           1 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ScreenOrientation)
      28           0 : NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
      29             : 
      30           1 : NS_IMPL_ADDREF_INHERITED(ScreenOrientation, DOMEventTargetHelper)
      31           0 : NS_IMPL_RELEASE_INHERITED(ScreenOrientation, DOMEventTargetHelper)
      32             : 
      33             : static OrientationType
      34           1 : InternalOrientationToType(ScreenOrientationInternal aOrientation)
      35             : {
      36           1 :   switch (aOrientation) {
      37             :   case eScreenOrientation_PortraitPrimary:
      38           0 :     return OrientationType::Portrait_primary;
      39             :   case eScreenOrientation_PortraitSecondary:
      40           0 :     return OrientationType::Portrait_secondary;
      41             :   case eScreenOrientation_LandscapePrimary:
      42           1 :     return OrientationType::Landscape_primary;
      43             :   case eScreenOrientation_LandscapeSecondary:
      44           0 :     return OrientationType::Landscape_secondary;
      45             :   default:
      46           0 :     MOZ_CRASH("Bad aOrientation value");
      47             :   }
      48             : }
      49             : 
      50             : static ScreenOrientationInternal
      51           0 : OrientationTypeToInternal(OrientationType aOrientation)
      52             : {
      53           0 :   switch (aOrientation) {
      54             :   case OrientationType::Portrait_primary:
      55           0 :     return eScreenOrientation_PortraitPrimary;
      56             :   case OrientationType::Portrait_secondary:
      57           0 :     return eScreenOrientation_PortraitSecondary;
      58             :   case OrientationType::Landscape_primary:
      59           0 :     return eScreenOrientation_LandscapePrimary;
      60             :   case OrientationType::Landscape_secondary:
      61           0 :     return eScreenOrientation_LandscapeSecondary;
      62             :   default:
      63           0 :     MOZ_CRASH("Bad aOrientation value");
      64             :   }
      65             : }
      66             : 
      67           1 : ScreenOrientation::ScreenOrientation(nsPIDOMWindowInner* aWindow, nsScreen* aScreen)
      68           1 :   : DOMEventTargetHelper(aWindow), mScreen(aScreen)
      69             : {
      70           1 :   MOZ_ASSERT(aWindow);
      71           1 :   MOZ_ASSERT(aScreen);
      72             : 
      73           1 :   hal::RegisterScreenConfigurationObserver(this);
      74             : 
      75           2 :   hal::ScreenConfiguration config;
      76           1 :   hal::GetCurrentScreenConfiguration(&config);
      77           1 :   mType = InternalOrientationToType(config.orientation());
      78           1 :   mAngle = config.angle();
      79             : 
      80           1 :   nsIDocument* doc = GetResponsibleDocument();
      81           1 :   if (doc) {
      82           1 :     doc->SetCurrentOrientation(mType, mAngle);
      83             :   }
      84           1 : }
      85             : 
      86           0 : ScreenOrientation::~ScreenOrientation()
      87             : {
      88           0 :   hal::UnregisterScreenConfigurationObserver(this);
      89           0 :   MOZ_ASSERT(!mFullScreenListener);
      90           0 : }
      91             : 
      92             : class ScreenOrientation::FullScreenEventListener final : public nsIDOMEventListener
      93             : {
      94           0 :   ~FullScreenEventListener() {}
      95             : public:
      96           0 :   FullScreenEventListener() {}
      97             : 
      98             :   NS_DECL_ISUPPORTS
      99             :   NS_DECL_NSIDOMEVENTLISTENER
     100             : };
     101             : 
     102             : class ScreenOrientation::VisibleEventListener final : public nsIDOMEventListener
     103             : {
     104           0 :   ~VisibleEventListener() {}
     105             : public:
     106           0 :   VisibleEventListener() {}
     107             : 
     108             :   NS_DECL_ISUPPORTS
     109             :   NS_DECL_NSIDOMEVENTLISTENER
     110             : };
     111             : 
     112             : class ScreenOrientation::LockOrientationTask final : public nsIRunnable
     113             : {
     114             :   ~LockOrientationTask();
     115             : public:
     116             :   NS_DECL_ISUPPORTS
     117             :   NS_DECL_NSIRUNNABLE
     118             : 
     119             :   LockOrientationTask(ScreenOrientation* aScreenOrientation,
     120             :                       Promise* aPromise,
     121             :                       ScreenOrientationInternal aOrientationLock,
     122             :                       nsIDocument* aDocument,
     123             :                       bool aIsFullScreen);
     124             : protected:
     125             :   bool OrientationLockContains(OrientationType aOrientationType);
     126             : 
     127             :   RefPtr<ScreenOrientation> mScreenOrientation;
     128             :   RefPtr<Promise> mPromise;
     129             :   ScreenOrientationInternal mOrientationLock;
     130             :   nsCOMPtr<nsIDocument> mDocument;
     131             :   bool mIsFullScreen;
     132             : };
     133             : 
     134           0 : NS_IMPL_ISUPPORTS(ScreenOrientation::LockOrientationTask, nsIRunnable)
     135             : 
     136           0 : ScreenOrientation::LockOrientationTask::LockOrientationTask(
     137             :   ScreenOrientation* aScreenOrientation, Promise* aPromise,
     138             :   ScreenOrientationInternal aOrientationLock,
     139           0 :   nsIDocument* aDocument, bool aIsFullScreen)
     140             :   : mScreenOrientation(aScreenOrientation), mPromise(aPromise),
     141             :     mOrientationLock(aOrientationLock), mDocument(aDocument),
     142           0 :     mIsFullScreen(aIsFullScreen)
     143             : {
     144           0 :   MOZ_ASSERT(aScreenOrientation);
     145           0 :   MOZ_ASSERT(aPromise);
     146           0 :   MOZ_ASSERT(aDocument);
     147           0 : }
     148             : 
     149           0 : ScreenOrientation::LockOrientationTask::~LockOrientationTask()
     150             : {
     151           0 : }
     152             : 
     153             : bool
     154           0 : ScreenOrientation::LockOrientationTask::OrientationLockContains(
     155             :   OrientationType aOrientationType)
     156             : {
     157           0 :   return mOrientationLock & OrientationTypeToInternal(aOrientationType);
     158             : }
     159             : 
     160             : NS_IMETHODIMP
     161           0 : ScreenOrientation::LockOrientationTask::Run()
     162             : {
     163             :   // Step to lock the orientation as defined in the spec.
     164             : 
     165           0 :   if (mDocument->GetOrientationPendingPromise() != mPromise) {
     166             :     // The document's pending promise is not associated with this task
     167             :     // to lock orientation. There has since been another request to
     168             :     // lock orientation, thus we don't need to do anything. Old promise
     169             :     // should be been rejected.
     170           0 :     return NS_OK;
     171             :   }
     172             : 
     173           0 :   if (mDocument->Hidden()) {
     174             :     // Active orientation lock is not the document's orientation lock.
     175           0 :     mPromise->MaybeResolveWithUndefined();
     176           0 :     mDocument->SetOrientationPendingPromise(nullptr);
     177           0 :     return NS_OK;
     178             :   }
     179             : 
     180           0 :   if (mOrientationLock == eScreenOrientation_None) {
     181           0 :     mScreenOrientation->UnlockDeviceOrientation();
     182           0 :     mPromise->MaybeResolveWithUndefined();
     183           0 :     mDocument->SetOrientationPendingPromise(nullptr);
     184           0 :     return NS_OK;
     185             :   }
     186             : 
     187           0 :   ErrorResult rv;
     188           0 :   bool result = mScreenOrientation->LockDeviceOrientation(mOrientationLock,
     189           0 :                                                           mIsFullScreen, rv);
     190           0 :   if (NS_WARN_IF(rv.Failed())) {
     191           0 :     return rv.StealNSResult();
     192             :   }
     193             : 
     194           0 :   if (NS_WARN_IF(!result)) {
     195           0 :     mPromise->MaybeReject(NS_ERROR_UNEXPECTED);
     196           0 :     mDocument->SetOrientationPendingPromise(nullptr);
     197           0 :     return NS_OK;
     198             :   }
     199             : 
     200           0 :   if (OrientationLockContains(mDocument->CurrentOrientationType()) ||
     201           0 :       (mOrientationLock == eScreenOrientation_Default &&
     202           0 :        mDocument->CurrentOrientationAngle() == 0)) {
     203             :     // Orientation lock will not cause an orientation change.
     204           0 :     mPromise->MaybeResolveWithUndefined();
     205           0 :     mDocument->SetOrientationPendingPromise(nullptr);
     206             :   }
     207             : 
     208           0 :   return NS_OK;
     209             : }
     210             : 
     211             : already_AddRefed<Promise>
     212           0 : ScreenOrientation::Lock(OrientationLockType aOrientation, ErrorResult& aRv)
     213             : {
     214           0 :   ScreenOrientationInternal orientation = eScreenOrientation_None;
     215             : 
     216           0 :   switch (aOrientation) {
     217             :   case OrientationLockType::Any:
     218           0 :     orientation = eScreenOrientation_PortraitPrimary |
     219             :                   eScreenOrientation_PortraitSecondary |
     220             :                   eScreenOrientation_LandscapePrimary |
     221             :                   eScreenOrientation_LandscapeSecondary;
     222           0 :     break;
     223             :   case OrientationLockType::Natural:
     224           0 :     orientation |= eScreenOrientation_Default;
     225           0 :     break;
     226             :   case OrientationLockType::Landscape:
     227           0 :     orientation = eScreenOrientation_LandscapePrimary |
     228             :                   eScreenOrientation_LandscapeSecondary;
     229           0 :     break;
     230             :   case OrientationLockType::Portrait:
     231           0 :     orientation = eScreenOrientation_PortraitPrimary |
     232             :                   eScreenOrientation_PortraitSecondary;
     233           0 :     break;
     234             :   case OrientationLockType::Portrait_primary:
     235           0 :     orientation = eScreenOrientation_PortraitPrimary;
     236           0 :     break;
     237             :   case OrientationLockType::Portrait_secondary:
     238           0 :     orientation = eScreenOrientation_PortraitSecondary;
     239           0 :     break;
     240             :   case OrientationLockType::Landscape_primary:
     241           0 :     orientation = eScreenOrientation_LandscapePrimary;
     242           0 :     break;
     243             :   case OrientationLockType::Landscape_secondary:
     244           0 :     orientation = eScreenOrientation_LandscapeSecondary;
     245           0 :     break;
     246             :   default:
     247           0 :     NS_WARNING("Unexpected orientation type");
     248           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
     249           0 :     return nullptr;
     250             :   }
     251             : 
     252           0 :   return LockInternal(orientation, aRv);
     253             : }
     254             : 
     255             : static inline void
     256             : AbortOrientationPromises(nsIDocShell* aDocShell)
     257             : {
     258             :   MOZ_ASSERT(aDocShell);
     259             : 
     260             :   nsIDocument* doc = aDocShell->GetDocument();
     261             :   if (doc) {
     262             :     Promise* promise = doc->GetOrientationPendingPromise();
     263             :     if (promise) {
     264             :       promise->MaybeReject(NS_ERROR_DOM_ABORT_ERR);
     265             :       doc->SetOrientationPendingPromise(nullptr);
     266             :     }
     267             :   }
     268             : 
     269             :   int32_t childCount;
     270             :   aDocShell->GetChildCount(&childCount);
     271             :   for (int32_t i = 0; i < childCount; i++) {
     272             :     nsCOMPtr<nsIDocShellTreeItem> child;
     273             :     if (NS_SUCCEEDED(aDocShell->GetChildAt(i, getter_AddRefs(child)))) {
     274             :       nsCOMPtr<nsIDocShell> childShell(do_QueryInterface(child));
     275             :       if (childShell) {
     276             :         AbortOrientationPromises(childShell);
     277             :       }
     278             :     }
     279             :   }
     280             : }
     281             : 
     282             : already_AddRefed<Promise>
     283           0 : ScreenOrientation::LockInternal(ScreenOrientationInternal aOrientation, ErrorResult& aRv)
     284             : {
     285             :   // Steps to apply an orientation lock as defined in spec.
     286             : 
     287           0 :   nsIDocument* doc = GetResponsibleDocument();
     288           0 :   if (NS_WARN_IF(!doc)) {
     289           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
     290           0 :     return nullptr;
     291             :   }
     292             : 
     293           0 :   nsCOMPtr<nsPIDOMWindowInner> owner = GetOwner();
     294           0 :   if (NS_WARN_IF(!owner)) {
     295           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
     296           0 :     return nullptr;
     297             :   }
     298             : 
     299           0 :   nsCOMPtr<nsIDocShell> docShell = owner->GetDocShell();
     300           0 :   if (NS_WARN_IF(!docShell)) {
     301           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
     302           0 :     return nullptr;
     303             :   }
     304             : 
     305           0 :   nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(owner);
     306           0 :   MOZ_ASSERT(go);
     307           0 :   RefPtr<Promise> p = Promise::Create(go, aRv);
     308           0 :   if (NS_WARN_IF(aRv.Failed())) {
     309           0 :     return nullptr;
     310             :   }
     311             : 
     312             : #if !defined(MOZ_WIDGET_ANDROID) && !defined(MOZ_WIDGET_GONK)
     313             :   // User agent does not support locking the screen orientation.
     314           0 :   p->MaybeReject(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
     315           0 :   return p.forget();
     316             : #else
     317             :   LockPermission perm = GetLockOrientationPermission(true);
     318             :   if (perm == LOCK_DENIED) {
     319             :     p->MaybeReject(NS_ERROR_DOM_SECURITY_ERR);
     320             :     return p.forget();
     321             :   }
     322             : 
     323             :   nsCOMPtr<nsIDocShellTreeItem> root;
     324             :   docShell->GetSameTypeRootTreeItem(getter_AddRefs(root));
     325             :   nsCOMPtr<nsIDocShell> rootShell(do_QueryInterface(root));
     326             :   if (!rootShell) {
     327             :     aRv.Throw(NS_ERROR_UNEXPECTED);
     328             :     return nullptr;
     329             :   }
     330             : 
     331             :   rootShell->SetOrientationLock(aOrientation);
     332             :   AbortOrientationPromises(rootShell);
     333             : 
     334             :   doc->SetOrientationPendingPromise(p);
     335             : 
     336             :   nsCOMPtr<nsIRunnable> lockOrientationTask =
     337             :     new LockOrientationTask(this, p, aOrientation, doc,
     338             :                             perm == FULLSCREEN_LOCK_ALLOWED);
     339             :   aRv = NS_DispatchToMainThread(lockOrientationTask);
     340             :   if (NS_WARN_IF(aRv.Failed())) {
     341             :     return nullptr;
     342             :   }
     343             : 
     344             :   return p.forget();
     345             : #endif
     346             : }
     347             : 
     348             : bool
     349           0 : ScreenOrientation::LockDeviceOrientation(ScreenOrientationInternal aOrientation,
     350             :                                          bool aIsFullScreen, ErrorResult& aRv)
     351             : {
     352           0 :   if (!GetOwner()) {
     353           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
     354           0 :     return false;
     355             :   }
     356             : 
     357           0 :   nsCOMPtr<EventTarget> target = do_QueryInterface(GetOwner()->GetDoc());
     358             :   // We need to register a listener so we learn when we leave full-screen
     359             :   // and when we will have to unlock the screen.
     360             :   // This needs to be done before LockScreenOrientation call to make sure
     361             :   // the locking can be unlocked.
     362           0 :   if (aIsFullScreen && !target) {
     363           0 :     return false;
     364             :   }
     365             : 
     366           0 :   if (NS_WARN_IF(!hal::LockScreenOrientation(aOrientation))) {
     367           0 :     return false;
     368             :   }
     369             : 
     370             :   // We are fullscreen and lock has been accepted.
     371           0 :   if (aIsFullScreen) {
     372           0 :     if (!mFullScreenListener) {
     373           0 :       mFullScreenListener = new FullScreenEventListener();
     374             :     }
     375             : 
     376           0 :     aRv = target->AddSystemEventListener(NS_LITERAL_STRING("fullscreenchange"),
     377           0 :                                          mFullScreenListener, /* useCapture = */ true);
     378           0 :     if (NS_WARN_IF(aRv.Failed())) {
     379           0 :       return false;
     380             :     }
     381             :   }
     382             : 
     383           0 :   return true;
     384             : }
     385             : 
     386             : void
     387           0 : ScreenOrientation::Unlock(ErrorResult& aRv)
     388             : {
     389           0 :   RefPtr<Promise> p = LockInternal(eScreenOrientation_None, aRv);
     390           0 : }
     391             : 
     392             : void
     393           0 : ScreenOrientation::UnlockDeviceOrientation()
     394             : {
     395           0 :   hal::UnlockScreenOrientation();
     396             : 
     397           0 :   if (!mFullScreenListener || !GetOwner()) {
     398           0 :     mFullScreenListener = nullptr;
     399           0 :     return;
     400             :   }
     401             : 
     402             :   // Remove event listener in case of fullscreen lock.
     403           0 :   nsCOMPtr<EventTarget> target = do_QueryInterface(GetOwner()->GetDoc());
     404           0 :   if (target) {
     405             :     DebugOnly<nsresult> rv =
     406           0 :       target->RemoveSystemEventListener(NS_LITERAL_STRING("fullscreenchange"),
     407             :                                         mFullScreenListener,
     408           0 :                                         /* useCapture */ true);
     409           0 :     NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "RemoveSystemEventListener failed");
     410             :   }
     411             : 
     412           0 :   mFullScreenListener = nullptr;
     413             : }
     414             : 
     415             : OrientationType
     416           0 : ScreenOrientation::DeviceType(CallerType aCallerType) const
     417             : {
     418           0 :   return nsContentUtils::ResistFingerprinting(aCallerType) ?
     419           0 :     OrientationType::Landscape_primary : mType;
     420             : }
     421             : 
     422             : uint16_t
     423           0 : ScreenOrientation::DeviceAngle(CallerType aCallerType) const
     424             : {
     425           0 :   return nsContentUtils::ResistFingerprinting(aCallerType) ? 0 : mAngle;
     426             : }
     427             : 
     428             : OrientationType
     429           0 : ScreenOrientation::GetType(CallerType aCallerType, ErrorResult& aRv) const
     430             : {
     431           0 :   if (nsContentUtils::ResistFingerprinting(aCallerType)) {
     432           0 :     return OrientationType::Landscape_primary;
     433             :   }
     434             : 
     435           0 :   nsIDocument* doc = GetResponsibleDocument();
     436           0 :   if (!doc) {
     437           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
     438           0 :     return OrientationType::Portrait_primary;
     439             :   }
     440             : 
     441           0 :   return doc->CurrentOrientationType();
     442             : }
     443             : 
     444             : uint16_t
     445           0 : ScreenOrientation::GetAngle(CallerType aCallerType, ErrorResult& aRv) const
     446             : {
     447           0 :   if (nsContentUtils::ResistFingerprinting(aCallerType)) {
     448           0 :     return 0;
     449             :   }
     450             : 
     451           0 :   nsIDocument* doc = GetResponsibleDocument();
     452           0 :   if (!doc) {
     453           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
     454           0 :     return 0;
     455             :   }
     456             : 
     457           0 :   return doc->CurrentOrientationAngle();
     458             : }
     459             : 
     460             : ScreenOrientation::LockPermission
     461           0 : ScreenOrientation::GetLockOrientationPermission(bool aCheckSandbox) const
     462             : {
     463           0 :   nsCOMPtr<nsPIDOMWindowInner> owner = GetOwner();
     464           0 :   if (!owner) {
     465           0 :     return LOCK_DENIED;
     466             :   }
     467             : 
     468             :   // Chrome can always lock the screen orientation.
     469           0 :   nsIDocShell* docShell = owner->GetDocShell();
     470           0 :   if (docShell && docShell->ItemType() == nsIDocShellTreeItem::typeChrome) {
     471           0 :     return LOCK_ALLOWED;
     472             :   }
     473             : 
     474           0 :   nsCOMPtr<nsIDocument> doc = owner->GetDoc();
     475           0 :   if (!doc || doc->Hidden()) {
     476           0 :     return LOCK_DENIED;
     477             :   }
     478             : 
     479             :   // Sandboxed without "allow-orientation-lock"
     480           0 :   if (aCheckSandbox && doc->GetSandboxFlags() & SANDBOXED_ORIENTATION_LOCK) {
     481           0 :     return LOCK_DENIED;
     482             :   }
     483             : 
     484           0 :   if (Preferences::GetBool("dom.screenorientation.testing.non_fullscreen_lock_allow",
     485             :                            false)) {
     486           0 :     return LOCK_ALLOWED;
     487             :   }
     488             : 
     489             :   // Other content must be full-screen in order to lock orientation.
     490           0 :   return doc->Fullscreen() ? FULLSCREEN_LOCK_ALLOWED : LOCK_DENIED;
     491             : }
     492             : 
     493             : nsIDocument*
     494           1 : ScreenOrientation::GetResponsibleDocument() const
     495             : {
     496           2 :   nsCOMPtr<nsPIDOMWindowInner> owner = GetOwner();
     497           1 :   if (!owner) {
     498           0 :     return nullptr;
     499             :   }
     500             : 
     501           1 :   return owner->GetDoc();
     502             : }
     503             : 
     504             : void
     505           0 : ScreenOrientation::Notify(const hal::ScreenConfiguration& aConfiguration)
     506             : {
     507           0 :   if (ShouldResistFingerprinting()) {
     508           0 :     return;
     509             :   }
     510             : 
     511           0 :   nsIDocument* doc = GetResponsibleDocument();
     512           0 :   if (!doc) {
     513           0 :     return;
     514             :   }
     515             : 
     516           0 :   ScreenOrientationInternal orientation = aConfiguration.orientation();
     517           0 :   if (orientation != eScreenOrientation_PortraitPrimary &&
     518           0 :       orientation != eScreenOrientation_PortraitSecondary &&
     519           0 :       orientation != eScreenOrientation_LandscapePrimary &&
     520             :       orientation != eScreenOrientation_LandscapeSecondary) {
     521             :     // The platform may notify of some other values from
     522             :     // an orientation lock, but we only care about real
     523             :     // changes to screen orientation which result in one of
     524             :     // the values we care about.
     525           0 :     return;
     526             :   }
     527             : 
     528           0 :   OrientationType previousOrientation = mType;
     529           0 :   mAngle = aConfiguration.angle();
     530           0 :   mType = InternalOrientationToType(orientation);
     531             : 
     532           0 :   DebugOnly<nsresult> rv;
     533           0 :   if (mScreen && mType != previousOrientation) {
     534             :     // Use of mozorientationchange is deprecated.
     535           0 :     rv = mScreen->DispatchTrustedEvent(NS_LITERAL_STRING("mozorientationchange"));
     536           0 :     NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "DispatchTrustedEvent failed");
     537             :   }
     538             : 
     539           0 :   if (doc->Hidden() && !mVisibleListener) {
     540           0 :     mVisibleListener = new VisibleEventListener();
     541           0 :     rv = doc->AddSystemEventListener(NS_LITERAL_STRING("visibilitychange"),
     542           0 :                                      mVisibleListener, /* useCapture = */ true);
     543           0 :     NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "AddSystemEventListener failed");
     544           0 :     return;
     545             :   }
     546             : 
     547           0 :   if (mType != doc->CurrentOrientationType()) {
     548           0 :     doc->SetCurrentOrientation(mType, mAngle);
     549             : 
     550           0 :     Promise* pendingPromise = doc->GetOrientationPendingPromise();
     551           0 :     if (pendingPromise) {
     552           0 :       pendingPromise->MaybeResolveWithUndefined();
     553           0 :       doc->SetOrientationPendingPromise(nullptr);
     554             :     }
     555             : 
     556             :     nsCOMPtr<nsIRunnable> runnable =
     557           0 :       NewRunnableMethod("dom::ScreenOrientation::DispatchChangeEvent",
     558             :                         this,
     559           0 :                         &ScreenOrientation::DispatchChangeEvent);
     560           0 :     rv = NS_DispatchToMainThread(runnable);
     561           0 :     NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "NS_DispatchToMainThread failed");
     562             :   }
     563             : }
     564             : 
     565             : void
     566           0 : ScreenOrientation::UpdateActiveOrientationLock(ScreenOrientationInternal aOrientation)
     567             : {
     568           0 :   if (aOrientation == eScreenOrientation_None) {
     569           0 :     hal::UnlockScreenOrientation();
     570             :   } else {
     571           0 :     DebugOnly<bool> ok = hal::LockScreenOrientation(aOrientation);
     572           0 :     NS_WARNING_ASSERTION(ok, "hal::LockScreenOrientation failed");
     573             :   }
     574           0 : }
     575             : 
     576             : void
     577           0 : ScreenOrientation::DispatchChangeEvent()
     578             : {
     579           0 :   DebugOnly<nsresult> rv = DispatchTrustedEvent(NS_LITERAL_STRING("change"));
     580           0 :   NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "DispatchTrustedEvent failed");
     581           0 : }
     582             : 
     583             : JSObject*
     584           0 : ScreenOrientation::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
     585             : {
     586           0 :   return ScreenOrientationBinding::Wrap(aCx, this, aGivenProto);
     587             : }
     588             : 
     589             : bool
     590           0 : ScreenOrientation::ShouldResistFingerprinting() const
     591             : {
     592           0 :   bool resist = false;
     593           0 :   if (nsCOMPtr<nsPIDOMWindowInner> owner = GetOwner()) {
     594           0 :     resist = nsContentUtils::ShouldResistFingerprinting(owner->GetDocShell());
     595             :   }
     596           0 :   return resist;
     597             : }
     598             : 
     599           0 : NS_IMPL_ISUPPORTS(ScreenOrientation::VisibleEventListener, nsIDOMEventListener)
     600             : 
     601             : NS_IMETHODIMP
     602           0 : ScreenOrientation::VisibleEventListener::HandleEvent(nsIDOMEvent* aEvent)
     603             : {
     604             :   // Document may have become visible, if the page is visible, run the steps
     605             :   // following the "now visible algorithm" as specified.
     606           0 :   nsCOMPtr<EventTarget> target = aEvent->InternalDOMEvent()->GetCurrentTarget();
     607           0 :   MOZ_ASSERT(target);
     608             : 
     609           0 :   nsCOMPtr<nsIDocument> doc = do_QueryInterface(target);
     610           0 :   if (!doc || doc->Hidden()) {
     611           0 :     return NS_OK;
     612             :   }
     613             : 
     614           0 :   auto* win = nsGlobalWindow::Cast(doc->GetInnerWindow());
     615           0 :   if (!win) {
     616           0 :     return NS_OK;
     617             :   }
     618             : 
     619           0 :   ErrorResult rv;
     620           0 :   nsScreen* screen = win->GetScreen(rv);
     621           0 :   if (NS_WARN_IF(rv.Failed())) {
     622           0 :     return rv.StealNSResult();
     623             :   }
     624             : 
     625           0 :   MOZ_ASSERT(screen);
     626           0 :   ScreenOrientation* orientation = screen->Orientation();
     627           0 :   MOZ_ASSERT(orientation);
     628             : 
     629           0 :   rv = target->RemoveSystemEventListener(NS_LITERAL_STRING("visibilitychange"),
     630           0 :                                          this, true);
     631           0 :   if (NS_WARN_IF(rv.Failed())) {
     632           0 :     return rv.StealNSResult();
     633             :   }
     634             : 
     635           0 :   if (doc->CurrentOrientationType() != orientation->DeviceType(CallerType::System)) {
     636           0 :     doc->SetCurrentOrientation(orientation->DeviceType(CallerType::System),
     637           0 :                                orientation->DeviceAngle(CallerType::System));
     638             : 
     639           0 :     Promise* pendingPromise = doc->GetOrientationPendingPromise();
     640           0 :     if (pendingPromise) {
     641           0 :       pendingPromise->MaybeResolveWithUndefined();
     642           0 :       doc->SetOrientationPendingPromise(nullptr);
     643             :     }
     644             : 
     645             :     nsCOMPtr<nsIRunnable> runnable =
     646           0 :       NewRunnableMethod("dom::ScreenOrientation::DispatchChangeEvent",
     647             :                         orientation,
     648           0 :                         &ScreenOrientation::DispatchChangeEvent);
     649           0 :     rv = NS_DispatchToMainThread(runnable);
     650           0 :     if (NS_WARN_IF(rv.Failed())) {
     651           0 :       return rv.StealNSResult();
     652             :     }
     653             :   }
     654             : 
     655           0 :   return NS_OK;
     656             : }
     657             : 
     658           0 : NS_IMPL_ISUPPORTS(ScreenOrientation::FullScreenEventListener, nsIDOMEventListener)
     659             : 
     660             : NS_IMETHODIMP
     661           0 : ScreenOrientation::FullScreenEventListener::HandleEvent(nsIDOMEvent* aEvent)
     662             : {
     663             : #ifdef DEBUG
     664           0 :   nsAutoString eventType;
     665           0 :   aEvent->GetType(eventType);
     666             : 
     667           0 :   MOZ_ASSERT(eventType.EqualsLiteral("fullscreenchange"));
     668             : #endif
     669             : 
     670           0 :   nsCOMPtr<EventTarget> target = aEvent->InternalDOMEvent()->GetCurrentTarget();
     671           0 :   MOZ_ASSERT(target);
     672             : 
     673           0 :   nsCOMPtr<nsIDocument> doc = do_QueryInterface(target);
     674           0 :   MOZ_ASSERT(doc);
     675             : 
     676             :   // We have to make sure that the event we got is the event sent when
     677             :   // fullscreen is disabled because we could get one when fullscreen
     678             :   // got enabled if the lock call is done at the same moment.
     679           0 :   if (doc->Fullscreen()) {
     680           0 :     return NS_OK;
     681             :   }
     682             : 
     683           0 :   hal::UnlockScreenOrientation();
     684             : 
     685           0 :   nsresult rv = target->RemoveSystemEventListener(NS_LITERAL_STRING("fullscreenchange"),
     686           0 :                                                   this, true);
     687           0 :   NS_ENSURE_SUCCESS(rv, rv);
     688             : 
     689           0 :   return NS_OK;
     690             : }

Generated by: LCOV version 1.13