MozReview-Commit-ID: 2R3jZZI6drP
This commit is contained in:
Phil Ringnalda 2017-06-21 20:39:08 -07:00
Родитель 9ec27f8568 aef6a66634
Коммит 669f3cd603
17 изменённых файлов: 201 добавлений и 462 удалений

Просмотреть файл

@ -324,7 +324,6 @@ nsHtml5StringParser* nsContentUtils::sHTMLFragmentParser = nullptr;
nsIParser* nsContentUtils::sXMLFragmentParser = nullptr;
nsIFragmentContentSink* nsContentUtils::sXMLFragmentSink = nullptr;
bool nsContentUtils::sFragmentParsingActive = false;
nsISerialEventTarget* nsContentUtils::sStableStateEventTarget = nullptr;
#if !(defined(DEBUG) || defined(MOZ_ENABLE_JS_DUMP))
bool nsContentUtils::sDOMWindowDumpEnabled;
@ -538,52 +537,6 @@ private:
nsCString mCharset;
};
class StableStateEventTarget final : public nsISerialEventTarget
{
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIEVENTTARGET_FULL
private:
~StableStateEventTarget() {}
};
NS_IMPL_ISUPPORTS(StableStateEventTarget, nsISerialEventTarget);
bool
StableStateEventTarget::IsOnCurrentThreadInfallible()
{
return true;
}
NS_IMETHODIMP
StableStateEventTarget::IsOnCurrentThread(bool* aResult)
{
*aResult = true;
return NS_OK;
}
NS_IMETHODIMP
StableStateEventTarget::Dispatch(already_AddRefed<nsIRunnable> aEvent, uint32_t aFlags)
{
if (NS_WARN_IF(!CycleCollectedJSContext::Get())) {
return NS_ERROR_UNEXPECTED;
}
nsContentUtils::RunInStableState(Move(aEvent));
return NS_OK;
}
NS_IMETHODIMP
StableStateEventTarget::DispatchFromScript(nsIRunnable* aEvent, uint32_t aFlags)
{
return Dispatch(nsCOMPtr<nsIRunnable>(aEvent).forget(), aFlags);
}
NS_IMETHODIMP
StableStateEventTarget::DelayedDispatch(already_AddRefed<nsIRunnable> aEvent, uint32_t aDelay)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
} // namespace
/**
@ -789,9 +742,6 @@ nsContentUtils::Init()
Unused << nsRFPService::GetOrCreate();
RefPtr<StableStateEventTarget> stableStateEventTarget = new StableStateEventTarget();
stableStateEventTarget.forget(&sStableStateEventTarget);
nsCOMPtr<nsIUUIDGenerator> uuidGenerator =
do_GetService("@mozilla.org/uuid-generator;1", &rv);
if (NS_WARN_IF(NS_FAILED(rv))) {
@ -2218,8 +2168,6 @@ nsContentUtils::Shutdown()
NS_IF_RELEASE(sSameOriginChecker);
NS_IF_RELEASE(sStableStateEventTarget);
if (sUserInteractionObserver) {
sUserInteractionObserver->Shutdown();
NS_RELEASE(sUserInteractionObserver);
@ -5718,13 +5666,6 @@ nsContentUtils::RunInMetastableState(already_AddRefed<nsIRunnable> aRunnable)
CycleCollectedJSContext::Get()->RunInMetastableState(Move(aRunnable));
}
/* static */
nsISerialEventTarget*
nsContentUtils::GetStableStateEventTarget()
{
return sStableStateEventTarget;
}
void
nsContentUtils::EnterMicroTask()
{

Просмотреть файл

@ -1879,16 +1879,6 @@ public:
*/
static void RunInMetastableState(already_AddRefed<nsIRunnable> aRunnable);
/**
* Returns a nsISerialEventTarget which will run any event dispatched to it
* once the event loop has reached a "stable state". Runnables dispatched to
* this event target must not cause any queued events to be processed (i.e.
* must not spin the event loop).
*
* See RunInStableState for more information about stable states
*/
static nsISerialEventTarget* GetStableStateEventTarget();
// Call EnterMicroTask when you're entering JS execution.
// Usually the best way to do this is to use nsAutoMicroTask.
static void EnterMicroTask();
@ -3222,8 +3212,6 @@ private:
*/
static bool sFragmentParsingActive;
static nsISerialEventTarget* sStableStateEventTarget;
static nsString* sShiftText;
static nsString* sControlText;
static nsString* sMetaText;

Просмотреть файл

@ -857,17 +857,6 @@ ContentChild::ProvideWindowCommon(TabChild* aTabOpener,
uint32_t maxTouchPoints = 0;
DimensionInfo dimensionInfo;
nsCOMPtr<nsPIDOMWindowInner> parentTopInnerWindow;
if (aParent) {
nsCOMPtr<nsPIDOMWindowOuter> parentTopWindow =
nsPIDOMWindowOuter::From(aParent)->GetTop();
if (parentTopWindow) {
parentTopInnerWindow = parentTopWindow->GetCurrentInnerWindow();
}
}
// Send down the request to open the window.
RefPtr<CreateWindowPromise> windowCreated;
if (aIframeMoz) {
MOZ_ASSERT(aTabOpener);
nsAutoCString url;
@ -880,11 +869,10 @@ ContentChild::ProvideWindowCommon(TabChild* aTabOpener,
url.SetIsVoid(true);
}
// NOTE: BrowserFrameOpenWindowPromise is the same type as
// CreateWindowPromise, and this code depends on that fact.
windowCreated =
newChild->SendBrowserFrameOpenWindow(aTabOpener, renderFrame, NS_ConvertUTF8toUTF16(url),
name, NS_ConvertUTF8toUTF16(features));
newChild->SendBrowserFrameOpenWindow(aTabOpener, renderFrame, NS_ConvertUTF8toUTF16(url),
name, NS_ConvertUTF8toUTF16(features),
aWindowIsNew, &textureFactoryIdentifier,
&layersId, &compositorOptions, &maxTouchPoints);
} else {
nsAutoCString baseURIString;
float fullZoom;
@ -893,98 +881,30 @@ ContentChild::ProvideWindowCommon(TabChild* aTabOpener,
return rv;
}
windowCreated =
SendCreateWindow(aTabOpener, newChild, renderFrame,
aChromeFlags, aCalledFromJS, aPositionSpecified,
aSizeSpecified,
features,
baseURIString,
fullZoom);
}
// Await the promise being resolved. When the promise is resolved, we'll set
// the `ready` local variable, which will cause us to exit our nested event
// loop.
//
// NOTE: We need to run this callback on the StableStateEventTarget because we
// need to resolve our runnable and exit from the nested event loop before
// processing any events which were sent after the reply to CreateWindow was
// sent.
bool ready = false;
windowCreated->Then(nsContentUtils::GetStableStateEventTarget(), __func__,
[&] (const CreatedWindowInfo& info) {
MOZ_RELEASE_ASSERT(NS_IsMainThread(),
"windowCreated->Then must run on the main thread");
rv = info.rv();
*aWindowIsNew = info.windowOpened();
frameScripts = info.frameScripts();
urlToLoad = info.urlToLoad();
textureFactoryIdentifier = info.textureFactoryIdentifier();
layersId = info.layersId();
compositorOptions = info.compositorOptions();
maxTouchPoints = info.maxTouchPoints();
dimensionInfo = info.dimensions();
ready = true;
},
[&] (const CreateWindowPromise::RejectValueType aReason) {
MOZ_RELEASE_ASSERT(NS_IsMainThread(),
"windowCreated->Then must run on the main thread");
NS_WARNING("windowCreated promise rejected");
rv = NS_ERROR_NOT_AVAILABLE;
ready = true;
});
// =======================
// Begin Nested Event Loop
// =======================
// We have to wait for a response from either SendCreateWindow or
// SendBrowserFrameOpenWindow with information we're going to need to return
// from this function, So we spin a nested event loop until they get back to
// us.
// Prevent the docshell from becoming active while the nested event loop is
// spinning.
newChild->AddPendingDocShellBlocker();
auto removePendingDocShellBlocker = MakeScopeExit([&] {
if (newChild) {
newChild->RemovePendingDocShellBlocker();
if (!SendCreateWindow(aTabOpener, newChild, renderFrame,
aChromeFlags, aCalledFromJS, aPositionSpecified,
aSizeSpecified,
features,
baseURIString,
fullZoom,
&rv,
aWindowIsNew,
&frameScripts,
&urlToLoad,
&textureFactoryIdentifier,
&layersId,
&compositorOptions,
&maxTouchPoints,
&dimensionInfo)) {
PRenderFrameChild::Send__delete__(renderFrame);
return NS_ERROR_NOT_AVAILABLE;
}
});
// Suspend our window if we have one to make sure we don't re-enter it.
if (parentTopInnerWindow) {
parentTopInnerWindow->Suspend();
if (NS_FAILED(rv)) {
PRenderFrameChild::Send__delete__(renderFrame);
return rv;
}
}
{
AutoNoJSAPI nojsapi;
// Spin the event loop until we get a response. Callers of this function
// already have to guard against an inner event loop spinning in the
// non-e10s case because of the need to spin one to create a new chrome
// window.
SpinEventLoopUntil([&] () { return ready; });
MOZ_RELEASE_ASSERT(ready,
"We are on the main thread, so we should not exit this "
"loop without ready being true.");
}
if (parentTopInnerWindow) {
parentTopInnerWindow->Resume();
}
// =====================
// End Nested Event Loop
// =====================
// Handle the error which we got back from the parent process, if we got
// one.
if (NS_FAILED(rv)) {
PRenderFrameChild::Send__delete__(renderFrame);
return rv;
}
if (!*aWindowIsNew) {
PRenderFrameChild::Send__delete__(renderFrame);
return NS_ERROR_ABORT;

Просмотреть файл

@ -4630,30 +4630,25 @@ ContentParent::RecvCreateWindow(PBrowserParent* aThisTab,
const nsCString& aFeatures,
const nsCString& aBaseURI,
const float& aFullZoom,
CreateWindowResolver&& aResolve)
nsresult* aResult,
bool* aWindowIsNew,
InfallibleTArray<FrameScriptInfo>* aFrameScripts,
nsCString* aURLToLoad,
TextureFactoryIdentifier* aTextureFactoryIdentifier,
uint64_t* aLayersId,
CompositorOptions* aCompositorOptions,
uint32_t* aMaxTouchPoints,
DimensionInfo* aDimensions)
{
nsresult rv = NS_OK;
CreatedWindowInfo cwi;
// We always expect to open a new window here. If we don't, it's an error.
cwi.windowOpened() = true;
cwi.layersId() = 0;
cwi.maxTouchPoints() = 0;
// Make sure to resolve the resolver when this function exits, even if we
// failed to generate a valid response.
auto resolveOnExit = MakeScopeExit([&] {
// Copy over the nsresult, and then resolve.
cwi.rv() = rv;
aResolve(cwi);
});
*aWindowIsNew = true;
*aResult = NS_OK;
TabParent* newTab = TabParent::GetFrom(aNewTab);
MOZ_ASSERT(newTab);
auto destroyNewTabOnError = MakeScopeExit([&] {
// We always expect to open a new window here. If we don't, it's an error.
if (!cwi.windowOpened() || NS_FAILED(rv)) {
if (!*aWindowIsNew || NS_FAILED(*aResult)) {
if (newTab) {
newTab->Destroy();
}
@ -4664,7 +4659,7 @@ ContentParent::RecvCreateWindow(PBrowserParent* aThisTab,
// we must have an opener.
newTab->SetHasContentOpener(true);
TabParent::AutoUseNewTab aunt(newTab, &cwi.urlToLoad());
TabParent::AutoUseNewTab aunt(newTab, aURLToLoad);
const uint64_t nextTabParentId = ++sNextTabParentId;
sNextTabParents.Put(nextTabParentId, newTab);
@ -4673,35 +4668,35 @@ ContentParent::RecvCreateWindow(PBrowserParent* aThisTab,
CommonCreateWindow(aThisTab, /* aSetOpener = */ true, aChromeFlags,
aCalledFromJS, aPositionSpecified, aSizeSpecified,
nullptr, aFeatures, aBaseURI, aFullZoom,
nextTabParentId, NullString(), rv,
newRemoteTab, &cwi.windowOpened());
nextTabParentId, NullString(), *aResult,
newRemoteTab, aWindowIsNew);
if (!ipcResult) {
return ipcResult;
}
if (NS_WARN_IF(NS_FAILED(rv))) {
if (NS_WARN_IF(NS_FAILED(*aResult))) {
return IPC_OK();
}
if (sNextTabParents.GetAndRemove(nextTabParentId).valueOr(nullptr)) {
cwi.windowOpened() = false;
*aWindowIsNew = false;
}
MOZ_ASSERT(TabParent::GetFrom(newRemoteTab) == newTab);
newTab->SwapFrameScriptsFrom(cwi.frameScripts());
newTab->SwapFrameScriptsFrom(*aFrameScripts);
RenderFrameParent* rfp = static_cast<RenderFrameParent*>(aRenderFrame);
if (!newTab->SetRenderFrame(rfp) ||
!newTab->GetRenderFrameInfo(&cwi.textureFactoryIdentifier(), &cwi.layersId())) {
rv = NS_ERROR_FAILURE;
!newTab->GetRenderFrameInfo(aTextureFactoryIdentifier, aLayersId)) {
*aResult = NS_ERROR_FAILURE;
}
cwi.compositorOptions() = rfp->GetCompositorOptions();
*aCompositorOptions = rfp->GetCompositorOptions();
nsCOMPtr<nsIWidget> widget = newTab->GetWidget();
if (widget) {
cwi.maxTouchPoints() = widget->GetMaxTouchPoints();
cwi.dimensions() = newTab->GetDimensionInfo();
}
*aMaxTouchPoints = widget ? widget->GetMaxTouchPoints() : 0;
// NOTE: widget must be set for this to return a meaningful value.
*aDimensions = widget ? newTab->GetDimensionInfo() : DimensionInfo();
return IPC_OK();
}

Просмотреть файл

@ -536,7 +536,15 @@ public:
const nsCString& aFeatures,
const nsCString& aBaseURI,
const float& aFullZoom,
CreateWindowResolver&& aResolve) override;
nsresult* aResult,
bool* aWindowIsNew,
InfallibleTArray<FrameScriptInfo>* aFrameScripts,
nsCString* aURLToLoad,
layers::TextureFactoryIdentifier* aTextureFactoryIdentifier,
uint64_t* aLayersId,
mozilla::layers::CompositorOptions* aCompositorOptions,
uint32_t* aMaxTouchPoints,
DimensionInfo* aDimensions) override;
virtual mozilla::ipc::IPCResult RecvCreateWindowInDifferentProcess(
PBrowserParent* aThisTab,

Просмотреть файл

@ -22,8 +22,6 @@ using CSSRect from "Units.h";
using CSSSize from "Units.h";
using mozilla::LayoutDeviceIntPoint from "Units.h";
using mozilla::dom::ScreenOrientationInternal from "mozilla/dom/ScreenOrientation.h";
using struct mozilla::layers::TextureFactoryIdentifier from "mozilla/layers/CompositorTypes.h";
using mozilla::layers::CompositorOptions from "mozilla/layers/CompositorOptions.h";
namespace mozilla {
namespace dom {
@ -98,27 +96,5 @@ struct DimensionInfo
LayoutDeviceIntPoint chromeDisp;
};
struct FrameScriptInfo
{
nsString url;
bool runInGlobalScope;
};
/**
* The information required to complete a window creation request.
*/
struct CreatedWindowInfo
{
nsresult rv;
bool windowOpened;
FrameScriptInfo[] frameScripts;
nsCString urlToLoad;
TextureFactoryIdentifier textureFactoryIdentifier;
uint64_t layersId;
CompositorOptions compositorOptions;
uint32_t maxTouchPoints;
DimensionInfo dimensions;
};
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -149,6 +149,11 @@ parent:
async PPaymentRequest();
/**
* Return native data of root widget
*/
nested(inside_cpow) sync GetWidgetNativeData() returns (WindowsHandle value);
/**
* Sends an NS_NATIVE_CHILD_OF_SHAREABLE_WINDOW to be adopted by the
* widget's shareable window on the chrome side. Only used on Windows.
@ -454,9 +459,13 @@ parent:
*
* @param opener the PBrowser whose content called window.open.
*/
async BrowserFrameOpenWindow(PBrowser opener, PRenderFrame renderFrame,
nsString aURL, nsString aName, nsString aFeatures)
returns (CreatedWindowInfo window);
sync BrowserFrameOpenWindow(PBrowser opener, PRenderFrame renderFrame,
nsString aURL, nsString aName, nsString aFeatures)
returns (bool windowOpened,
TextureFactoryIdentifier textureFactoryIdentifier,
uint64_t layersId,
CompositorOptions compositorOptions,
uint32_t maxTouchPoints);
/**
* Tells the containing widget whether the given input block results in a
@ -889,12 +898,6 @@ child:
*/
async SetOriginAttributes(OriginAttributes aOriginAttributes);
/**
* Pass the current handle for the current native widget to the content
* process, so it can be used by PuppetWidget.
*/
async SetWidgetNativeData(WindowsHandle aHandle);
/*
* FIXME: write protocol!

Просмотреть файл

@ -177,6 +177,14 @@ struct DomainPolicyClone
URIParams[] superWhitelist;
};
struct FrameScriptInfo
{
nsString url;
bool runInGlobalScope;
};
struct AndroidSystemInfo
{
nsString device;
@ -980,17 +988,25 @@ parent:
sync GetGraphicsDeviceInitData()
returns (ContentDeviceData aData);
async CreateWindow(nullable PBrowser aThisTab,
PBrowser aNewTab,
PRenderFrame aRenderFrame,
uint32_t aChromeFlags,
bool aCalledFromJS,
bool aPositionSpecified,
bool aSizeSpecified,
nsCString aFeatures,
nsCString aBaseURI,
float aFullZoom)
returns (CreatedWindowInfo window);
sync CreateWindow(nullable PBrowser aThisTab,
PBrowser aNewTab,
PRenderFrame aRenderFrame,
uint32_t aChromeFlags,
bool aCalledFromJS,
bool aPositionSpecified,
bool aSizeSpecified,
nsCString aFeatures,
nsCString aBaseURI,
float aFullZoom)
returns (nsresult rv,
bool windowOpened,
FrameScriptInfo[] frameScripts,
nsCString urlToLoad,
TextureFactoryIdentifier textureFactoryIdentifier,
uint64_t layersId,
CompositorOptions compositorOptions,
uint32_t maxTouchPoints,
DimensionInfo dimensions);
async CreateWindowInDifferentProcess(
PBrowser aThisTab,

Просмотреть файл

@ -407,11 +407,6 @@ TabChild::TabChild(nsIContentChild* aManager,
#if defined(ACCESSIBILITY)
, mTopLevelDocAccessibleChild(nullptr)
#endif
, mPendingDocShellIsActive(false)
, mPendingDocShellPreserveLayers(false)
, mPendingDocShellReceivedMessage(false)
, mPendingDocShellBlockers(0)
, mWidgetNativeData(0)
{
nsWeakPtr weakPtrThis(do_GetWeakReference(static_cast<nsITabChild*>(this))); // for capture by the lambda
mSetAllowedTouchBehaviorCallback = [weakPtrThis](uint64_t aInputBlockId,
@ -2368,26 +2363,20 @@ TabChild::RecvDestroy()
return IPC_OK();
}
void
TabChild::AddPendingDocShellBlocker()
mozilla::ipc::IPCResult
TabChild::RecvSetDocShellIsActive(const bool& aIsActive,
const bool& aPreserveLayers,
const uint64_t& aLayerObserverEpoch)
{
mPendingDocShellBlockers++;
}
void
TabChild::RemovePendingDocShellBlocker()
{
mPendingDocShellBlockers--;
if (!mPendingDocShellBlockers && mPendingDocShellReceivedMessage) {
mPendingDocShellReceivedMessage = false;
InternalSetDocShellIsActive(mPendingDocShellIsActive,
mPendingDocShellPreserveLayers);
// Since SetDocShellIsActive requests come in from both the hang monitor
// channel and the PContent channel, we have an ordering problem. This code
// ensures that we respect the order in which the requests were made and
// ignore stale requests.
if (mLayerObserverEpoch >= aLayerObserverEpoch) {
return IPC_OK();
}
}
mLayerObserverEpoch = aLayerObserverEpoch;
void
TabChild::InternalSetDocShellIsActive(bool aIsActive, bool aPreserveLayers)
{
auto clearForcePaint = MakeScopeExit([&] {
// We might force a paint, or we might already have painted and this is a
// no-op. In either case, once we exit this scope, we need to alert the
@ -2413,7 +2402,7 @@ TabChild::InternalSetDocShellIsActive(bool aIsActive, bool aPreserveLayers)
// We send the current layer observer epoch to the compositor so that
// TabParent knows whether a layer update notification corresponds to the
// latest SetDocShellIsActive request that was made.
mPuppetWidget->GetLayerManager()->SetLayerObserverEpoch(mLayerObserverEpoch);
mPuppetWidget->GetLayerManager()->SetLayerObserverEpoch(aLayerObserverEpoch);
}
// docshell is consider prerendered only if not active yet
@ -2427,8 +2416,8 @@ TabChild::InternalSetDocShellIsActive(bool aIsActive, bool aPreserveLayers)
// notification to fire in the parent (so that it knows that the child has
// updated its epoch). ForcePaintNoOp does that.
if (IPCOpen()) {
Unused << SendForcePaintNoOp(mLayerObserverEpoch);
return;
Unused << SendForcePaintNoOp(aLayerObserverEpoch);
return IPC_OK();
}
}
@ -2469,33 +2458,7 @@ TabChild::InternalSetDocShellIsActive(bool aIsActive, bool aPreserveLayers)
} else if (!aPreserveLayers) {
MakeHidden();
}
}
mozilla::ipc::IPCResult
TabChild::RecvSetDocShellIsActive(const bool& aIsActive,
const bool& aPreserveLayers,
const uint64_t& aLayerObserverEpoch)
{
// Since requests to change the active docshell come in from both the hang
// monitor channel and the PContent channel, we have an ordering problem. This
// code ensures that we respect the order in which the requests were made and
// ignore stale requests.
if (mLayerObserverEpoch >= aLayerObserverEpoch) {
return IPC_OK();
}
mLayerObserverEpoch = aLayerObserverEpoch;
// If we're currently waiting for window opening to complete, we need to hold
// off on setting the docshell active. We queue up the values we're receiving
// in the mWindowOpenDocShellActiveStatus.
if (mPendingDocShellBlockers > 0) {
mPendingDocShellReceivedMessage = true;
mPendingDocShellIsActive = aIsActive;
mPendingDocShellPreserveLayers = aPreserveLayers;
return IPC_OK();
}
InternalSetDocShellIsActive(aIsActive, aPreserveLayers);
return IPC_OK();
}
@ -3213,13 +3176,6 @@ TabChild::RecvSetOriginAttributes(const OriginAttributes& aOriginAttributes)
return IPC_OK();
}
mozilla::ipc::IPCResult
TabChild::RecvSetWidgetNativeData(const WindowsHandle& aWidgetNativeData)
{
mWidgetNativeData = aWidgetNativeData;
return IPC_OK();
}
mozilla::plugins::PPluginWidgetChild*
TabChild::AllocPPluginWidgetChild()
{

Просмотреть файл

@ -694,15 +694,6 @@ public:
}
#endif
void AddPendingDocShellBlocker();
void RemovePendingDocShellBlocker();
// The HANDLE object for the widget this TabChild in.
WindowsHandle WidgetNativeData()
{
return mWidgetNativeData;
}
protected:
virtual ~TabChild();
@ -744,8 +735,6 @@ protected:
virtual mozilla::ipc::IPCResult RecvSetOriginAttributes(const OriginAttributes& aOriginAttributes) override;
virtual mozilla::ipc::IPCResult RecvSetWidgetNativeData(const WindowsHandle& aWidgetNativeData) override;
private:
void HandleDoubleTap(const CSSPoint& aPoint, const Modifiers& aModifiers,
const ScrollableLayerGuid& aGuid);
@ -801,9 +790,6 @@ private:
const ScrollableLayerGuid& aGuid,
const uint64_t& aInputBlockId);
void InternalSetDocShellIsActive(bool aIsActive,
bool aPreserveLayers);
class DelayedDeleteRunnable;
TextureFactoryIdentifier mTextureFactoryIdentifier;
@ -884,13 +870,6 @@ private:
PDocAccessibleChild* mTopLevelDocAccessibleChild;
#endif
bool mPendingDocShellIsActive;
bool mPendingDocShellPreserveLayers;
bool mPendingDocShellReceivedMessage;
uint32_t mPendingDocShellBlockers;
WindowsHandle mWidgetNativeData;
DISALLOW_EVIL_CONSTRUCTORS(TabChild);
};

Просмотреть файл

@ -292,17 +292,6 @@ TabParent::SetOwnerElement(Element* aElement)
AddWindowListeners();
TryCacheDPIAndScale();
// Try to send down WidgetNativeData, now that this TabParent is associated
// with a widget.
nsCOMPtr<nsIWidget> widget = GetTopLevelWidget();
if (widget) {
WindowsHandle widgetNativeData = reinterpret_cast<WindowsHandle>(
widget->GetNativeData(NS_NATIVE_SHAREABLE_WINDOW));
if (widgetNativeData) {
Unused << SendSetWidgetNativeData(widgetNativeData);
}
}
}
void
@ -2329,6 +2318,18 @@ TabParent::GetTopLevelWidget()
return nullptr;
}
mozilla::ipc::IPCResult
TabParent::RecvGetWidgetNativeData(WindowsHandle* aValue)
{
*aValue = 0;
nsCOMPtr<nsIWidget> widget = GetTopLevelWidget();
if (widget) {
*aValue = reinterpret_cast<WindowsHandle>(
widget->GetNativeData(NS_NATIVE_SHAREABLE_WINDOW));
}
return IPC_OK();
}
mozilla::ipc::IPCResult
TabParent::RecvSetNativeChildOfShareableWindow(const uintptr_t& aChildWindow)
{
@ -2582,31 +2583,21 @@ TabParent::RecvBrowserFrameOpenWindow(PBrowserParent* aOpener,
const nsString& aURL,
const nsString& aName,
const nsString& aFeatures,
BrowserFrameOpenWindowResolver&& aResolve)
bool* aOutWindowOpened,
TextureFactoryIdentifier* aTextureFactoryIdentifier,
uint64_t* aLayersId,
CompositorOptions* aCompositorOptions,
uint32_t* aMaxTouchPoints)
{
CreatedWindowInfo cwi;
cwi.rv() = NS_OK;
cwi.layersId() = 0;
cwi.maxTouchPoints() = 0;
BrowserElementParent::OpenWindowResult opened =
BrowserElementParent::OpenWindowOOP(TabParent::GetFrom(aOpener),
this, aRenderFrame, aURL, aName, aFeatures,
&cwi.textureFactoryIdentifier(),
&cwi.layersId());
cwi.compositorOptions() =
static_cast<RenderFrameParent*>(aRenderFrame)->GetCompositorOptions();
cwi.windowOpened() = (opened == BrowserElementParent::OPEN_WINDOW_ADDED);
aTextureFactoryIdentifier, aLayersId);
*aCompositorOptions = static_cast<RenderFrameParent*>(aRenderFrame)->GetCompositorOptions();
*aOutWindowOpened = (opened == BrowserElementParent::OPEN_WINDOW_ADDED);
nsCOMPtr<nsIWidget> widget = GetWidget();
if (widget) {
cwi.maxTouchPoints() = widget->GetMaxTouchPoints();
cwi.dimensions() = GetDimensionInfo();
}
// Resolve the request with the information we collected.
aResolve(cwi);
if (!cwi.windowOpened()) {
*aMaxTouchPoints = widget ? widget->GetMaxTouchPoints() : 0;
if (!*aOutWindowOpened) {
Destroy();
}
return IPC_OK();

Просмотреть файл

@ -165,13 +165,16 @@ public:
virtual mozilla::ipc::IPCResult
RecvSetHasBeforeUnload(const bool& aHasBeforeUnload) override;
virtual mozilla::ipc::IPCResult
RecvBrowserFrameOpenWindow(PBrowserParent* aOpener,
PRenderFrameParent* aRenderFrame,
const nsString& aURL,
const nsString& aName,
const nsString& aFeatures,
BrowserFrameOpenWindowResolver&& aResolve) override;
virtual mozilla::ipc::IPCResult RecvBrowserFrameOpenWindow(PBrowserParent* aOpener,
PRenderFrameParent* aRenderFrame,
const nsString& aURL,
const nsString& aName,
const nsString& aFeatures,
bool* aOutWindowOpened,
TextureFactoryIdentifier* aTextureFactoryIdentifier,
uint64_t* aLayersId,
CompositorOptions* aCompositorOptions,
uint32_t* aMaxTouchPoints) override;
virtual mozilla::ipc::IPCResult
RecvSyncMessage(const nsString& aMessage,
@ -305,6 +308,8 @@ public:
virtual mozilla::ipc::IPCResult RecvGetWidgetRounding(int32_t* aValue) override;
virtual mozilla::ipc::IPCResult RecvGetWidgetNativeData(WindowsHandle* aValue) override;
virtual mozilla::ipc::IPCResult RecvSetNativeChildOfShareableWindow(const uintptr_t& childWindow) override;
virtual mozilla::ipc::IPCResult RecvDispatchFocusToTopLevelWindow() override;

Просмотреть файл

@ -3125,13 +3125,14 @@ nsPermissionManager::GetPermissionsWithKey(const nsACString& aPermissionKey,
for (auto iter = mPermissionTable.Iter(); !iter.Done(); iter.Next()) {
PermissionHashKey* entry = iter.Get();
nsAutoCString permissionKey;
GetKeyForOrigin(entry->GetKey()->mOrigin, permissionKey);
// XXX: Is it worthwhile to have a shortcut Origin->Key implementation? as
// we could implement this without creating a codebase principal.
// If the keys don't match, and we aren't getting the default "" key, then
// we can exit early. We have to keep looking if we're getting the default
// key, as we may see a preload permission which should be transmitted.
if (aPermissionKey != permissionKey && !aPermissionKey.IsEmpty()) {
// Fetch the principal for the given origin.
nsCOMPtr<nsIPrincipal> principal;
nsresult rv = GetPrincipalFromOrigin(entry->GetKey()->mOrigin,
getter_AddRefs(principal));
if (NS_WARN_IF(NS_FAILED(rv))) {
continue;
}
@ -3143,8 +3144,14 @@ nsPermissionManager::GetPermissionsWithKey(const nsACString& aPermissionKey,
continue;
}
bool isPreload = IsPreloadPermission(mTypeArray[permEntry.mType].get());
if ((isPreload && aPermissionKey.IsEmpty()) || (!isPreload && aPermissionKey == permissionKey)) {
// XXX: This performs extra work, such as in many cases re-computing the
// Origin (which we just computed the nsIPrincipal from). We may want to
// implement a custom version of this logic which avoids that extra work.
// See bug 1354700.
nsAutoCString permissionKey;
GetKeyForPermission(principal, mTypeArray[permEntry.mType].get(), permissionKey);
if (permissionKey == aPermissionKey) {
aPerms.AppendElement(IPC::Permission(entry->GetKey()->mOrigin,
mTypeArray.ElementAt(permEntry.mType),
permEntry.mPermission,
@ -3206,64 +3213,44 @@ nsPermissionManager::SetPermissionsWithKey(const nsACString& aPermissionKey,
return NS_OK;
}
/* static */ void
nsPermissionManager::GetKeyForOrigin(const nsACString& aOrigin, nsACString& aKey)
{
aKey.Truncate();
// We only key origins for http, https, and ftp URIs. All origins begin with
// the URL which they apply to, which means that they should begin with their
// scheme in the case where they are one of these interesting URIs. We don't
// want to actually parse the URL here however, because this can be called on
// hot paths.
if (!StringBeginsWith(aOrigin, NS_LITERAL_CSTRING("http:")) &&
!StringBeginsWith(aOrigin, NS_LITERAL_CSTRING("https:")) &&
!StringBeginsWith(aOrigin, NS_LITERAL_CSTRING("ftp:"))) {
return;
}
// We need to look at the originAttributes if they are present, to make sure
// to remove any which we don't want. We put the rest of the origin, not
// including the attributes, into the key.
OriginAttributes attrs;
if (!attrs.PopulateFromOrigin(aOrigin, aKey)) {
aKey.Truncate();
return;
}
attrs.StripAttributes(OriginAttributes::STRIP_USER_CONTEXT_ID |
OriginAttributes::STRIP_FIRST_PARTY_DOMAIN);
#ifdef DEBUG
// Parse the origin string into a principal, and extract some useful
// information from it for assertions.
nsCOMPtr<nsIPrincipal> dbgPrincipal;
MOZ_ALWAYS_SUCCEEDS(GetPrincipalFromOrigin(aOrigin, getter_AddRefs(dbgPrincipal)));
nsCOMPtr<nsIURI> dbgUri;
MOZ_ALWAYS_SUCCEEDS(dbgPrincipal->GetURI(getter_AddRefs(dbgUri)));
nsAutoCString dbgScheme;
MOZ_ALWAYS_SUCCEEDS(dbgUri->GetScheme(dbgScheme));
MOZ_ASSERT(dbgScheme.EqualsLiteral("http") ||
dbgScheme.EqualsLiteral("https") ||
dbgScheme.EqualsLiteral("ftp"));
MOZ_ASSERT(dbgPrincipal->OriginAttributesRef() == attrs);
#endif
// Append the stripped suffix to the output origin key.
nsAutoCString suffix;
attrs.CreateSuffix(suffix);
aKey.Append(suffix);
}
/* static */ void
nsPermissionManager::GetKeyForPrincipal(nsIPrincipal* aPrincipal, nsACString& aKey)
{
nsAutoCString origin;
nsresult rv = aPrincipal->GetOrigin(origin);
if (NS_WARN_IF(NS_FAILED(rv))) {
MOZ_ASSERT(aPrincipal);
aKey.Truncate();
nsCOMPtr<nsIURI> uri;
nsresult rv = aPrincipal->GetURI(getter_AddRefs(uri));
if (NS_WARN_IF(NS_FAILED(rv) || !uri)) {
// NOTE: We don't propagate the error here, instead we produce the default
// "" permission key. This means that we can assign every principal a key,
// even if the GetURI operation on that principal is not meaningful.
aKey.Truncate();
return;
}
GetKeyForOrigin(origin, aKey);
nsAutoCString scheme;
rv = uri->GetScheme(scheme);
if (NS_WARN_IF(NS_FAILED(rv))) {
// NOTE: Produce the default "" key as a fallback.
aKey.Truncate();
return;
}
// URIs which have schemes other than http, https and ftp share the ""
// permission key.
if (scheme.EqualsLiteral("http") ||
scheme.EqualsLiteral("https") ||
scheme.EqualsLiteral("ftp")) {
rv = GetOriginFromPrincipal(aPrincipal, aKey);
if (NS_SUCCEEDED(rv)) {
return;
}
}
// NOTE: Produce the default "" key as a fallback.
aKey.Truncate();
return;
}
/* static */ void

Просмотреть файл

@ -229,22 +229,6 @@ public:
*/
static void GetKeyForPrincipal(nsIPrincipal* aPrincipal, nsACString& aPermissionKey);
/**
* See `nsIPermissionManager::GetPermissionsWithKey` for more info on
* permission keys.
*
* Get the permission key corresponding to the given Origin. This method is
* like GetKeyForPrincipal, except that it avoids creating a nsIPrincipal
* object when you already have access to an origin string.
*
* If this method is passed a nonsensical origin string it may produce a
* nonsensical permission key result.
*
* @param aOrigin The origin which the key is to be extracted from.
* @param aPermissionKey A string which will be filled with the permission key.
*/
static void GetKeyForOrigin(const nsACString& aOrigin, nsACString& aPermissionKey);
/**
* See `nsIPermissionManager::GetPermissionsWithKey` for more info on
* permission keys.

Просмотреть файл

@ -195,18 +195,6 @@ struct TextureFactoryIdentifier
, mSupportsBackdropCopyForComponentAlpha(true)
, mSyncHandle(aSyncHandle)
{}
bool operator==(const TextureFactoryIdentifier& aOther) const {
return
mParentBackend == aOther.mParentBackend &&
mParentProcessType == aOther.mParentProcessType &&
mMaxTextureSize == aOther.mMaxTextureSize &&
mCompositorUseANGLE == aOther.mCompositorUseANGLE &&
mSupportsTextureBlitting == aOther.mSupportsTextureBlitting &&
mSupportsPartialUploads == aOther.mSupportsPartialUploads &&
mSupportsComponentAlpha == aOther.mSupportsComponentAlpha &&
mSyncHandle == aOther.mSyncHandle;
}
};
/**

Просмотреть файл

@ -817,6 +817,8 @@ description =
description =
[PBrowser::PPluginWidget]
description =
[PBrowser::GetWidgetNativeData]
description =
[PBrowser::DispatchFocusToTopLevelWindow]
description =
[PBrowser::NotifyIMEFocus]
@ -837,6 +839,8 @@ description =
description =
[PBrowser::GetWidgetRounding]
description =
[PBrowser::BrowserFrameOpenWindow]
description =
[PBrowser::RequestNativeKeyBindings]
description =
[PBrowser::GetTabCount]
@ -905,6 +909,8 @@ description =
description =
[PContent::GetGraphicsDeviceInitData]
description =
[PContent::CreateWindow]
description =
[PContent::GetAndroidSystemInfo]
description =
[PContent::UngrabPointer]

Просмотреть файл

@ -1189,14 +1189,10 @@ PuppetWidget::GetNativeData(uint32_t aDataType)
{
switch (aDataType) {
case NS_NATIVE_SHAREABLE_WINDOW: {
// NOTE: We can not have a tab child in some situations, such as when we're
// rendering to a fake widget for thumbnails.
if (!mTabChild) {
NS_WARNING("Need TabChild to get the nativeWindow from!");
}
MOZ_ASSERT(mTabChild, "Need TabChild to get the nativeWindow from!");
mozilla::WindowsHandle nativeData = 0;
if (mTabChild) {
nativeData = mTabChild->WidgetNativeData();
mTabChild->SendGetWidgetNativeData(&nativeData);
}
return (void*)nativeData;
}