Bug 1854550 - pt 10. Allow LOG() with zero extra arguments r=glandium
[gecko.git] / dom / base / nsScreen.cpp
blobbeefd9f86694e4dfe5e14e3d0aaaa5c70af13543
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
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "nsContentUtils.h"
8 #include "nsScreen.h"
9 #include "mozilla/dom/Document.h"
10 #include "nsGlobalWindowInner.h"
11 #include "nsGlobalWindowOuter.h"
12 #include "nsIDocShell.h"
13 #include "nsPresContext.h"
14 #include "nsCOMPtr.h"
15 #include "nsIDocShellTreeItem.h"
16 #include "nsLayoutUtils.h"
17 #include "nsJSUtils.h"
18 #include "nsDeviceContext.h"
19 #include "mozilla/widget/ScreenManager.h"
21 using namespace mozilla;
22 using namespace mozilla::dom;
24 /* static */
25 already_AddRefed<nsScreen> nsScreen::Create(nsPIDOMWindowInner* aWindow) {
26 MOZ_ASSERT(aWindow);
28 if (!aWindow->GetDocShell()) {
29 return nullptr;
32 nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(aWindow);
33 NS_ENSURE_TRUE(sgo, nullptr);
35 RefPtr<nsScreen> screen = new nsScreen(aWindow);
36 return screen.forget();
39 nsScreen::nsScreen(nsPIDOMWindowInner* aWindow)
40 : DOMEventTargetHelper(aWindow),
41 mScreenOrientation(new ScreenOrientation(aWindow, this)) {}
43 nsScreen::~nsScreen() = default;
45 // QueryInterface implementation for nsScreen
46 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsScreen)
47 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
49 NS_IMPL_ADDREF_INHERITED(nsScreen, DOMEventTargetHelper)
50 NS_IMPL_RELEASE_INHERITED(nsScreen, DOMEventTargetHelper)
52 NS_IMPL_CYCLE_COLLECTION_INHERITED(nsScreen, DOMEventTargetHelper,
53 mScreenOrientation)
55 int32_t nsScreen::GetPixelDepth(ErrorResult& aRv) {
56 // Return 24 to prevent fingerprinting.
57 if (ShouldResistFingerprinting(RFPTarget::ScreenPixelDepth)) {
58 return 24;
61 nsDeviceContext* context = GetDeviceContext();
63 if (!context) {
64 aRv.Throw(NS_ERROR_FAILURE);
65 return -1;
68 return context->GetDepth();
71 nsPIDOMWindowOuter* nsScreen::GetOuter() const {
72 if (nsPIDOMWindowInner* inner = GetOwner()) {
73 return inner->GetOuterWindow();
76 return nullptr;
79 nsDeviceContext* nsScreen::GetDeviceContext() const {
80 return nsLayoutUtils::GetDeviceContextForScreenInfo(GetOuter());
83 nsresult nsScreen::GetRect(CSSIntRect& aRect) {
84 // Return window inner rect to prevent fingerprinting.
85 if (ShouldResistFingerprinting(RFPTarget::ScreenRect)) {
86 return GetWindowInnerRect(aRect);
89 // Here we manipulate the value of aRect to represent the screen size,
90 // if in RDM.
91 if (nsCOMPtr<nsPIDOMWindowInner> owner = GetOwner()) {
92 if (Document* doc = owner->GetExtantDoc()) {
93 Maybe<CSSIntSize> deviceSize =
94 nsGlobalWindowOuter::GetRDMDeviceSize(*doc);
95 if (deviceSize.isSome()) {
96 const CSSIntSize& size = deviceSize.value();
97 aRect.SetRect(0, 0, size.width, size.height);
98 return NS_OK;
103 nsDeviceContext* context = GetDeviceContext();
105 if (!context) {
106 return NS_ERROR_FAILURE;
109 nsRect r;
110 context->GetRect(r);
111 aRect = CSSIntRect::FromAppUnitsRounded(r);
112 return NS_OK;
115 nsresult nsScreen::GetAvailRect(CSSIntRect& aRect) {
116 // Return window inner rect to prevent fingerprinting.
117 if (ShouldResistFingerprinting(RFPTarget::ScreenAvailRect)) {
118 return GetWindowInnerRect(aRect);
121 // Here we manipulate the value of aRect to represent the screen size,
122 // if in RDM.
123 if (nsCOMPtr<nsPIDOMWindowInner> owner = GetOwner()) {
124 if (Document* doc = owner->GetExtantDoc()) {
125 Maybe<CSSIntSize> deviceSize =
126 nsGlobalWindowOuter::GetRDMDeviceSize(*doc);
127 if (deviceSize.isSome()) {
128 const CSSIntSize& size = deviceSize.value();
129 aRect.SetRect(0, 0, size.width, size.height);
130 return NS_OK;
135 nsDeviceContext* context = GetDeviceContext();
136 if (!context) {
137 return NS_ERROR_FAILURE;
140 nsRect r;
141 context->GetClientRect(r);
142 aRect = CSSIntRect::FromAppUnitsRounded(r);
143 return NS_OK;
146 uint16_t nsScreen::GetOrientationAngle() const {
147 nsDeviceContext* context = GetDeviceContext();
148 if (context) {
149 return context->GetScreenOrientationAngle();
151 RefPtr<widget::Screen> s =
152 widget::ScreenManager::GetSingleton().GetPrimaryScreen();
153 return s->GetOrientationAngle();
156 hal::ScreenOrientation nsScreen::GetOrientationType() const {
157 nsDeviceContext* context = GetDeviceContext();
158 if (context) {
159 return context->GetScreenOrientationType();
161 RefPtr<widget::Screen> s =
162 widget::ScreenManager::GetSingleton().GetPrimaryScreen();
163 return s->GetOrientationType();
166 ScreenOrientation* nsScreen::Orientation() const { return mScreenOrientation; }
168 void nsScreen::GetMozOrientation(nsString& aOrientation,
169 CallerType aCallerType) const {
170 switch (mScreenOrientation->DeviceType(aCallerType)) {
171 case OrientationType::Portrait_primary:
172 aOrientation.AssignLiteral("portrait-primary");
173 break;
174 case OrientationType::Portrait_secondary:
175 aOrientation.AssignLiteral("portrait-secondary");
176 break;
177 case OrientationType::Landscape_primary:
178 aOrientation.AssignLiteral("landscape-primary");
179 break;
180 case OrientationType::Landscape_secondary:
181 aOrientation.AssignLiteral("landscape-secondary");
182 break;
183 default:
184 MOZ_CRASH("Unacceptable screen orientation type.");
188 bool nsScreen::MozLockOrientation(const nsAString& aOrientation,
189 ErrorResult& aRv) {
190 nsString orientation(aOrientation);
191 Sequence<nsString> orientations;
192 if (!orientations.AppendElement(orientation, fallible)) {
193 aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
194 return false;
196 return MozLockOrientation(orientations, aRv);
199 // This function is deprecated, use ScreenOrientation API instead.
200 bool nsScreen::MozLockOrientation(const Sequence<nsString>& aOrientations,
201 ErrorResult& aRv) {
202 return false;
205 void nsScreen::MozUnlockOrientation() {}
207 /* virtual */
208 JSObject* nsScreen::WrapObject(JSContext* aCx,
209 JS::Handle<JSObject*> aGivenProto) {
210 return Screen_Binding::Wrap(aCx, this, aGivenProto);
213 nsresult nsScreen::GetWindowInnerRect(CSSIntRect& aRect) {
214 aRect.x = 0;
215 aRect.y = 0;
216 nsCOMPtr<nsPIDOMWindowInner> win = GetOwner();
217 if (!win) {
218 return NS_ERROR_FAILURE;
220 double width;
221 double height;
222 nsresult rv = win->GetInnerWidth(&width);
223 NS_ENSURE_SUCCESS(rv, rv);
224 rv = win->GetInnerHeight(&height);
225 NS_ENSURE_SUCCESS(rv, rv);
226 aRect.SizeTo(std::round(width), std::round(height));
227 return NS_OK;
230 bool nsScreen::ShouldResistFingerprinting(RFPTarget aTarget) const {
231 nsCOMPtr<nsPIDOMWindowInner> owner = GetOwner();
232 return owner &&
233 nsGlobalWindowInner::Cast(owner)->ShouldResistFingerprinting(aTarget);