1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5  * You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #ifndef mozilla_dom_ScreenOrientation_h
8 #define mozilla_dom_ScreenOrientation_h
9 
10 #include "mozilla/DOMEventTargetHelper.h"
11 #include "mozilla/dom/BindingDeclarations.h"
12 #include "mozilla/dom/ScreenOrientationBinding.h"
13 #include "mozilla/HalScreenConfiguration.h"
14 #include "mozilla/MozPromise.h"
15 
16 class nsScreen;
17 
18 namespace mozilla {
19 namespace dom {
20 
21 class Promise;
22 
23 class ScreenOrientation final : public DOMEventTargetHelper {
24   // nsScreen has deprecated API that shares implementation.
25   friend class ::nsScreen;
26 
27  public:
28   NS_DECL_ISUPPORTS_INHERITED
29   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ScreenOrientation,
30                                            mozilla::DOMEventTargetHelper)
31 
32   IMPL_EVENT_HANDLER(change)
33 
34   // Called when the orientation may have changed.
35   void MaybeChanged();
36 
37   ScreenOrientation(nsPIDOMWindowInner* aWindow, nsScreen* aScreen);
38 
39   already_AddRefed<Promise> Lock(OrientationLockType aOrientation,
40                                  ErrorResult& aRv);
41 
42   void Unlock(ErrorResult& aRv);
43 
44   // DeviceType and DeviceAngle gets the current type and angle of the device.
45   OrientationType DeviceType(CallerType aCallerType) const;
46   uint16_t DeviceAngle(CallerType aCallerType) const;
47 
48   // GetType and GetAngle gets the type and angle of the responsible document
49   // (as defined in specification).
50   OrientationType GetType(CallerType aCallerType, ErrorResult& aRv) const;
51   uint16_t GetAngle(CallerType aCallerType, ErrorResult& aRv) const;
52 
53   JSObject* WrapObject(JSContext* aCx,
54                        JS::Handle<JSObject*> aGivenProto) override;
55 
56   static void UpdateActiveOrientationLock(hal::ScreenOrientation aOrientation);
57   static void AbortInProcessOrientationPromises(
58       BrowsingContext* aBrowsingContext);
59 
60  private:
61   virtual ~ScreenOrientation();
62 
63   // Listener to unlock orientation if we leave fullscreen.
64   class FullscreenEventListener;
65 
66   // Listener to update document's orienation lock when document becomes
67   // visible.
68   class VisibleEventListener;
69 
70   // Task to run step to lock orientation as defined in specification.
71   class LockOrientationTask;
72 
73   enum LockPermission { LOCK_DENIED, FULLSCREEN_LOCK_ALLOWED, LOCK_ALLOWED };
74 
75   // This method calls into the HAL to lock the device and sets
76   // up listeners for full screen change.
77   RefPtr<GenericNonExclusivePromise> LockDeviceOrientation(
78       hal::ScreenOrientation aOrientation, bool aIsFullscreen);
79 
80   // This method calls in to the HAL to unlock the device and removes
81   // full screen change listener.
82   void UnlockDeviceOrientation();
83   void CleanupFullscreenListener();
84 
85   // This method performs the same function as |Lock| except it takes
86   // a hal::ScreenOrientation argument instead of an OrientationType.
87   // This method exists in order to share implementation with nsScreen that
88   // uses ScreenOrientation.
89   already_AddRefed<Promise> LockInternal(hal::ScreenOrientation aOrientation,
90                                          ErrorResult& aRv);
91 
92   nsCOMPtr<nsIRunnable> DispatchChangeEventAndResolvePromise();
93 
94   bool ShouldResistFingerprinting() const;
95 
96   LockPermission GetLockOrientationPermission(bool aCheckSandbox) const;
97 
98   // Gets the responsible document as defined in the spec.
99   Document* GetResponsibleDocument() const;
100 
101   RefPtr<nsScreen> mScreen;
102   RefPtr<FullscreenEventListener> mFullscreenListener;
103   RefPtr<VisibleEventListener> mVisibleListener;
104   OrientationType mType;
105   uint16_t mAngle;
106   // Whether we've tried to call into hal to lock the device orientation. This
107   // is needed because you don't want calling UnlockDeviceOrientation() during
108   // shutdown to initialize PHal if it hasn't been initialized earlier. Also,
109   // makes sense (there's no reason destroying a ScreenOrientation object from a
110   // different window should remove the orientation lock).
111   bool mTriedToLockDeviceOrientation = false;
112 };
113 
114 }  // namespace dom
115 }  // namespace mozilla
116 
117 #endif  // mozilla_dom_ScreenOrientation_h
118