gecko-dev/dom/base/nsScreen.cpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

233 строки
6.6 KiB
C++
Исходник Обычный вид История

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
2012-05-21 15:12:37 +04:00
/* 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/. */
Bug 1278816 - Move Performance API into dom/performance, r=smaug --HG-- rename : dom/base/PerformanceEntry.cpp => dom/performance/PerformanceEntry.cpp rename : dom/base/PerformanceEntry.h => dom/performance/PerformanceEntry.h rename : dom/base/PerformanceMark.cpp => dom/performance/PerformanceMark.cpp rename : dom/base/PerformanceMark.h => dom/performance/PerformanceMark.h rename : dom/base/PerformanceMeasure.cpp => dom/performance/PerformanceMeasure.cpp rename : dom/base/PerformanceMeasure.h => dom/performance/PerformanceMeasure.h rename : dom/base/PerformanceObserver.cpp => dom/performance/PerformanceObserver.cpp rename : dom/base/PerformanceObserver.h => dom/performance/PerformanceObserver.h rename : dom/base/PerformanceObserverEntryList.cpp => dom/performance/PerformanceObserverEntryList.cpp rename : dom/base/PerformanceObserverEntryList.h => dom/performance/PerformanceObserverEntryList.h rename : dom/base/PerformanceResourceTiming.cpp => dom/performance/PerformanceResourceTiming.cpp rename : dom/base/PerformanceResourceTiming.h => dom/performance/PerformanceResourceTiming.h rename : dom/base/nsPerformance.cpp => dom/performance/nsPerformance.cpp rename : dom/base/nsPerformance.h => dom/performance/nsPerformance.h rename : dom/base/test/performance_observer.html => dom/performance/tests/performance_observer.html rename : dom/base/test/test_performance_observer.html => dom/performance/tests/test_performance_observer.html rename : dom/base/test/test_performance_observer.js => dom/performance/tests/test_performance_observer.js rename : dom/base/test/test_performance_user_timing.html => dom/performance/tests/test_performance_user_timing.html rename : dom/base/test/test_performance_user_timing.js => dom/performance/tests/test_performance_user_timing.js
2016-06-09 13:42:21 +03:00
#include "nsContentUtils.h"
#include "nsScreen.h"
#include "mozilla/dom/Document.h"
#include "nsIDocShell.h"
#include "nsPresContext.h"
#include "nsCOMPtr.h"
#include "nsIDocShellTreeItem.h"
#include "nsLayoutUtils.h"
#include "nsJSUtils.h"
#include "nsDeviceContext.h"
#include "mozilla/widget/ScreenManager.h"
using namespace mozilla;
using namespace mozilla::dom;
/* static */
already_AddRefed<nsScreen> nsScreen::Create(nsPIDOMWindowInner* aWindow) {
MOZ_ASSERT(aWindow);
if (!aWindow->GetDocShell()) {
return nullptr;
}
nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(aWindow);
NS_ENSURE_TRUE(sgo, nullptr);
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 08:24:48 +03:00
RefPtr<nsScreen> screen = new nsScreen(aWindow);
return screen.forget();
}
nsScreen::nsScreen(nsPIDOMWindowInner* aWindow)
: DOMEventTargetHelper(aWindow),
mScreenOrientation(new ScreenOrientation(aWindow, this)) {}
nsScreen::~nsScreen() = default;
// QueryInterface implementation for nsScreen
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsScreen)
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
NS_IMPL_ADDREF_INHERITED(nsScreen, DOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(nsScreen, DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_INHERITED(nsScreen, DOMEventTargetHelper,
mScreenOrientation)
int32_t nsScreen::GetPixelDepth(ErrorResult& aRv) {
// Return 24 to prevent fingerprinting.
if (ShouldResistFingerprinting()) {
return 24;
}
nsDeviceContext* context = GetDeviceContext();
if (!context) {
aRv.Throw(NS_ERROR_FAILURE);
return -1;
}
return context->GetDepth();
}
nsPIDOMWindowOuter* nsScreen::GetOuter() const {
if (nsPIDOMWindowInner* inner = GetOwner()) {
return inner->GetOuterWindow();
}
return nullptr;
}
nsDeviceContext* nsScreen::GetDeviceContext() const {
return nsLayoutUtils::GetDeviceContextForScreenInfo(GetOuter());
}
nsresult nsScreen::GetRect(CSSIntRect& aRect) {
// Return window inner rect to prevent fingerprinting.
if (ShouldResistFingerprinting()) {
return GetWindowInnerRect(aRect);
}
// Here we manipulate the value of aRect to represent the screen size,
// if in RDM.
if (nsCOMPtr<nsPIDOMWindowInner> owner = GetOwner()) {
if (Document* doc = owner->GetExtantDoc()) {
Maybe<CSSIntSize> deviceSize =
nsGlobalWindowOuter::GetRDMDeviceSize(*doc);
if (deviceSize.isSome()) {
const CSSIntSize& size = deviceSize.value();
aRect.SetRect(0, 0, size.width, size.height);
return NS_OK;
}
}
}
nsDeviceContext* context = GetDeviceContext();
if (!context) {
return NS_ERROR_FAILURE;
}
nsRect r;
context->GetRect(r);
aRect = CSSIntRect::FromAppUnitsRounded(r);
return NS_OK;
}
nsresult nsScreen::GetAvailRect(CSSIntRect& aRect) {
// Return window inner rect to prevent fingerprinting.
if (ShouldResistFingerprinting()) {
return GetWindowInnerRect(aRect);
}
// Here we manipulate the value of aRect to represent the screen size,
// if in RDM.
if (nsCOMPtr<nsPIDOMWindowInner> owner = GetOwner()) {
if (Document* doc = owner->GetExtantDoc()) {
Maybe<CSSIntSize> deviceSize =
nsGlobalWindowOuter::GetRDMDeviceSize(*doc);
if (deviceSize.isSome()) {
const CSSIntSize& size = deviceSize.value();
aRect.SetRect(0, 0, size.width, size.height);
return NS_OK;
}
}
}
nsDeviceContext* context = GetDeviceContext();
if (!context) {
return NS_ERROR_FAILURE;
}
nsRect r;
context->GetClientRect(r);
aRect = CSSIntRect::FromAppUnitsRounded(r);
return NS_OK;
}
uint16_t nsScreen::GetOrientationAngle() const {
nsDeviceContext* context = GetDeviceContext();
if (context) {
return context->GetScreenOrientationAngle();
}
RefPtr<widget::Screen> s =
widget::ScreenManager::GetSingleton().GetPrimaryScreen();
return s->GetOrientationAngle();
}
hal::ScreenOrientation nsScreen::GetOrientationType() const {
nsDeviceContext* context = GetDeviceContext();
if (context) {
return context->GetScreenOrientationType();
}
RefPtr<widget::Screen> s =
widget::ScreenManager::GetSingleton().GetPrimaryScreen();
return s->GetOrientationType();
}
ScreenOrientation* nsScreen::Orientation() const { return mScreenOrientation; }
void nsScreen::GetMozOrientation(nsString& aOrientation,
CallerType aCallerType) const {
switch (mScreenOrientation->DeviceType(aCallerType)) {
case OrientationType::Portrait_primary:
aOrientation.AssignLiteral("portrait-primary");
break;
case OrientationType::Portrait_secondary:
aOrientation.AssignLiteral("portrait-secondary");
break;
case OrientationType::Landscape_primary:
aOrientation.AssignLiteral("landscape-primary");
break;
case OrientationType::Landscape_secondary:
aOrientation.AssignLiteral("landscape-secondary");
break;
default:
MOZ_CRASH("Unacceptable screen orientation type.");
}
}
bool nsScreen::MozLockOrientation(const nsAString& aOrientation,
ErrorResult& aRv) {
nsString orientation(aOrientation);
Sequence<nsString> orientations;
if (!orientations.AppendElement(orientation, fallible)) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return false;
}
return MozLockOrientation(orientations, aRv);
}
Bug 1697647 - Add screen orientation lock api r=ipc-reviewers,mccr8,agi,smaug,jonalmeida Previously, the screenOrientation.lock API was for Fennec and not supported for Fenix and multi-process use. The overall idea is to now allow apps to use the API through a delegate and make asynchronous calls to LockDeviceOrientation. This required replacing the existing code that returned a default false bool to calls that perform the requested orientation change and instead return a promise that contained either an allow or deny value. Returning a promise instead of a bool involved changing the API calls from the C++ side to Java. The new general control flow of screenOrientation lock follows: an app calls C++ ScreenOrientation.lock() which eventually dispatches LockOrientationTask to resolve the pending orientation promise. Hal.cpp sends an IPC call to the content process and RecvLockScreenOrientation retrieves the current instance of geckoRuntime and calls the java side LockScreenOrientation. Apps must create a delegate and override onOrientationLock to set the requested orientation. In geckoview's testing, this is done with the android API setRequestedOrientation. Once a device orientation change has been triggered, native OnOrientationChange calls to NotifyScreenConfigurationChange, which notifies all observers and dispatches a change event to resolve the pending orientation promise. Testing: I used a demo on the GeckoView Example (https://usefulangle.com/demos/105/screen.html) to test locking to landscape orientation. This required a change to the GVE to show the app from recreating the whole thing on orientation change. In the example AndroidManifest xml file, `orientation` prevents restart when orientation changes. The Junit/Kotlin tests were to verify that the expected orientation delegate was called with the expected new orientation value, in an orientation change, if the new orientation was the same as the current, and if the pre-lock conditions such as being fullscreen were not met. A static preference `dom.screenorientation.allow-lock` was added to the dom group, since it affects the ui dom) and is currently turned off. C++ can access it through its mirrored variable dom_screenorientation_allow_lock (same name but with underscores). The junit tests turn the preference on and test the lock feature. Reference: Orientation constant values: C++ 1 ScreenOrientation_PortraitPrimary); - vertical with button at bottom 2 ScreenOrientation_PortraitSecondary); - vertical with button at top 4 ScreenOrientation_LandscapePrimary); - horizational w button right 8 ScreenOrientation_LandscapeSecondary); - horization button left 16 ScreenOrientation_Default); Java 1 GeckoScreenOrientation.ScreenOrientation.PORTRAIT_PRIMARY.value 2 GeckoScreenOrientation.ScreenOrientation.PORTRAIT_SECONDARY.value 4 GeckoScreenOrientation.ScreenOrientation.LANDSCAPE_PRIMARY.value 8 GeckoScreenOrientation.ScreenOrientation.LANDSCAPE_SECONDARY.value Java public API 0 ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE 1 Activitynfo.SCREEN_ORIENTATION_PORTRAIT Android 1 ORIENTATION_PORTRAIT 2 ORIENTATION_LANDSCAPE Differential Revision: https://phabricator.services.mozilla.com/D129427
2021-12-06 16:58:37 +03:00
// This function is deprecated, use ScreenOrientation API instead.
bool nsScreen::MozLockOrientation(const Sequence<nsString>& aOrientations,
ErrorResult& aRv) {
Bug 1697647 - Add screen orientation lock api r=ipc-reviewers,mccr8,agi,smaug,jonalmeida Previously, the screenOrientation.lock API was for Fennec and not supported for Fenix and multi-process use. The overall idea is to now allow apps to use the API through a delegate and make asynchronous calls to LockDeviceOrientation. This required replacing the existing code that returned a default false bool to calls that perform the requested orientation change and instead return a promise that contained either an allow or deny value. Returning a promise instead of a bool involved changing the API calls from the C++ side to Java. The new general control flow of screenOrientation lock follows: an app calls C++ ScreenOrientation.lock() which eventually dispatches LockOrientationTask to resolve the pending orientation promise. Hal.cpp sends an IPC call to the content process and RecvLockScreenOrientation retrieves the current instance of geckoRuntime and calls the java side LockScreenOrientation. Apps must create a delegate and override onOrientationLock to set the requested orientation. In geckoview's testing, this is done with the android API setRequestedOrientation. Once a device orientation change has been triggered, native OnOrientationChange calls to NotifyScreenConfigurationChange, which notifies all observers and dispatches a change event to resolve the pending orientation promise. Testing: I used a demo on the GeckoView Example (https://usefulangle.com/demos/105/screen.html) to test locking to landscape orientation. This required a change to the GVE to show the app from recreating the whole thing on orientation change. In the example AndroidManifest xml file, `orientation` prevents restart when orientation changes. The Junit/Kotlin tests were to verify that the expected orientation delegate was called with the expected new orientation value, in an orientation change, if the new orientation was the same as the current, and if the pre-lock conditions such as being fullscreen were not met. A static preference `dom.screenorientation.allow-lock` was added to the dom group, since it affects the ui dom) and is currently turned off. C++ can access it through its mirrored variable dom_screenorientation_allow_lock (same name but with underscores). The junit tests turn the preference on and test the lock feature. Reference: Orientation constant values: C++ 1 ScreenOrientation_PortraitPrimary); - vertical with button at bottom 2 ScreenOrientation_PortraitSecondary); - vertical with button at top 4 ScreenOrientation_LandscapePrimary); - horizational w button right 8 ScreenOrientation_LandscapeSecondary); - horization button left 16 ScreenOrientation_Default); Java 1 GeckoScreenOrientation.ScreenOrientation.PORTRAIT_PRIMARY.value 2 GeckoScreenOrientation.ScreenOrientation.PORTRAIT_SECONDARY.value 4 GeckoScreenOrientation.ScreenOrientation.LANDSCAPE_PRIMARY.value 8 GeckoScreenOrientation.ScreenOrientation.LANDSCAPE_SECONDARY.value Java public API 0 ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE 1 Activitynfo.SCREEN_ORIENTATION_PORTRAIT Android 1 ORIENTATION_PORTRAIT 2 ORIENTATION_LANDSCAPE Differential Revision: https://phabricator.services.mozilla.com/D129427
2021-12-06 16:58:37 +03:00
return false;
}
Bug 1697647 - Add screen orientation lock api r=ipc-reviewers,mccr8,agi,smaug,jonalmeida Previously, the screenOrientation.lock API was for Fennec and not supported for Fenix and multi-process use. The overall idea is to now allow apps to use the API through a delegate and make asynchronous calls to LockDeviceOrientation. This required replacing the existing code that returned a default false bool to calls that perform the requested orientation change and instead return a promise that contained either an allow or deny value. Returning a promise instead of a bool involved changing the API calls from the C++ side to Java. The new general control flow of screenOrientation lock follows: an app calls C++ ScreenOrientation.lock() which eventually dispatches LockOrientationTask to resolve the pending orientation promise. Hal.cpp sends an IPC call to the content process and RecvLockScreenOrientation retrieves the current instance of geckoRuntime and calls the java side LockScreenOrientation. Apps must create a delegate and override onOrientationLock to set the requested orientation. In geckoview's testing, this is done with the android API setRequestedOrientation. Once a device orientation change has been triggered, native OnOrientationChange calls to NotifyScreenConfigurationChange, which notifies all observers and dispatches a change event to resolve the pending orientation promise. Testing: I used a demo on the GeckoView Example (https://usefulangle.com/demos/105/screen.html) to test locking to landscape orientation. This required a change to the GVE to show the app from recreating the whole thing on orientation change. In the example AndroidManifest xml file, `orientation` prevents restart when orientation changes. The Junit/Kotlin tests were to verify that the expected orientation delegate was called with the expected new orientation value, in an orientation change, if the new orientation was the same as the current, and if the pre-lock conditions such as being fullscreen were not met. A static preference `dom.screenorientation.allow-lock` was added to the dom group, since it affects the ui dom) and is currently turned off. C++ can access it through its mirrored variable dom_screenorientation_allow_lock (same name but with underscores). The junit tests turn the preference on and test the lock feature. Reference: Orientation constant values: C++ 1 ScreenOrientation_PortraitPrimary); - vertical with button at bottom 2 ScreenOrientation_PortraitSecondary); - vertical with button at top 4 ScreenOrientation_LandscapePrimary); - horizational w button right 8 ScreenOrientation_LandscapeSecondary); - horization button left 16 ScreenOrientation_Default); Java 1 GeckoScreenOrientation.ScreenOrientation.PORTRAIT_PRIMARY.value 2 GeckoScreenOrientation.ScreenOrientation.PORTRAIT_SECONDARY.value 4 GeckoScreenOrientation.ScreenOrientation.LANDSCAPE_PRIMARY.value 8 GeckoScreenOrientation.ScreenOrientation.LANDSCAPE_SECONDARY.value Java public API 0 ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE 1 Activitynfo.SCREEN_ORIENTATION_PORTRAIT Android 1 ORIENTATION_PORTRAIT 2 ORIENTATION_LANDSCAPE Differential Revision: https://phabricator.services.mozilla.com/D129427
2021-12-06 16:58:37 +03:00
void nsScreen::MozUnlockOrientation() {}
/* virtual */
Bug 1117172 part 3. Change the wrappercached WrapObject methods to allow passing in aGivenProto. r=peterv The only manual changes here are to BindingUtils.h, BindingUtils.cpp, Codegen.py, Element.cpp, IDBFileRequest.cpp, IDBObjectStore.cpp, dom/workers/Navigator.cpp, WorkerPrivate.cpp, DeviceStorageRequestChild.cpp, Notification.cpp, nsGlobalWindow.cpp, MessagePort.cpp, nsJSEnvironment.cpp, Sandbox.cpp, XPCConvert.cpp, ExportHelpers.cpp, and DataStoreService.cpp. The rest of this diff was generated by running the following commands: find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapObjectInternal\(JSContext *\* *(?:aCx|cx|aContext|aCtx|js))\)/\1, JS::Handle<JSObject*> aGivenProto)/g' find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapObjectInternal\((?:aCx|cx|aContext|aCtx|js))\)/\1, aGivenProto)/g' find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapNode\(JSContext *\* *(?:aCx|cx|aContext|aCtx|js))\)/\1, JS::Handle<JSObject*> aGivenProto)/g' find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapNode\((?:aCx|cx|aContext|aCtx|js))\)/\1, aGivenProto)/g' find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapObject\(JSContext *\* *(?:aCx|cx|aContext|aCtx|js))\)/\1, JS::Handle<JSObject*> aGivenProto)/g' find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(Binding(?:_workers)?::Wrap\((?:aCx|cx|aContext|aCtx|js), [^,)]+)\)/\1, aGivenProto)/g'
2015-03-19 17:13:33 +03:00
JSObject* nsScreen::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) {
return Screen_Binding::Wrap(aCx, this, aGivenProto);
}
nsresult nsScreen::GetWindowInnerRect(CSSIntRect& aRect) {
aRect.x = 0;
aRect.y = 0;
nsCOMPtr<nsPIDOMWindowInner> win = GetOwner();
if (!win) {
return NS_ERROR_FAILURE;
}
double width;
double height;
nsresult rv = win->GetInnerWidth(&width);
NS_ENSURE_SUCCESS(rv, rv);
rv = win->GetInnerHeight(&height);
NS_ENSURE_SUCCESS(rv, rv);
aRect.SizeTo(std::round(width), std::round(height));
return NS_OK;
}
bool nsScreen::ShouldResistFingerprinting() const {
nsCOMPtr<nsPIDOMWindowInner> owner = GetOwner();
return owner &&
nsGlobalWindowInner::Cast(owner)->ShouldResistFingerprinting();
}