Bug 1194751 - Part 6. Use mozilla::widget::ScreenManager in content process. r=mconley

This is the most important part of the patch series. It removes the
PScreenManager protocol and use ScreenManager directly in the content
processes.

Initial and subsequent updates are sent via PContent::RefreshScreens.
struct ScreenDetails are kept to serialize Screen over IPC.

nsIScreenManager::ScreenForNativeWidget is removed because
nsIWidget::GetWidgetScreen can replace it. nsIScreen::GetId is removed
because it's not useful for the more general Screen class.

MozReview-Commit-ID: 5dJO3isgBuQ

--HG--
extra : rebase_source : 06aa4e4fd56e2b2af1e7483aee7c0cc7f35bdb97
This commit is contained in:
Kan-Ru Chen 2017-03-09 19:30:26 +08:00
parent 824adc9354
commit 8ba424eabb
33 changed files with 133 additions and 1136 deletions

View File

@ -61,6 +61,7 @@
#include "mozilla/net/CaptivePortalService.h"
#include "mozilla/plugins/PluginInstanceParent.h"
#include "mozilla/plugins/PluginModuleParent.h"
#include "mozilla/widget/ScreenManager.h"
#include "mozilla/widget/WidgetMessageUtils.h"
#include "nsBaseDragService.h"
#include "mozilla/media/MediaChild.h"
@ -99,7 +100,6 @@
#include "nsIMutable.h"
#include "nsIObserverService.h"
#include "nsIScriptSecurityManager.h"
#include "nsScreenManagerProxy.h"
#include "nsMemoryInfoDumper.h"
#include "nsServiceManagerUtils.h"
#include "nsStyleSheetService.h"
@ -1748,27 +1748,6 @@ ContentChild::DeallocPParentToChildStreamChild(PParentToChildStreamChild* aActor
return nsIContentChild::DeallocPParentToChildStreamChild(aActor);
}
PScreenManagerChild*
ContentChild::AllocPScreenManagerChild(float* aSystemDefaultScale,
bool* aSuccess)
{
// The ContentParent should never attempt to allocate the
// nsScreenManagerProxy. Instead, the nsScreenManagerProxy
// service is requested and instantiated via XPCOM, and the
// constructor of nsScreenManagerProxy sets up the IPC connection.
MOZ_CRASH("Should never get here!");
return nullptr;
}
bool
ContentChild::DeallocPScreenManagerChild(PScreenManagerChild* aService)
{
// nsScreenManagerProxy is AddRef'd in its constructor.
nsScreenManagerProxy *child = static_cast<nsScreenManagerProxy*>(aService);
child->Release();
return true;
}
PPSMContentDownloaderChild*
ContentChild::AllocPPSMContentDownloaderChild(const uint32_t& aCertType)
{
@ -3267,7 +3246,14 @@ ContentChild::RecvSetPermissionsWithKey(const nsCString& aPermissionKey,
nsCOMPtr<nsIPermissionManager> permissionManager =
services::GetPermissionManager();
permissionManager->SetPermissionsWithKey(aPermissionKey, aPerms);
return IPC_OK();
}
mozilla::ipc::IPCResult
ContentChild::RecvRefreshScreens(nsTArray<ScreenDetails>&& aScreens)
{
ScreenManager& screenManager = ScreenManager::GetSingleton();
screenManager.Refresh(Move(aScreens));
return IPC_OK();
}

View File

@ -242,12 +242,6 @@ public:
virtual PParentToChildStreamChild* AllocPParentToChildStreamChild() override;
virtual bool DeallocPParentToChildStreamChild(PParentToChildStreamChild*) override;
virtual PScreenManagerChild*
AllocPScreenManagerChild(float* aSystemDefaultScale,
bool* aSuccess) override;
virtual bool DeallocPScreenManagerChild(PScreenManagerChild*) override;
virtual PPSMContentDownloaderChild*
AllocPPSMContentDownloaderChild( const uint32_t& aCertType) override;
@ -476,6 +470,9 @@ public:
virtual mozilla::ipc::IPCResult RecvParentActivated(PBrowserChild* aTab, const bool& aActivated) override;
mozilla::ipc::IPCResult
RecvRefreshScreens(nsTArray<ScreenDetails>&& aScreens) override;
// Get the directory for IndexedDB files. We query the parent for this and
// cache the value
nsString &GetIndexedDBPath();

View File

@ -97,6 +97,7 @@
#include "mozilla/Telemetry.h"
#include "mozilla/TelemetryIPC.h"
#include "mozilla/WebBrowserPersistDocumentParent.h"
#include "mozilla/widget/ScreenManager.h"
#include "mozilla/Unused.h"
#include "nsAnonymousTemporaryFile.h"
#include "nsAppRunner.h"
@ -162,7 +163,6 @@
#include "PreallocatedProcessManager.h"
#include "ProcessPriorityManager.h"
#include "SandboxHal.h"
#include "ScreenManagerParent.h"
#include "SourceSurfaceRawData.h"
#include "TabParent.h"
#include "URIUtils.h"
@ -2233,6 +2233,9 @@ ContentParent::InitInternal(ProcessPriority aInitialPriority,
storage->GetAll(&entry.items());
xpcomInit.dataStorage().AppendElement(Move(entry));
}
// Must send screen info before send initialData
ScreenManager& screenManager = ScreenManager::GetSingleton();
screenManager.CopyScreensToRemote(this);
Unused << SendSetXPCOMProcessAttributes(xpcomInit, initialData, lnfCache);
@ -3136,20 +3139,6 @@ ContentParent::DeallocPParentToChildStreamParent(PParentToChildStreamParent* aAc
return nsIContentParent::DeallocPParentToChildStreamParent(aActor);
}
PScreenManagerParent*
ContentParent::AllocPScreenManagerParent(float* aSystemDefaultScale,
bool* aSuccess)
{
return new ScreenManagerParent(aSystemDefaultScale, aSuccess);
}
bool
ContentParent::DeallocPScreenManagerParent(PScreenManagerParent* aActor)
{
delete aActor;
return true;
}
PPSMContentDownloaderParent*
ContentParent::AllocPPSMContentDownloaderParent(const uint32_t& aCertType)
{

View File

@ -446,13 +446,6 @@ public:
virtual bool
DeallocPParentToChildStreamParent(PParentToChildStreamParent* aActor) override;
virtual PScreenManagerParent*
AllocPScreenManagerParent(float* aSystemDefaultScale,
bool* aSuccess) override;
virtual bool
DeallocPScreenManagerParent(PScreenManagerParent* aActor) override;
virtual PHalParent* AllocPHalParent() override;
virtual mozilla::ipc::IPCResult RecvPHalConstructor(PHalParent* aActor) override

View File

@ -16,6 +16,11 @@ using struct mozilla::void_t
using struct mozilla::SerializedStructuredCloneBuffer
from "ipc/IPCMessageUtils.h";
using LayoutDeviceIntRect from "Units.h";
using DesktopIntRect from "Units.h";
using DesktopToLayoutDeviceScale from "Units.h";
using CSSToLayoutDeviceScale from "Units.h";
namespace mozilla {
namespace dom {
@ -178,5 +183,16 @@ struct IPCDataTransfer
IPCDataTransferItem[] items;
};
struct ScreenDetails {
LayoutDeviceIntRect rect;
DesktopIntRect rectDisplayPix;
LayoutDeviceIntRect availRect;
DesktopIntRect availRectDisplayPix;
int32_t pixelDepth;
int32_t colorDepth;
DesktopToLayoutDeviceScale contentsScaleFactor;
CSSToLayoutDeviceScale defaultCSSScaleFactor;
};
} // namespace dom
} // namespace mozilla

View File

@ -28,7 +28,6 @@ using class mozilla::gfx::Matrix from "mozilla/gfx/Matrix.h";
using struct gfxSize from "gfxPoint.h";
using CSSRect from "Units.h";
using CSSSize from "Units.h";
using mozilla::LayoutDeviceIntRect from "Units.h";
using mozilla::LayoutDeviceIntPoint from "Units.h";
using mozilla::LayoutDevicePoint from "Units.h";
using mozilla::ScreenIntPoint from "Units.h";

View File

@ -30,7 +30,6 @@ include protocol PChildToParentStream;
include protocol PParentToChildStream;
include protocol POfflineCacheUpdate;
include protocol PRenderFrame;
include protocol PScreenManager;
include protocol PSpeechSynthesis;
include protocol PStorage;
include protocol PTestShell;
@ -289,7 +288,6 @@ nested(upto inside_cpow) sync protocol PContent
manages PPrinting;
manages PChildToParentStream;
manages PParentToChildStream;
manages PScreenManager;
manages PSpeechSynthesis;
manages PStorage;
manages PTestShell;
@ -595,6 +593,8 @@ child:
async SetPermissionsWithKey(nsCString aPermissionKey, Permission[] aPermissions);
async RefreshScreens(ScreenDetails[] aScreens);
parent:
async InitBackground(Endpoint<PBackgroundParent> aEndpoint);
@ -711,10 +711,6 @@ parent:
async PChildToParentStream();
nested(inside_sync) sync PScreenManager()
returns (float systemDefaultScale,
bool success);
async PSpeechSynthesis();
nested(inside_cpow) async PStorage();

View File

@ -1,62 +0,0 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* 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 protocol PBrowser;
include protocol PContent;
include "mozilla/GfxMessageUtils.h";
using nsIntRect from "nsRect.h";
using mozilla::dom::TabId from "mozilla/dom/ipc/IdType.h";
namespace mozilla {
namespace dom {
struct ScreenDetails {
uint32_t id;
nsIntRect rect;
nsIntRect rectDisplayPix;
nsIntRect availRect;
nsIntRect availRectDisplayPix;
int32_t pixelDepth;
int32_t colorDepth;
double contentsScaleFactor;
double defaultCSSScaleFactor;
};
nested(upto inside_cpow) sync protocol PScreenManager
{
manager PContent;
parent:
nested(inside_sync) sync Refresh()
returns (float systemDefaultScale,
bool success);
nested(inside_cpow) sync ScreenRefresh(uint32_t aId)
returns (ScreenDetails screen,
bool success);
nested(inside_sync) sync GetPrimaryScreen()
returns (ScreenDetails screen,
bool success);
nested(inside_sync) sync ScreenForRect(int32_t aLeft,
int32_t aTop,
int32_t aWidth,
int32_t aHeight)
returns (ScreenDetails screen,
bool success);
nested(inside_cpow) sync ScreenForBrowser(TabId aTabId)
returns (ScreenDetails screen,
bool success);
child:
async __delete__();
};
} // namespace dom
} // namespace mozilla

View File

@ -1,227 +0,0 @@
/* -*- 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 "mozilla/dom/ContentParent.h"
#include "mozilla/dom/TabParent.h"
#include "mozilla/Unused.h"
#include "nsIWidget.h"
#include "nsServiceManagerUtils.h"
#include "ScreenManagerParent.h"
#include "ContentProcessManager.h"
namespace mozilla {
namespace dom {
static const char *sScreenManagerContractID = "@mozilla.org/gfx/screenmanager;1";
ScreenManagerParent::ScreenManagerParent(float* aSystemDefaultScale,
bool* aSuccess)
{
mScreenMgr = do_GetService(sScreenManagerContractID);
if (!mScreenMgr) {
MOZ_CRASH("Couldn't get nsIScreenManager from ScreenManagerParent.");
}
Unused << RecvRefresh(aSystemDefaultScale, aSuccess);
}
mozilla::ipc::IPCResult
ScreenManagerParent::RecvRefresh(float* aSystemDefaultScale,
bool* aSuccess)
{
*aSuccess = false;
nsresult rv = mScreenMgr->GetSystemDefaultScale(aSystemDefaultScale);
if (NS_FAILED(rv)) {
return IPC_OK();
}
*aSuccess = true;
return IPC_OK();
}
mozilla::ipc::IPCResult
ScreenManagerParent::RecvScreenRefresh(const uint32_t& aId,
ScreenDetails* aRetVal,
bool* aSuccess)
{
*aSuccess = false;
nsCOMPtr<nsIScreen> screen;
nsresult rv = mScreenMgr->ScreenForId(aId, getter_AddRefs(screen));
if (NS_FAILED(rv)) {
return IPC_OK();
}
ScreenDetails details;
Unused << ExtractScreenDetails(screen, details);
*aRetVal = details;
*aSuccess = true;
return IPC_OK();
}
mozilla::ipc::IPCResult
ScreenManagerParent::RecvGetPrimaryScreen(ScreenDetails* aRetVal,
bool* aSuccess)
{
*aSuccess = false;
nsCOMPtr<nsIScreen> screen;
nsresult rv = mScreenMgr->GetPrimaryScreen(getter_AddRefs(screen));
NS_ENSURE_SUCCESS(rv, IPC_OK());
ScreenDetails details;
if (!ExtractScreenDetails(screen, details)) {
return IPC_OK();
}
*aRetVal = details;
*aSuccess = true;
return IPC_OK();
}
mozilla::ipc::IPCResult
ScreenManagerParent::RecvScreenForRect(const int32_t& aLeft,
const int32_t& aTop,
const int32_t& aWidth,
const int32_t& aHeight,
ScreenDetails* aRetVal,
bool* aSuccess)
{
*aSuccess = false;
nsCOMPtr<nsIScreen> screen;
nsresult rv = mScreenMgr->ScreenForRect(aLeft, aTop, aWidth, aHeight, getter_AddRefs(screen));
NS_ENSURE_SUCCESS(rv, IPC_OK());
ScreenDetails details;
if (!ExtractScreenDetails(screen, details)) {
return IPC_OK();
}
*aRetVal = details;
*aSuccess = true;
return IPC_OK();
}
mozilla::ipc::IPCResult
ScreenManagerParent::RecvScreenForBrowser(const TabId& aTabId,
ScreenDetails* aRetVal,
bool* aSuccess)
{
*aSuccess = false;
#ifdef MOZ_VALGRIND
// Zero this so that Valgrind doesn't complain when we send it to another
// process.
memset(aRetVal, 0, sizeof(ScreenDetails));
#endif
// Find the mWidget associated with the tabparent, and then return
// the nsIScreen it's on.
ContentParent* cp = static_cast<ContentParent*>(this->Manager());
ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
RefPtr<TabParent> tabParent =
cpm->GetTopLevelTabParentByProcessAndTabId(cp->ChildID(), aTabId);
if(!tabParent){
return IPC_FAIL_NO_REASON(this);
}
nsCOMPtr<nsIWidget> widget = tabParent->GetWidget();
nsCOMPtr<nsIScreen> screen;
if (widget && widget->GetNativeData(NS_NATIVE_WINDOW)) {
mScreenMgr->ScreenForNativeWidget(widget->GetNativeData(NS_NATIVE_WINDOW),
getter_AddRefs(screen));
} else {
nsresult rv = mScreenMgr->GetPrimaryScreen(getter_AddRefs(screen));
if (NS_WARN_IF(NS_FAILED(rv))) {
return IPC_OK();
}
}
NS_ENSURE_TRUE(screen, IPC_OK());
ScreenDetails details;
if (!ExtractScreenDetails(screen, details)) {
return IPC_OK();
}
*aRetVal = details;
*aSuccess = true;
return IPC_OK();
}
bool
ScreenManagerParent::ExtractScreenDetails(nsIScreen* aScreen, ScreenDetails &aDetails)
{
if (!aScreen) {
return false;
}
uint32_t id;
nsresult rv = aScreen->GetId(&id);
NS_ENSURE_SUCCESS(rv, false);
aDetails.id() = id;
nsIntRect rect;
rv = aScreen->GetRect(&rect.x, &rect.y, &rect.width, &rect.height);
NS_ENSURE_SUCCESS(rv, false);
aDetails.rect() = rect;
nsIntRect rectDisplayPix;
rv = aScreen->GetRectDisplayPix(&rectDisplayPix.x, &rectDisplayPix.y,
&rectDisplayPix.width, &rectDisplayPix.height);
NS_ENSURE_SUCCESS(rv, false);
aDetails.rectDisplayPix() = rectDisplayPix;
nsIntRect availRect;
rv = aScreen->GetAvailRect(&availRect.x, &availRect.y, &availRect.width,
&availRect.height);
NS_ENSURE_SUCCESS(rv, false);
aDetails.availRect() = availRect;
nsIntRect availRectDisplayPix;
rv = aScreen->GetAvailRectDisplayPix(&availRectDisplayPix.x,
&availRectDisplayPix.y,
&availRectDisplayPix.width,
&availRectDisplayPix.height);
NS_ENSURE_SUCCESS(rv, false);
aDetails.availRectDisplayPix() = availRectDisplayPix;
int32_t pixelDepth = 0;
rv = aScreen->GetPixelDepth(&pixelDepth);
NS_ENSURE_SUCCESS(rv, false);
aDetails.pixelDepth() = pixelDepth;
int32_t colorDepth = 0;
rv = aScreen->GetColorDepth(&colorDepth);
NS_ENSURE_SUCCESS(rv, false);
aDetails.colorDepth() = colorDepth;
double contentsScaleFactor = 1.0;
rv = aScreen->GetContentsScaleFactor(&contentsScaleFactor);
NS_ENSURE_SUCCESS(rv, false);
aDetails.contentsScaleFactor() = contentsScaleFactor;
double defaultCSSScaleFactor = 1.0;
rv = aScreen->GetDefaultCSSScaleFactor(&defaultCSSScaleFactor);
NS_ENSURE_SUCCESS(rv, false);
aDetails.defaultCSSScaleFactor() = defaultCSSScaleFactor;
return true;
}
void
ScreenManagerParent::ActorDestroy(ActorDestroyReason why)
{
}
} // namespace dom
} // namespace mozilla

View File

@ -1,54 +0,0 @@
/* -*- 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_ScreenManagerParent_h
#define mozilla_dom_ScreenManagerParent_h
#include "mozilla/dom/PScreenManagerParent.h"
#include "nsIScreenManager.h"
namespace mozilla {
namespace dom {
class ScreenManagerParent : public PScreenManagerParent
{
public:
ScreenManagerParent(float* aSystemDefaultScale,
bool* aSuccess);
~ScreenManagerParent() {};
virtual mozilla::ipc::IPCResult RecvRefresh(float* aSystemDefaultScale,
bool* aSuccess) override;
virtual mozilla::ipc::IPCResult RecvScreenRefresh(const uint32_t& aId,
ScreenDetails* aRetVal,
bool* aSuccess) override;
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
virtual mozilla::ipc::IPCResult RecvGetPrimaryScreen(ScreenDetails* aRetVal,
bool* aSuccess) override;
virtual mozilla::ipc::IPCResult RecvScreenForRect(const int32_t& aLeft,
const int32_t& aTop,
const int32_t& aWidth,
const int32_t& aHeight,
ScreenDetails* aRetVal,
bool* aSuccess) override;
virtual mozilla::ipc::IPCResult RecvScreenForBrowser(const TabId& aTabId,
ScreenDetails* aRetVal,
bool* aSuccess) override;
private:
bool ExtractScreenDetails(nsIScreen* aScreen, ScreenDetails &aDetails);
nsCOMPtr<nsIScreenManager> mScreenMgr;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_ScreenManagerParent_h

View File

@ -65,7 +65,6 @@ UNIFIED_SOURCES += [
'PermissionMessageUtils.cpp',
'PreallocatedProcessManager.cpp',
'ProcessPriorityManager.cpp',
'ScreenManagerParent.cpp',
'StructuredCloneData.cpp',
'TabChild.cpp',
'TabContext.cpp',
@ -97,7 +96,6 @@ IPDL_SOURCES += [
'PFilePicker.ipdl',
'PPluginWidget.ipdl',
'PProcessHangMonitor.ipdl',
'PScreenManager.ipdl',
'PTabContext.ipdlh',
'PURLClassifier.ipdl',
'PURLClassifierInfo.ipdlh',

View File

@ -1172,12 +1172,7 @@ NPBool nsPluginInstanceOwner::ConvertPointNoPuppet(nsIWidget *widget,
double scaleFactor = double(nsPresContext::AppUnitsPerCSSPixel())/
presContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom();
nsCOMPtr<nsIScreenManager> screenMgr = do_GetService("@mozilla.org/gfx/screenmanager;1");
if (!screenMgr) {
return false;
}
nsCOMPtr<nsIScreen> screen;
screenMgr->ScreenForNativeWidget(widget->GetNativeData(NS_NATIVE_WINDOW), getter_AddRefs(screen));
nsCOMPtr<nsIScreen> screen = widget->GetWidgetScreen();
if (!screen) {
return false;
}

View File

@ -609,21 +609,8 @@ nsDeviceContext::FindScreen(nsIScreen** outScreen)
CheckDPIChange();
if (mWidget->GetOwningTabChild()) {
mScreenManager->ScreenForNativeWidget((void *)mWidget->GetOwningTabChild(),
outScreen);
}
else if (mWidget->GetNativeData(NS_NATIVE_WINDOW)) {
mScreenManager->ScreenForNativeWidget(mWidget->GetNativeData(NS_NATIVE_WINDOW),
outScreen);
}
#ifdef MOZ_WIDGET_ANDROID
if (!(*outScreen)) {
nsCOMPtr<nsIScreen> screen = mWidget->GetWidgetScreen();
screen.forget(outScreen);
}
#endif
nsCOMPtr<nsIScreen> screen = mWidget->GetWidgetScreen();
screen.forget(outScreen);
if (!(*outScreen)) {
mScreenManager->GetPrimaryScreen(outScreen);

View File

@ -884,8 +884,6 @@ description =
description =
[PContent::IsSecureURI]
description =
[PContent::PScreenManager]
description =
[PContent::PURLClassifier]
description =
[PContent::ClassifyLocal]
@ -934,16 +932,6 @@ description =
description =
[PContentBridge::SyncMessage]
description =
[PScreenManager::Refresh]
description =
[PScreenManager::ScreenRefresh]
description =
[PScreenManager::GetPrimaryScreen]
description =
[PScreenManager::ScreenForRect]
description =
[PScreenManager::ScreenForBrowser]
description =
[PGMP::StartPlugin]
description =
[PGMPService::LaunchGMP]

View File

@ -1357,13 +1357,6 @@ PuppetWidget::GetScreenDimensions()
return nsIntSize(r.width, r.height);
}
NS_IMETHODIMP
PuppetScreen::GetId(uint32_t *outId)
{
*outId = 1;
return NS_OK;
}
NS_IMETHODIMP
PuppetScreen::GetRect(int32_t *outLeft, int32_t *outTop,
int32_t *outWidth, int32_t *outHeight)
@ -1408,14 +1401,6 @@ PuppetScreenManager::~PuppetScreenManager()
{
}
NS_IMETHODIMP
PuppetScreenManager::ScreenForId(uint32_t aId,
nsIScreen** outScreen)
{
NS_IF_ADDREF(*outScreen = mOneScreen.get());
return NS_OK;
}
NS_IMETHODIMP
PuppetScreenManager::GetPrimaryScreen(nsIScreen** outScreen)
{
@ -1433,13 +1418,6 @@ PuppetScreenManager::ScreenForRect(int32_t inLeft,
return GetPrimaryScreen(outScreen);
}
NS_IMETHODIMP
PuppetScreenManager::ScreenForNativeWidget(void* aWidget,
nsIScreen** outScreen)
{
return GetPrimaryScreen(outScreen);
}
NS_IMETHODIMP
PuppetScreenManager::GetSystemDefaultScale(float *aDefaultScale)
{

View File

@ -443,7 +443,6 @@ public:
explicit PuppetScreen(void* nativeScreen);
~PuppetScreen();
NS_IMETHOD GetId(uint32_t* aId) override;
NS_IMETHOD GetRect(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight) override;
NS_IMETHOD GetAvailRect(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight) override;
NS_IMETHOD GetPixelDepth(int32_t* aPixelDepth) override;

View File

@ -6,13 +6,13 @@
#include "Screen.h"
#include "mozilla/dom/DOMTypes.h"
namespace mozilla {
namespace widget {
NS_IMPL_ISUPPORTS(Screen, nsIScreen)
static uint32_t sScreenId = 0;
Screen::Screen(LayoutDeviceIntRect aRect, LayoutDeviceIntRect aAvailRect,
uint32_t aPixelDepth, uint32_t aColorDepth,
DesktopToLayoutDeviceScale aContentsScale,
@ -25,7 +25,18 @@ Screen::Screen(LayoutDeviceIntRect aRect, LayoutDeviceIntRect aAvailRect,
, mColorDepth(aColorDepth)
, mContentsScale(aContentsScale)
, mDefaultCssScale(aDefaultCssScale)
, mId(++sScreenId)
{
}
Screen::Screen(const mozilla::dom::ScreenDetails& aScreen)
: mRect(aScreen.rect())
, mAvailRect(aScreen.availRect())
, mRectDisplayPix(aScreen.rectDisplayPix())
, mAvailRectDisplayPix(aScreen.availRectDisplayPix())
, mPixelDepth(aScreen.pixelDepth())
, mColorDepth(aScreen.colorDepth())
, mContentsScale(aScreen.contentsScaleFactor())
, mDefaultCssScale(aScreen.defaultCSSScaleFactor())
{
}
@ -38,15 +49,15 @@ Screen::Screen(const Screen& aOther)
, mColorDepth(aOther.mColorDepth)
, mContentsScale(aOther.mContentsScale)
, mDefaultCssScale(aOther.mDefaultCssScale)
, mId(aOther.mId)
{
}
NS_IMETHODIMP
Screen::GetId(uint32_t* aOutId)
mozilla::dom::ScreenDetails
Screen::ToScreenDetails()
{
*aOutId = mId;
return NS_OK;
return mozilla::dom::ScreenDetails(
mRect, mRectDisplayPix, mAvailRect, mAvailRectDisplayPix,
mPixelDepth, mColorDepth, mContentsScale, mDefaultCssScale);
}
NS_IMETHODIMP

View File

@ -11,6 +11,12 @@
#include "Units.h"
namespace mozilla {
namespace dom {
class ScreenDetails;
} // namespace dom
} // namespace mozilla
namespace mozilla {
namespace widget {
@ -24,8 +30,11 @@ public:
uint32_t aPixelDepth, uint32_t aColorDepth,
DesktopToLayoutDeviceScale aContentsScale,
CSSToLayoutDeviceScale aDefaultCssScale);
explicit Screen(const mozilla::dom::ScreenDetails& aScreenDetails);
Screen(const Screen& aOther);
mozilla::dom::ScreenDetails ToScreenDetails();
private:
virtual ~Screen() {}
@ -37,7 +46,6 @@ private:
uint32_t mColorDepth;
DesktopToLayoutDeviceScale mContentsScale;
CSSToLayoutDeviceScale mDefaultCssScale;
uint32_t mId;
};
} // namespace widget

View File

@ -7,6 +7,7 @@
#include "ScreenManager.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/Logging.h"
#include "mozilla/StaticPtr.h"
@ -53,26 +54,63 @@ ScreenManager::SetHelper(UniquePtr<Helper> aHelper)
void
ScreenManager::Refresh(nsTArray<RefPtr<Screen>>&& aScreens)
{
MOZ_LOG(sScreenLog, LogLevel::Debug, ("Refresh screens"));
mScreenList = Move(aScreens);
CopyScreensToAllRemotesIfIsParent();
}
NS_IMETHODIMP
ScreenManager::ScreenForId(uint32_t aId, nsIScreen** aOutScreen)
void
ScreenManager::Refresh(nsTArray<mozilla::dom::ScreenDetails>&& aScreens)
{
*aOutScreen = nullptr;
MOZ_LOG(sScreenLog, LogLevel::Debug, ("Refresh screens from IPC"));
nsresult rv;
for (auto& screen : mScreenList) {
uint32_t id;
rv = screen->GetId(&id);
if (NS_SUCCEEDED(rv) && id == aId) {
RefPtr<Screen> ret = screen;
ret.forget(aOutScreen);
return NS_OK;
}
mScreenList.Clear();
for (auto& screen : aScreens) {
mScreenList.AppendElement(new Screen(screen));
}
return NS_ERROR_FAILURE;
CopyScreensToAllRemotesIfIsParent();
}
template<class Range>
void
ScreenManager::CopyScreensToRemoteRange(Range aRemoteRange)
{
AutoTArray<ScreenDetails, 4> screens;
for (auto& screen : mScreenList) {
screens.AppendElement(screen->ToScreenDetails());
}
for (auto cp : aRemoteRange) {
MOZ_LOG(sScreenLog, LogLevel::Debug, ("Send screens to [Pid %d]", cp->Pid()));
if (!cp->SendRefreshScreens(screens)) {
MOZ_LOG(sScreenLog, LogLevel::Error,
("SendRefreshScreens to [Pid %d] failed", cp->Pid()));
}
}
}
void
ScreenManager::CopyScreensToRemote(ContentParent* aContentParent)
{
MOZ_ASSERT(aContentParent);
MOZ_ASSERT(XRE_IsParentProcess());
auto range = { aContentParent };
CopyScreensToRemoteRange(range);
}
void
ScreenManager::CopyScreensToAllRemotesIfIsParent()
{
if (XRE_IsContentProcess()) {
return;
}
MOZ_LOG(sScreenLog, LogLevel::Debug, ("Refreshing all ContentParents"));
CopyScreensToRemoteRange(ContentParent::AllProcesses(ContentParent::eLive));
}
// Returns the screen that contains the rectangle. If the rect overlaps
@ -161,11 +199,5 @@ ScreenManager::GetSystemDefaultScale(float* aDefaultScale)
return NS_OK;
}
NS_IMETHODIMP
ScreenManager::ScreenForNativeWidget(void* aWidget, nsIScreen** aOutScreen)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
} // namespace widget
} // namespace mozilla

View File

@ -14,6 +14,13 @@
#include "mozilla/widget/Screen.h"
#include "nsTArray.h"
namespace mozilla {
namespace dom {
class ContentParent;
class ScreenDetails;
}
}
namespace mozilla {
namespace widget {
@ -36,11 +43,17 @@ public:
void SetHelper(UniquePtr<Helper> aHelper);
void Refresh(nsTArray<RefPtr<Screen>>&& aScreens);
void Refresh(nsTArray<mozilla::dom::ScreenDetails>&& aScreens);
void CopyScreensToRemote(mozilla::dom::ContentParent* aContentParent);
private:
ScreenManager();
virtual ~ScreenManager();
template<class Range>
void CopyScreensToRemoteRange(Range aRemoteRange);
void CopyScreensToAllRemotesIfIsParent();
AutoTArray<RefPtr<Screen>, 4> mScreenList;
UniquePtr<Helper> mHelper;
};

View File

@ -1,213 +0,0 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 2; -*- */
/* vim: set sw=4 ts=8 et 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 "mozilla/Unused.h"
#include "nsContentUtils.h"
#include "nsIAppShell.h"
#include "nsScreenManagerProxy.h"
#include "nsServiceManagerUtils.h"
#include "nsWidgetsCID.h"
#include "ScreenProxy.h"
namespace mozilla {
namespace widget {
using namespace mozilla::dom;
static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
ScreenProxy::ScreenProxy(nsScreenManagerProxy* aScreenManager, ScreenDetails aDetails)
: mContentsScaleFactor(0)
, mDefaultCSSScaleFactor(0)
, mScreenManager(aScreenManager)
, mId(0)
, mPixelDepth(0)
, mColorDepth(0)
, mCacheValid(false)
, mCacheWillInvalidate(false)
{
PopulateByDetails(aDetails);
}
NS_IMETHODIMP
ScreenProxy::GetId(uint32_t *outId)
{
*outId = mId;
return NS_OK;
}
NS_IMETHODIMP
ScreenProxy::GetRect(int32_t *outLeft,
int32_t *outTop,
int32_t *outWidth,
int32_t *outHeight)
{
if (!EnsureCacheIsValid()) {
return NS_ERROR_FAILURE;
}
*outLeft = mRect.x;
*outTop = mRect.y;
*outWidth = mRect.width;
*outHeight = mRect.height;
return NS_OK;
}
NS_IMETHODIMP
ScreenProxy::GetRectDisplayPix(int32_t *outLeft,
int32_t *outTop,
int32_t *outWidth,
int32_t *outHeight)
{
if (!EnsureCacheIsValid()) {
return NS_ERROR_FAILURE;
}
*outLeft = mRectDisplayPix.x;
*outTop = mRectDisplayPix.y;
*outWidth = mRectDisplayPix.width;
*outHeight = mRectDisplayPix.height;
return NS_OK;
}
NS_IMETHODIMP
ScreenProxy::GetAvailRect(int32_t *outLeft,
int32_t *outTop,
int32_t *outWidth,
int32_t *outHeight)
{
if (!EnsureCacheIsValid()) {
return NS_ERROR_FAILURE;
}
*outLeft = mAvailRect.x;
*outTop = mAvailRect.y;
*outWidth = mAvailRect.width;
*outHeight = mAvailRect.height;
return NS_OK;
}
NS_IMETHODIMP
ScreenProxy::GetAvailRectDisplayPix(int32_t *outLeft,
int32_t *outTop,
int32_t *outWidth,
int32_t *outHeight)
{
if (!EnsureCacheIsValid()) {
return NS_ERROR_FAILURE;
}
*outLeft = mAvailRectDisplayPix.x;
*outTop = mAvailRectDisplayPix.y;
*outWidth = mAvailRectDisplayPix.width;
*outHeight = mAvailRectDisplayPix.height;
return NS_OK;
}
NS_IMETHODIMP
ScreenProxy::GetPixelDepth(int32_t *aPixelDepth)
{
if (!EnsureCacheIsValid()) {
return NS_ERROR_FAILURE;
}
*aPixelDepth = mPixelDepth;
return NS_OK;
}
NS_IMETHODIMP
ScreenProxy::GetColorDepth(int32_t *aColorDepth)
{
if (!EnsureCacheIsValid()) {
return NS_ERROR_FAILURE;
}
*aColorDepth = mColorDepth;
return NS_OK;
}
NS_IMETHODIMP
ScreenProxy::GetContentsScaleFactor(double* aContentsScaleFactor)
{
if (!EnsureCacheIsValid()) {
return NS_ERROR_FAILURE;
}
*aContentsScaleFactor = mContentsScaleFactor;
return NS_OK;
}
NS_IMETHODIMP
ScreenProxy::GetDefaultCSSScaleFactor(double* aScaleFactor)
{
if (!EnsureCacheIsValid()) {
return NS_ERROR_FAILURE;
}
*aScaleFactor = mDefaultCSSScaleFactor;
return NS_OK;
}
void
ScreenProxy::PopulateByDetails(ScreenDetails aDetails)
{
mId = aDetails.id();
mRect = nsIntRect(aDetails.rect());
mRectDisplayPix = nsIntRect(aDetails.rectDisplayPix());
mAvailRect = nsIntRect(aDetails.availRect());
mAvailRectDisplayPix = nsIntRect(aDetails.availRectDisplayPix());
mPixelDepth = aDetails.pixelDepth();
mColorDepth = aDetails.colorDepth();
mContentsScaleFactor = aDetails.contentsScaleFactor();
mDefaultCSSScaleFactor = aDetails.defaultCSSScaleFactor();
}
bool
ScreenProxy::EnsureCacheIsValid()
{
if (mCacheValid) {
return true;
}
bool success = false;
// Kick off a synchronous IPC call to the parent to get the
// most up-to-date information.
ScreenDetails details;
Unused << mScreenManager->SendScreenRefresh(mId, &details, &success);
if (!success) {
NS_WARNING("Updating a ScreenProxy in the child process failed on parent side.");
return false;
}
PopulateByDetails(details);
mCacheValid = true;
InvalidateCacheOnNextTick();
return true;
}
void
ScreenProxy::InvalidateCacheOnNextTick()
{
if (mCacheWillInvalidate) {
return;
}
mCacheWillInvalidate = true;
nsContentUtils::RunInStableState(NewRunnableMethod(this, &ScreenProxy::InvalidateCache));
}
void
ScreenProxy::InvalidateCache()
{
mCacheValid = false;
mCacheWillInvalidate = false;
}
} // namespace widget
} // namespace mozilla

View File

@ -1,75 +0,0 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 2; -*- */
/* vim: set sw=4 ts=8 et 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_widget_ScreenProxy_h
#define mozilla_widget_ScreenProxy_h
#include "nsBaseScreen.h"
#include "mozilla/dom/PScreenManagerChild.h"
#include "mozilla/dom/TabChild.h"
class nsScreenManagerProxy;
namespace mozilla {
namespace widget {
class ScreenProxy : public nsBaseScreen
{
public:
ScreenProxy(nsScreenManagerProxy* aScreenManager,
mozilla::dom::ScreenDetails aDetails);
~ScreenProxy() {};
NS_IMETHOD GetId(uint32_t* aId) override;
NS_IMETHOD GetRect(int32_t* aLeft,
int32_t* aTop,
int32_t* aWidth,
int32_t* aHeight) override;
NS_IMETHOD GetRectDisplayPix(int32_t* aLeft,
int32_t* aTop,
int32_t* aWidth,
int32_t* aHeight) override;
NS_IMETHOD GetAvailRect(int32_t* aLeft,
int32_t* aTop,
int32_t* aWidth,
int32_t* aHeight) override;
NS_IMETHOD GetAvailRectDisplayPix(int32_t* aLeft,
int32_t* aTop,
int32_t* aWidth,
int32_t* aHeight) override;
NS_IMETHOD GetPixelDepth(int32_t* aPixelDepth) override;
NS_IMETHOD GetColorDepth(int32_t* aColorDepth) override;
NS_IMETHOD GetContentsScaleFactor(double* aContentsScaleFactor) override;
NS_IMETHOD GetDefaultCSSScaleFactor(double* aScaleFactor) override;
private:
void PopulateByDetails(mozilla::dom::ScreenDetails aDetails);
bool EnsureCacheIsValid();
void InvalidateCacheOnNextTick();
void InvalidateCache();
double mContentsScaleFactor;
double mDefaultCSSScaleFactor;
RefPtr<nsScreenManagerProxy> mScreenManager;
uint32_t mId;
int32_t mPixelDepth;
int32_t mColorDepth;
nsIntRect mRect;
nsIntRect mRectDisplayPix;
nsIntRect mAvailRect;
nsIntRect mAvailRectDisplayPix;
bool mCacheValid;
bool mCacheWillInvalidate;
};
} // namespace widget
} // namespace mozilla
#endif

View File

@ -210,13 +210,6 @@ nsScreenManagerAndroid::ScreenForRect(int32_t inLeft,
return GetPrimaryScreen(outScreen);
}
NS_IMETHODIMP
nsScreenManagerAndroid::ScreenForNativeWidget(void *aWidget, nsIScreen **outScreen)
{
// Not support to query non-primary screen with native widget.
return GetPrimaryScreen(outScreen);
}
NS_IMETHODIMP
nsScreenManagerAndroid::GetSystemDefaultScale(float *aDefaultScale)
{

View File

@ -117,22 +117,3 @@ nsScreenManagerCocoa::GetSystemDefaultScale(float *aDefaultScale)
*aDefaultScale = 1.0f;
return NS_OK;
}
NS_IMETHODIMP
nsScreenManagerCocoa::ScreenForNativeWidget (void *nativeWidget, nsIScreen **outScreen)
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
NSWindow *window = static_cast<NSWindow*>(nativeWidget);
if (window) {
nsIScreen *screen = ScreenForCocoaScreen([window screen]);
*outScreen = screen;
NS_ADDREF(*outScreen);
return NS_OK;
}
*outScreen = nullptr;
return NS_OK;
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
}

View File

@ -831,20 +831,6 @@ nsScreenManagerGonk::ScreenForRect(int32_t inLeft,
return GetPrimaryScreen(outScreen);
}
NS_IMETHODIMP
nsScreenManagerGonk::ScreenForNativeWidget(void *aWidget, nsIScreen **outScreen)
{
for (size_t i = 0; i < mScreens.Length(); i++) {
if (aWidget == mScreens[i]->GetNativeWindow()) {
NS_IF_ADDREF(*outScreen = mScreens[i].get());
return NS_OK;
}
}
*outScreen = nullptr;
return NS_OK;
}
NS_IMETHODIMP
nsScreenManagerGonk::GetSystemDefaultScale(float *aDefaultScale)
{

View File

@ -159,14 +159,12 @@ UNIFIED_SOURCES += [
'nsIWidgetListener.cpp',
'nsPrimitiveHelpers.cpp',
'nsPrintSettingsImpl.cpp',
'nsScreenManagerProxy.cpp',
'nsTransferable.cpp',
'nsXPLookAndFeel.cpp',
'PuppetBidiKeyboard.cpp',
'PuppetWidget.cpp',
'Screen.cpp',
'ScreenManager.cpp',
'ScreenProxy.cpp',
'SharedWidgetUtils.cpp',
'TextEventDispatcher.cpp',
'VsyncDispatcher.cpp',

View File

@ -11,8 +11,8 @@
#include "nsColorPickerProxy.h"
#include "nsDragServiceProxy.h"
#include "nsFilePickerProxy.h"
#include "nsScreenManagerProxy.h"
#include "mozilla/widget/PuppetBidiKeyboard.h"
#include "mozilla/widget/ScreenManager.h"
using namespace mozilla;
using namespace mozilla::widget;
@ -23,8 +23,8 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboardProxy)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsColorPickerProxy)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsDragServiceProxy)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsFilePickerProxy)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsScreenManagerProxy)
NS_GENERIC_FACTORY_CONSTRUCTOR(PuppetBidiKeyboard)
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(ScreenManager, ScreenManager::GetAddRefedSingleton)
NS_DEFINE_NAMED_CID(NS_CLIPBOARD_CID);
NS_DEFINE_NAMED_CID(NS_COLORPICKER_CID);
@ -42,10 +42,10 @@ static const mozilla::Module::CIDEntry kWidgetCIDs[] = {
Module::CONTENT_PROCESS_ONLY },
{ &kNS_FILEPICKER_CID, false, nullptr, nsFilePickerProxyConstructor,
Module::CONTENT_PROCESS_ONLY },
{ &kNS_SCREENMANAGER_CID, false, nullptr, nsScreenManagerProxyConstructor,
Module::CONTENT_PROCESS_ONLY },
{ &kPUPPETBIDIKEYBOARD_CID, false, NULL, PuppetBidiKeyboardConstructor,
mozilla::Module::CONTENT_PROCESS_ONLY },
Module::CONTENT_PROCESS_ONLY },
{ &kNS_SCREENMANAGER_CID, false, nullptr, ScreenManagerConstructor,
Module::CONTENT_PROCESS_ONLY },
{ nullptr }
};

View File

@ -20,12 +20,6 @@ enum class DisplayType: int32_t {
[scriptable, uuid(826e80c8-d70f-42e2-8aa9-82c05f2a370a)]
interface nsIScreen : nsISupports
{
/**
* A unique identifier for this device, useful for requerying
* for it via nsIScreenManager.
*/
readonly attribute unsigned long id;
/**
* These report screen dimensions in (screen-specific) device pixels
*/

View File

@ -18,13 +18,6 @@ interface nsIScreenManager : nsISupports
//
nsIScreen screenForRect ( in long left, in long top, in long width, in long height ) ;
//
// Returns the screen corresponding to the id. If no such screen exists,
// this will throw NS_ERROR_FAILURE. The id is a unique numeric value
// assigned to each screen, and is an attribute available on the nsIScreen
// interface.
nsIScreen screenForId ( in unsigned long id ) ;
// The screen with the menubar/taskbar. This shouldn't be needed very
// often.
readonly attribute nsIScreen primaryScreen;
@ -48,14 +41,4 @@ interface nsIScreenManager : nsISupports
// to the system-wide (X11 or Gtk2) DPI value, as Firefox does not yet
// honor these settings. See bug 798362 and bug 712898.
readonly attribute float systemDefaultScale;
// Returns the nsIScreen instance for the given native widget pointer;
// the pointer is specific to the particular widget implementation,
// and is generally of the same type that NS_NATIVE_WINDOW is.
[noscript] nsIScreen screenForNativeWidget ( in voidPtr nativeWidget );
};
%{ C++
%}

View File

@ -1,205 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 "mozilla/Unused.h"
#include "mozilla/dom/ContentChild.h"
#include "nsScreenManagerProxy.h"
#include "nsServiceManagerUtils.h"
#include "nsContentUtils.h"
#include "nsIAppShell.h"
#include "nsIScreen.h"
#include "nsIScreenManager.h"
#include "nsWidgetsCID.h"
static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
using namespace mozilla;
using namespace mozilla::dom;
using namespace mozilla::widget;
NS_IMPL_ISUPPORTS(nsScreenManagerProxy, nsIScreenManager)
nsScreenManagerProxy::nsScreenManagerProxy()
: mSystemDefaultScale(1.0)
, mCacheValid(true)
, mCacheWillInvalidate(false)
{
bool success = false;
Unused << ContentChild::GetSingleton()->SendPScreenManagerConstructor(
this,
&mSystemDefaultScale,
&success);
if (!success) {
// We're in bad shape. We'll return the default values, but we'll basically
// be lying.
NS_WARNING("Setting up communications with the parent nsIScreenManager failed.");
}
InvalidateCacheOnNextTick();
// nsScreenManagerProxy is a service, which will always have a reference
// held to it by the Component Manager once the service is requested.
// However, nsScreenManagerProxy also implements PScreenManagerChild, and
// that means that the manager of the PScreenManager protocol (PContent
// in this case) needs to know how to deallocate this actor. We AddRef here
// so that in the event that PContent tries to deallocate us either before
// or after process shutdown, we don't try to do a double-free.
AddRef();
}
/**
* nsIScreenManager
**/
NS_IMETHODIMP
nsScreenManagerProxy::GetPrimaryScreen(nsIScreen** outScreen)
{
InvalidateCacheOnNextTick();
if (!mPrimaryScreen) {
ScreenDetails details;
bool success = false;
Unused << SendGetPrimaryScreen(&details, &success);
if (!success) {
return NS_ERROR_FAILURE;
}
mPrimaryScreen = new ScreenProxy(this, details);
}
NS_ADDREF(*outScreen = mPrimaryScreen);
return NS_OK;
}
NS_IMETHODIMP
nsScreenManagerProxy::ScreenForId(uint32_t aId, nsIScreen** outScreen)
{
// At this time, there's no need for child processes to query for
// screens by ID.
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsScreenManagerProxy::ScreenForRect(int32_t inLeft,
int32_t inTop,
int32_t inWidth,
int32_t inHeight,
nsIScreen** outScreen)
{
bool success = false;
ScreenDetails details;
Unused << SendScreenForRect(inLeft, inTop, inWidth, inHeight, &details, &success);
if (!success) {
return NS_ERROR_FAILURE;
}
RefPtr<ScreenProxy> screen = new ScreenProxy(this, details);
NS_ADDREF(*outScreen = screen);
return NS_OK;
}
NS_IMETHODIMP
nsScreenManagerProxy::ScreenForNativeWidget(void* aWidget,
nsIScreen** outScreen)
{
// Because ScreenForNativeWidget can be called numerous times
// indirectly from content via the DOM Screen API, we cache the
// results for this tick of the event loop.
TabChild* tabChild = static_cast<TabChild*>(aWidget);
// Enumerate the cached screen array, looking for one that has
// the TabChild that we're looking for...
for (uint32_t i = 0; i < mScreenCache.Length(); ++i) {
ScreenCacheEntry& curr = mScreenCache[i];
if (curr.mTabChild == aWidget) {
NS_ADDREF(*outScreen = static_cast<nsIScreen*>(curr.mScreenProxy));
return NS_OK;
}
}
// Never cached this screen, so we have to ask the parent process
// for it.
bool success = false;
ScreenDetails details;
Unused << SendScreenForBrowser(tabChild->GetTabId(), &details, &success);
if (!success) {
return NS_ERROR_FAILURE;
}
ScreenCacheEntry newEntry;
RefPtr<ScreenProxy> screen = new ScreenProxy(this, details);
newEntry.mScreenProxy = screen;
newEntry.mTabChild = tabChild;
mScreenCache.AppendElement(newEntry);
NS_ADDREF(*outScreen = screen);
InvalidateCacheOnNextTick();
return NS_OK;
}
NS_IMETHODIMP
nsScreenManagerProxy::GetSystemDefaultScale(float *aSystemDefaultScale)
{
if (!EnsureCacheIsValid()) {
return NS_ERROR_FAILURE;
}
*aSystemDefaultScale = mSystemDefaultScale;
return NS_OK;
}
bool
nsScreenManagerProxy::EnsureCacheIsValid()
{
if (mCacheValid) {
return true;
}
bool success = false;
// Kick off a synchronous IPC call to the parent to get the
// most up-to-date information.
Unused << SendRefresh(&mSystemDefaultScale, &success);
if (!success) {
NS_WARNING("Refreshing nsScreenManagerProxy failed in the parent process.");
return false;
}
mCacheValid = true;
InvalidateCacheOnNextTick();
return true;
}
void
nsScreenManagerProxy::InvalidateCacheOnNextTick()
{
if (mCacheWillInvalidate) {
return;
}
mCacheWillInvalidate = true;
nsContentUtils::RunInStableState(NewRunnableMethod(this, &nsScreenManagerProxy::InvalidateCache));
}
void
nsScreenManagerProxy::InvalidateCache()
{
mCacheValid = false;
mCacheWillInvalidate = false;
if (mPrimaryScreen) {
mPrimaryScreen = nullptr;
}
for (int32_t i = mScreenCache.Length() - 1; i >= 0; --i) {
mScreenCache.RemoveElementAt(i);
}
}

View File

@ -1,66 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 nsScreenManagerProxy_h
#define nsScreenManagerProxy_h
#include "nsIScreenManager.h"
#include "mozilla/dom/PScreenManagerChild.h"
#include "mozilla/dom/TabChild.h"
#include "ScreenProxy.h"
/**
* The nsScreenManagerProxy is used by the content process to get
* information about system screens. It uses the PScreenManager protocol
* to communicate with a PScreenManagerParent to get this information,
* and also caches the information it gets back.
*
* We cache both the system screen information that nsIScreenManagers
* provide, as well as the nsIScreens that callers can query for.
*
* Both of these caches are invalidated on the next tick of the event
* loop.
*/
class nsScreenManagerProxy final : public nsIScreenManager,
public mozilla::dom::PScreenManagerChild
{
public:
nsScreenManagerProxy();
NS_DECL_ISUPPORTS
NS_DECL_NSISCREENMANAGER
private:
~nsScreenManagerProxy() {};
bool EnsureCacheIsValid();
void InvalidateCacheOnNextTick();
void InvalidateCache();
float mSystemDefaultScale;
bool mCacheValid;
bool mCacheWillInvalidate;
RefPtr<mozilla::widget::ScreenProxy> mPrimaryScreen;
// nsScreenManagerProxy caches the results to repeated calls to
// ScreenForNativeWidget, which can be triggered indirectly by
// web content using the DOM Screen API. This allows us to bypass
// a lot of IPC traffic.
//
// The cache stores ScreenProxy's mapped to the TabChild that
// asked for the ScreenForNativeWidget was called with via
// ScreenCacheEntry's. The cache is cleared on the next tick of
// the event loop.
struct ScreenCacheEntry
{
RefPtr<mozilla::widget::ScreenProxy> mScreenProxy;
RefPtr<mozilla::dom::TabChild> mTabChild;
};
nsTArray<ScreenCacheEntry> mScreenCache;
};
#endif // nsScreenManagerProxy_h

View File

@ -117,19 +117,6 @@ UIKitScreenManager::ScreenForRect(int32_t inLeft,
return GetPrimaryScreen(outScreen);
}
NS_IMETHODIMP
UIKitScreenManager::ScreenForId(uint32_t id,
nsIScreen** outScreen)
{
return GetPrimaryScreen(outScreen);
}
NS_IMETHODIMP
UIKitScreenManager::ScreenForNativeWidget(void* aWidget, nsIScreen** outScreen)
{
return GetPrimaryScreen(outScreen);
}
NS_IMETHODIMP
UIKitScreenManager::GetSystemDefaultScale(float* aScale)
{

View File

@ -130,11 +130,3 @@ nsScreenManagerWin::GetSystemDefaultScale(float *aDefaultScale)
*aDefaultScale = float(widget::WinUtils::LogToPhysFactor(primary));
return NS_OK;
}
NS_IMETHODIMP
nsScreenManagerWin::ScreenForNativeWidget(void *aWidget, nsIScreen **outScreen)
{
HMONITOR mon = MonitorFromWindow((HWND) aWidget, MONITOR_DEFAULTTOPRIMARY);
*outScreen = CreateNewScreenObject(mon);
return NS_OK;
}