gecko-dev/dom/ipc/TabContext.cpp
Nicholas Nethercote 18fae65f38 Bug 1563139 - Remove StaticPrefs.h. r=glandium
This requires replacing inclusions of it with inclusions of more specific prefs
files.

The exception is that StaticPrefsAll.h, which is equivalent to StaticPrefs.h,
and is used in `Codegen.py` because doing something smarter is tricky and
suitable for a follow-up. As a result, any change to StaticPrefList.yaml will
still trigger recompilation of all the generated DOM bindings files, but that's
still a big improvement over trigger recompilation of every file that uses
static prefs.

Most of the changes in this commit are very boring. The only changes that are
not boring are modules/libpref/*, Codegen.py, and ServoBindings.toml.

Differential Revision: https://phabricator.services.mozilla.com/D39138

--HG--
extra : moz-landing-system : lando
2019-07-26 01:10:23 +00:00

244 lines
8.1 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: */
/* 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/TabContext.h"
#include "mozilla/dom/PTabContext.h"
#include "mozilla/dom/BrowserParent.h"
#include "mozilla/dom/BrowserChild.h"
#include "mozilla/StaticPrefs_dom.h"
#include "nsIScriptSecurityManager.h"
#include "nsServiceManagerUtils.h"
using namespace mozilla::dom::ipc;
using namespace mozilla::layout;
namespace mozilla {
namespace dom {
TabContext::TabContext()
: mInitialized(false),
mIsMozBrowserElement(false),
mChromeOuterWindowID(0),
mJSPluginID(-1),
mShowFocusRings(UIStateChangeType_NoChange),
mMaxTouchPoints(0) {}
bool TabContext::IsMozBrowserElement() const { return mIsMozBrowserElement; }
bool TabContext::IsMozBrowser() const { return IsMozBrowserElement(); }
bool TabContext::IsJSPlugin() const { return mJSPluginID >= 0; }
int32_t TabContext::JSPluginId() const { return mJSPluginID; }
uint64_t TabContext::ChromeOuterWindowID() const {
return mChromeOuterWindowID;
}
bool TabContext::SetTabContext(const TabContext& aContext) {
NS_ENSURE_FALSE(mInitialized, false);
*this = aContext;
mInitialized = true;
return true;
}
void TabContext::SetPrivateBrowsingAttributes(bool aIsPrivateBrowsing) {
mOriginAttributes.SyncAttributesWithPrivateBrowsing(aIsPrivateBrowsing);
}
bool TabContext::UpdateTabContextAfterSwap(const TabContext& aContext) {
// This is only used after already initialized.
MOZ_ASSERT(mInitialized);
// The only permissable changes are to `mIsMozBrowserElement` and
// mChromeOuterWindowID. All other fields must match for the change
// to be accepted.
if (aContext.mOriginAttributes != mOriginAttributes) {
return false;
}
mChromeOuterWindowID = aContext.mChromeOuterWindowID;
mIsMozBrowserElement = aContext.mIsMozBrowserElement;
return true;
}
const OriginAttributes& TabContext::OriginAttributesRef() const {
return mOriginAttributes;
}
const nsAString& TabContext::PresentationURL() const {
return mPresentationURL;
}
UIStateChangeType TabContext::ShowFocusRings() const { return mShowFocusRings; }
bool TabContext::SetTabContext(bool aIsMozBrowserElement,
uint64_t aChromeOuterWindowID,
UIStateChangeType aShowFocusRings,
const OriginAttributes& aOriginAttributes,
const nsAString& aPresentationURL,
uint32_t aMaxTouchPoints) {
NS_ENSURE_FALSE(mInitialized, false);
mInitialized = true;
mIsMozBrowserElement = aIsMozBrowserElement;
mChromeOuterWindowID = aChromeOuterWindowID;
mOriginAttributes = aOriginAttributes;
mPresentationURL = aPresentationURL;
mShowFocusRings = aShowFocusRings;
mMaxTouchPoints = aMaxTouchPoints;
return true;
}
bool TabContext::SetTabContextForJSPluginFrame(int32_t aJSPluginID) {
NS_ENSURE_FALSE(mInitialized, false);
mInitialized = true;
mJSPluginID = aJSPluginID;
return true;
}
IPCTabContext TabContext::AsIPCTabContext() const {
if (IsJSPlugin()) {
return IPCTabContext(JSPluginFrameIPCTabContext(mJSPluginID));
}
return IPCTabContext(FrameIPCTabContext(
mOriginAttributes, mIsMozBrowserElement, mChromeOuterWindowID,
mPresentationURL, mShowFocusRings, mMaxTouchPoints));
}
MaybeInvalidTabContext::MaybeInvalidTabContext(const IPCTabContext& aParams)
: mInvalidReason(nullptr) {
bool isMozBrowserElement = false;
uint64_t chromeOuterWindowID = 0;
int32_t jsPluginId = -1;
OriginAttributes originAttributes;
nsAutoString presentationURL;
UIStateChangeType showFocusRings = UIStateChangeType_NoChange;
uint32_t maxTouchPoints = 0;
switch (aParams.type()) {
case IPCTabContext::TPopupIPCTabContext: {
const PopupIPCTabContext& ipcContext = aParams.get_PopupIPCTabContext();
TabContext* context;
if (ipcContext.opener().type() == PBrowserOrId::TPBrowserParent) {
context =
BrowserParent::GetFrom(ipcContext.opener().get_PBrowserParent());
if (!context) {
mInvalidReason =
"Child is-browser process tried to "
"open a null tab.";
return;
}
if (context->IsMozBrowserElement() &&
!ipcContext.isMozBrowserElement()) {
// If the BrowserParent corresponds to a browser element, then it can
// only open other browser elements, for security reasons. We should
// have checked this before calling the TabContext constructor, so
// this is a fatal error.
mInvalidReason =
"Child is-browser process tried to "
"open a non-browser tab.";
return;
}
} else if (ipcContext.opener().type() == PBrowserOrId::TPBrowserChild) {
context =
static_cast<BrowserChild*>(ipcContext.opener().get_PBrowserChild());
} else if (ipcContext.opener().type() == PBrowserOrId::TTabId) {
// We should never get here because this PopupIPCTabContext is only
// used for allocating a new tab id, not for allocating a PBrowser.
mInvalidReason =
"Child process tried to open an tab without the opener "
"information.";
return;
} else {
// This should be unreachable because PopupIPCTabContext::opener is not
// a nullable field.
mInvalidReason = "PopupIPCTabContext::opener was null (?!).";
return;
}
// Browser elements can't nest other browser elements. So if
// our opener is browser element, we must be a new DOM window
// opened by it. In that case we inherit our containing app ID
// (if any).
//
// Otherwise, we're a new app window and we inherit from our
// opener app.
isMozBrowserElement = ipcContext.isMozBrowserElement();
originAttributes = context->mOriginAttributes;
chromeOuterWindowID = ipcContext.chromeOuterWindowID();
break;
}
case IPCTabContext::TJSPluginFrameIPCTabContext: {
const JSPluginFrameIPCTabContext& ipcContext =
aParams.get_JSPluginFrameIPCTabContext();
jsPluginId = ipcContext.jsPluginId();
break;
}
case IPCTabContext::TFrameIPCTabContext: {
const FrameIPCTabContext& ipcContext = aParams.get_FrameIPCTabContext();
isMozBrowserElement = ipcContext.isMozBrowserElement();
chromeOuterWindowID = ipcContext.chromeOuterWindowID();
presentationURL = ipcContext.presentationURL();
showFocusRings = ipcContext.showFocusRings();
originAttributes = ipcContext.originAttributes();
maxTouchPoints = ipcContext.maxTouchPoints();
break;
}
case IPCTabContext::TUnsafeIPCTabContext: {
// XXXcatalinb: This used *only* by ServiceWorkerClients::OpenWindow.
// It is meant as a temporary solution until service workers can
// provide a BrowserChild equivalent. Don't allow this on b2g since
// it might be used to escalate privileges.
if (!StaticPrefs::dom_serviceWorkers_enabled()) {
mInvalidReason = "ServiceWorkers should be enabled.";
return;
}
break;
}
default: {
MOZ_CRASH();
}
}
bool rv;
if (jsPluginId >= 0) {
rv = mTabContext.SetTabContextForJSPluginFrame(jsPluginId);
} else {
rv = mTabContext.SetTabContext(isMozBrowserElement, chromeOuterWindowID,
showFocusRings, originAttributes,
presentationURL, maxTouchPoints);
}
if (!rv) {
mInvalidReason = "Couldn't initialize TabContext.";
}
}
bool MaybeInvalidTabContext::IsValid() { return mInvalidReason == nullptr; }
const char* MaybeInvalidTabContext::GetInvalidReason() {
return mInvalidReason;
}
const TabContext& MaybeInvalidTabContext::GetTabContext() {
if (!IsValid()) {
MOZ_CRASH("Can't GetTabContext() if !IsValid().");
}
return mTabContext;
}
} // namespace dom
} // namespace mozilla