Backed out changeset a6a847452dbf (bug 802366)

This commit is contained in:
Justin Lebar 2012-10-30 21:36:29 -04:00
parent 7131844d4f
commit 22489f7920
25 changed files with 383 additions and 445 deletions

View File

@ -8359,7 +8359,7 @@ HasCrossProcessParent(nsIDocument* aDocument)
if (!docShell) {
return false;
}
return docShell->GetIsBrowserOrApp();
return docShell->GetIsContentBoundary();
}
static bool

View File

@ -944,7 +944,7 @@ nsFrameLoader::ShowRemoteFrame(const nsIntSize& size)
EnsureMessageManager();
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
if (OwnerIsBrowserOrAppFrame() && os && !mRemoteBrowserInitialized) {
if (OwnerIsBrowserFrame() && os && !mRemoteBrowserInitialized) {
os->NotifyObservers(NS_ISUPPORTS_CAST(nsIFrameLoader*, this),
"remote-browser-frame-shown", NULL);
mRemoteBrowserInitialized = true;
@ -1393,23 +1393,25 @@ nsFrameLoader::SetOwnerContent(Element* aContent)
}
bool
nsFrameLoader::OwnerIsBrowserOrAppFrame()
nsFrameLoader::OwnerIsBrowserFrame()
{
nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(mOwnerContent);
return browserFrame ? browserFrame->GetReallyIsBrowserOrApp() : false;
bool isBrowser = false;
if (browserFrame) {
browserFrame->GetReallyIsBrowser(&isBrowser);
}
return isBrowser;
}
bool
nsFrameLoader::OwnerIsAppFrame()
{
nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(mOwnerContent);
return browserFrame ? browserFrame->GetReallyIsApp() : false;
}
bool
nsFrameLoader::OwnerIsBrowserFrame()
{
return OwnerIsBrowserOrAppFrame() && !OwnerIsAppFrame();
bool isApp = false;
if (browserFrame) {
browserFrame->GetReallyIsApp(&isApp);
}
return isApp;
}
void
@ -1422,55 +1424,6 @@ nsFrameLoader::GetOwnerAppManifestURL(nsAString& aOut)
}
}
already_AddRefed<mozIApplication>
nsFrameLoader::GetOwnApp()
{
nsAutoString manifest;
GetOwnerAppManifestURL(manifest);
if (manifest.IsEmpty()) {
return nullptr;
}
nsCOMPtr<nsIAppsService> appsService = do_GetService(APPS_SERVICE_CONTRACTID);
NS_ENSURE_TRUE(appsService, nullptr);
nsCOMPtr<mozIDOMApplication> domApp;
appsService->GetAppByManifestURL(manifest, getter_AddRefs(domApp));
nsCOMPtr<mozIApplication> app = do_QueryInterface(domApp);
MOZ_ASSERT_IF(domApp, app);
return app.forget();
}
already_AddRefed<mozIApplication>
nsFrameLoader::GetOwnOrContainingApp()
{
nsCOMPtr<mozIApplication> app = GetOwnApp();
if (app) {
return app.forget();
}
// See if our owner content's principal has an associated app.
uint32_t appId = mOwnerContent->NodePrincipal()->GetAppId();
MOZ_ASSERT(appId != nsIScriptSecurityManager::UNKNOWN_APP_ID);
if (appId == nsIScriptSecurityManager::NO_APP_ID ||
appId == nsIScriptSecurityManager::UNKNOWN_APP_ID) {
return nullptr;
}
nsCOMPtr<nsIAppsService> appsService = do_GetService(APPS_SERVICE_CONTRACTID);
NS_ENSURE_TRUE(appsService, nullptr);
nsCOMPtr<mozIDOMApplication> domApp;
appsService->GetAppByLocalId(appId, getter_AddRefs(domApp));
MOZ_ASSERT(domApp);
app = do_QueryInterface(domApp);
MOZ_ASSERT_IF(domApp, app);
return app.forget();
}
bool
nsFrameLoader::ShouldUseRemoteProcess()
{
@ -1487,7 +1440,7 @@ nsFrameLoader::ShouldUseRemoteProcess()
// If we're an <iframe mozbrowser> and we don't have a "remote" attribute,
// fall back to the default.
if (OwnerIsBrowserOrAppFrame() &&
if (OwnerIsBrowserFrame() &&
!mOwnerContent->HasAttr(kNameSpaceID_None, nsGkAtoms::Remote)) {
return Preferences::GetBool("dom.ipc.browser_frames.oop_by_default", false);
@ -1495,7 +1448,7 @@ nsFrameLoader::ShouldUseRemoteProcess()
// Otherwise, we're remote if we have "remote=true" and we're either a
// browser frame or a XUL element.
return (OwnerIsBrowserOrAppFrame() ||
return (OwnerIsBrowserFrame() ||
mOwnerContent->GetNameSpaceID() == kNameSpaceID_XUL) &&
mOwnerContent->AttrValueIs(kNameSpaceID_None,
nsGkAtoms::Remote,
@ -1542,6 +1495,24 @@ nsFrameLoader::MaybeCreateDocShell()
mDocShell = do_CreateInstance("@mozilla.org/docshell;1");
NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);
if (OwnerIsBrowserFrame()) {
nsAutoString manifest;
GetOwnerAppManifestURL(manifest);
if (!manifest.IsEmpty()) {
nsCOMPtr<nsIAppsService> appsService =
do_GetService(APPS_SERVICE_CONTRACTID);
if (!appsService) {
NS_ERROR("Apps Service is not available!");
return NS_ERROR_FAILURE;
}
uint32_t appId;
appsService->GetAppLocalIdByManifestURL(manifest, &appId);
mDocShell->SetAppId(appId);
}
}
if (!mNetworkCreated) {
nsCOMPtr<nsIDocShellHistory> history = do_QueryInterface(mDocShell);
if (history) {
@ -1643,34 +1614,9 @@ nsFrameLoader::MaybeCreateDocShell()
EnsureMessageManager();
if (OwnerIsAppFrame()) {
// You can't be both an app and a browser frame.
MOZ_ASSERT(!OwnerIsBrowserFrame());
nsCOMPtr<mozIApplication> ownApp = GetOwnApp();
MOZ_ASSERT(ownApp);
uint32_t ownAppId = nsIScriptSecurityManager::NO_APP_ID;
if (ownApp) {
NS_ENSURE_SUCCESS(ownApp->GetLocalId(&ownAppId), NS_ERROR_FAILURE);
}
mDocShell->SetIsApp(ownAppId);
}
if (OwnerIsBrowserFrame()) {
// You can't be both a browser and an app frame.
MOZ_ASSERT(!OwnerIsAppFrame());
mDocShell->SetIsBrowserElement();
nsCOMPtr<mozIApplication> containingApp = GetOwnOrContainingApp();
uint32_t containingAppId = nsIScriptSecurityManager::NO_APP_ID;
if (containingApp) {
NS_ENSURE_SUCCESS(containingApp->GetLocalId(&containingAppId),
NS_ERROR_FAILURE);
}
mDocShell->SetIsBrowserInsideApp(containingAppId);
}
if (OwnerIsBrowserOrAppFrame()) {
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
if (os) {
os->NotifyObservers(NS_ISUPPORTS_CAST(nsIFrameLoader*, this),
@ -2002,7 +1948,7 @@ nsFrameLoader::TryRemoteBrowser()
nsCOMPtr<nsIDocShellTreeItem> parentAsItem(do_QueryInterface(parentAsWebNav));
// <iframe mozbrowser> gets to skip these checks.
if (!OwnerIsBrowserOrAppFrame()) {
if (!OwnerIsBrowserFrame()) {
int32_t parentType;
parentAsItem->GetItemType(&parentType);
@ -2038,18 +1984,35 @@ nsFrameLoader::TryRemoteBrowser()
return false;
}
// Get our own or containing app only if we're a browser or app frame. We
// want to avoid the situation where, if we're a remote frame that's neither
// a browser nor an app frame, we pass our containing app to
// ContentParent::CreateBrowserOrApp below, because that would effectively
// give this non-browser-or-app frame app privileges.
bool isBrowserElement = false;
nsCOMPtr<mozIApplication> app;
if (OwnerIsBrowserOrAppFrame()) {
app = GetOwnOrContainingApp();
if (OwnerIsBrowserFrame()) {
isBrowserElement = true;
nsAutoString manifest;
GetOwnerAppManifestURL(manifest);
if (!manifest.IsEmpty()) {
nsCOMPtr<nsIAppsService> appsService = do_GetService(APPS_SERVICE_CONTRACTID);
if (!appsService) {
NS_ERROR("Apps Service is not available!");
return false;
}
nsCOMPtr<mozIDOMApplication> domApp;
appsService->GetAppByManifestURL(manifest, getter_AddRefs(domApp));
// If the frame is actually an app, we should not mark it as a
// browser. This is to identify the data store: since <app>s
// and <browser>s-within-<app>s have different stores, we want
// to ensure the <app> uses its store, not the one for its
// <browser>s.
app = do_QueryInterface(domApp);
if (app) {
isBrowserElement = false;
}
}
}
mRemoteBrowser = ContentParent::CreateBrowserOrApp(app, OwnerIsBrowserFrame());
if (mRemoteBrowser) {
if ((mRemoteBrowser = ContentParent::CreateBrowser(app, isBrowserElement))) {
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(mOwnerContent);
mRemoteBrowser->SetOwnerElement(element);
@ -2359,7 +2322,7 @@ nsFrameLoader::EnsureMessageManager()
return rv;
}
if (!mIsTopLevelContent && !OwnerIsBrowserOrAppFrame() && !mRemoteFrame) {
if (!mIsTopLevelContent && !OwnerIsBrowserFrame() && !mRemoteFrame) {
return NS_OK;
}

View File

@ -33,7 +33,6 @@ class nsITabParent;
class nsIDocShellTreeItem;
class nsIDocShellTreeOwner;
class nsIDocShellTreeNode;
class mozIApplication;
namespace mozilla {
namespace dom {
@ -314,9 +313,9 @@ private:
/**
* Is this a frameloader for a bona fide <iframe mozbrowser> or
* <iframe mozapp>? (I.e., does the frame return true for
* nsIMozBrowserFrame::GetReallyIsBrowserOrApp()?)
* nsIMozBrowserFrame::GetReallyIsBrowser()?)
*/
bool OwnerIsBrowserOrAppFrame();
bool OwnerIsBrowserFrame();
/**
* Is this a frameloader for a bona fide <iframe mozapp>? (I.e., does the
@ -324,31 +323,12 @@ private:
*/
bool OwnerIsAppFrame();
/**
* Is this a frame loader for a bona fide <iframe mozbrowser>?
*/
bool OwnerIsBrowserFrame();
/**
* Get our owning element's app manifest URL, or return the empty string if
* our owning element doesn't have an app manifest URL.
*/
void GetOwnerAppManifestURL(nsAString& aOut);
/**
* Get the app for our frame. This is the app whose manifest is returned by
* GetOwnerAppManifestURL.
*/
already_AddRefed<mozIApplication> GetOwnApp();
/**
* Get the closest app to our frame. This is either the frame returned by
* GetOwnApp() or the app associated with our owner element's principal.
*
* That is, this method returns the app that our owner content is inside.
*/
already_AddRefed<mozIApplication> GetOwnOrContainingApp();
/**
* If we are an IPC frame, set mRemoteFrame. Otherwise, create and
* initialize mDocShell.

View File

@ -97,15 +97,14 @@ nsInProcessTabChildGlobal::nsInProcessTabChildGlobal(nsIDocShell* aShell,
mDelayedDisconnect(false), mOwner(aOwner), mChromeMessageManager(aChrome)
{
// If owner corresponds to an <iframe mozbrowser> or <iframe mozapp>, we'll
// have to tweak our PreHandleEvent implementation.
// If owner corresponds to an <iframe mozbrowser>, we'll have to tweak our
// PreHandleEvent implementation.
nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(mOwner);
bool isBrowser = false;
if (browserFrame) {
mIsBrowserOrAppFrame = browserFrame->GetReallyIsBrowserOrApp();
}
else {
mIsBrowserOrAppFrame = false;
browserFrame->GetReallyIsBrowser(&isBrowser);
}
mIsBrowserFrame = isBrowser;
}
nsInProcessTabChildGlobal::~nsInProcessTabChildGlobal()
@ -269,7 +268,7 @@ nsInProcessTabChildGlobal::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
{
aVisitor.mCanHandle = true;
if (mIsBrowserOrAppFrame &&
if (mIsBrowserFrame &&
(!mOwner || !nsContentUtils::IsInChromeDocshell(mOwner->OwnerDoc()))) {
if (mOwner) {
nsPIDOMWindow* innerWindow = mOwner->OwnerDoc()->GetInnerWindow();

View File

@ -122,10 +122,9 @@ protected:
bool mLoadingScript;
bool mDelayedDisconnect;
// Is this the message manager for an in-process <iframe mozbrowser> or
// <iframe mozapp>? This affects where events get sent, so it affects
// PreHandleEvent.
bool mIsBrowserOrAppFrame;
// Is this the message manager for an in-process <iframe mozbrowser>? This
// affects where events get sent, so it affects PreHandleEvent.
bool mIsBrowserFrame;
public:
nsIContent* mOwner;
nsFrameMessageManager* mChromeMessageManager;

View File

@ -1570,10 +1570,14 @@ nsEventStateManager::IsRemoteTarget(nsIContent* target) {
return true;
}
// <frame/iframe mozbrowser/mozapp>
// <frame/iframe mozbrowser>
nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(target);
if (browserFrame && browserFrame->GetReallyIsBrowserOrApp()) {
return !!TabParent::GetFrom(target);
if (browserFrame) {
bool isBrowser = false;
browserFrame->GetReallyIsBrowser(&isBrowser);
if (isBrowser) {
return !!TabParent::GetFrom(target);
}
}
return false;

View File

@ -278,8 +278,8 @@ nsGenericHTMLFrameElement::IsHTMLFocusable(bool aWithMouse,
* needs to have the right attributes, and its creator must have the right
* permissions.)
*/
/* [infallible] */ nsresult
nsGenericHTMLFrameElement::GetReallyIsBrowserOrApp(bool *aOut)
nsresult
nsGenericHTMLFrameElement::GetReallyIsBrowser(bool *aOut)
{
*aOut = false;
@ -289,9 +289,9 @@ nsGenericHTMLFrameElement::GetReallyIsBrowserOrApp(bool *aOut)
}
// Fail if this frame doesn't have the mozbrowser attribute.
bool hasMozbrowser = false;
GetMozbrowser(&hasMozbrowser);
if (!hasMozbrowser) {
bool isBrowser = false;
GetMozbrowser(&isBrowser);
if (!isBrowser) {
return NS_OK;
}
@ -299,7 +299,7 @@ nsGenericHTMLFrameElement::GetReallyIsBrowserOrApp(bool *aOut)
nsIPrincipal *principal = NodePrincipal();
nsCOMPtr<nsIPermissionManager> permMgr =
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
NS_ENSURE_TRUE(permMgr, NS_OK);
NS_ENSURE_STATE(permMgr);
uint32_t permission = nsIPermissionManager::DENY_ACTION;
nsresult rv = permMgr->TestPermissionFromPrincipal(principal, "browser", &permission);
@ -308,7 +308,7 @@ nsGenericHTMLFrameElement::GetReallyIsBrowserOrApp(bool *aOut)
return NS_OK;
}
/* [infallible] */ NS_IMETHODIMP
NS_IMETHODIMP
nsGenericHTMLFrameElement::GetReallyIsApp(bool *aOut)
{
nsAutoString manifestURL;
@ -324,7 +324,9 @@ nsGenericHTMLFrameElement::GetAppManifestURL(nsAString& aOut)
aOut.Truncate();
// At the moment, you can't be an app without being a browser.
if (!nsIMozBrowserFrame::GetReallyIsBrowserOrApp()) {
bool isBrowser = false;
GetReallyIsBrowser(&isBrowser);
if (!isBrowser) {
return NS_OK;
}
@ -332,7 +334,7 @@ nsGenericHTMLFrameElement::GetAppManifestURL(nsAString& aOut)
nsIPrincipal *principal = NodePrincipal();
nsCOMPtr<nsIPermissionManager> permMgr =
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
NS_ENSURE_TRUE(permMgr, NS_OK);
NS_ENSURE_STATE(permMgr);
uint32_t permission = nsIPermissionManager::DENY_ACTION;
nsresult rv = permMgr->TestPermissionFromPrincipal(principal,
@ -350,10 +352,11 @@ nsGenericHTMLFrameElement::GetAppManifestURL(nsAString& aOut)
}
nsCOMPtr<nsIAppsService> appsService = do_GetService(APPS_SERVICE_CONTRACTID);
NS_ENSURE_TRUE(appsService, NS_OK);
NS_ENSURE_STATE(appsService);
nsCOMPtr<mozIDOMApplication> app;
appsService->GetAppByManifestURL(manifestURL, getter_AddRefs(app));
if (app) {
aOut.Assign(manifestURL);
}

View File

@ -326,7 +326,7 @@ bool nsDSURIContentListener::CheckOneFrameOptionsPolicy(nsIRequest *request,
parentDocShellItem) {
nsCOMPtr<nsIDocShell> curDocShell = do_QueryInterface(curDocShellItem);
if (curDocShell && curDocShell->GetIsBrowserOrApp()) {
if (curDocShell && curDocShell->GetIsContentBoundary()) {
break;
}

View File

@ -729,7 +729,6 @@ nsDocShell::nsDocShell():
mCharsetReloadState(eCharsetReloadInit),
mChildOffset(0),
mBusyFlags(BUSY_FLAGS_NONE),
mFrameType(eFrameTypeRegular),
mAppType(nsIDocShell::APP_TYPE_UNKNOWN),
mLoadType(0),
mMarginWidth(-1),
@ -767,7 +766,7 @@ nsDocShell::nsDocShell():
#ifdef DEBUG
mInEnsureScriptEnv(false),
#endif
mOwnOrContainingAppId(nsIScriptSecurityManager::UNKNOWN_APP_ID),
mAppId(nsIScriptSecurityManager::NO_APP_ID),
mParentCharsetSource(0)
{
mHistoryID = ++gDocshellIDCounter;
@ -2136,7 +2135,7 @@ nsDocShell::GetFullscreenAllowed(bool* aFullscreenAllowed)
{
NS_ENSURE_ARG_POINTER(aFullscreenAllowed);
// Browsers and apps have their mFullscreenAllowed retrieved from their
// Content boundaries have their mFullscreenAllowed retrieved from their
// corresponding iframe in their parent upon creation.
if (mFullscreenAllowed != CHECK_ATTRIBUTES) {
*aFullscreenAllowed = (mFullscreenAllowed == PARENT_ALLOWS);
@ -2146,9 +2145,9 @@ nsDocShell::GetFullscreenAllowed(bool* aFullscreenAllowed)
// Assume false until we determine otherwise...
*aFullscreenAllowed = false;
// For non-browsers/apps, check that the enclosing iframe element
// For non-content boundaries, check that the enclosing iframe element
// has the allowfullscreen attribute set to true. If any ancestor
// iframe does not have mozallowfullscreen=true, then fullscreen is
// iframe does not have allowfullscreen=true, then fullscreen is
// prohibited.
nsCOMPtr<nsPIDOMWindow> win = do_GetInterface(GetAsSupports(this));
if (!win) {
@ -2185,7 +2184,7 @@ nsDocShell::GetFullscreenAllowed(bool* aFullscreenAllowed)
NS_IMETHODIMP
nsDocShell::SetFullscreenAllowed(bool aFullscreenAllowed)
{
if (!nsIDocShell::GetIsBrowserOrApp()) {
if (!nsIDocShell::GetIsContentBoundary()) {
// Only allow setting of fullscreenAllowed on content/process boundaries.
// At non-boundaries the fullscreenAllowed attribute is calculated based on
// whether all enclosing frames have the "mozFullscreenAllowed" attribute
@ -2797,7 +2796,7 @@ nsDocShell::GetSameTypeParent(nsIDocShellTreeItem ** aParent)
NS_ENSURE_ARG_POINTER(aParent);
*aParent = nullptr;
if (nsIDocShell::GetIsBrowserOrApp()) {
if (mIsBrowserFrame) {
return NS_OK;
}
@ -2919,11 +2918,19 @@ nsDocShell::CanAccessItem(nsIDocShellTreeItem* aTargetItem,
return false;
}
if (targetDS && accessingDS &&
(targetDS->GetIsInBrowserElement() !=
accessingDS->GetIsInBrowserElement() ||
targetDS->GetAppId() != accessingDS->GetAppId())) {
return false;
if (targetDS && accessingDS) {
bool targetInBrowser = false, accessingInBrowser = false;
targetDS->GetIsInBrowserElement(&targetInBrowser);
accessingDS->GetIsInBrowserElement(&accessingInBrowser);
uint32_t targetAppId = 0, accessingAppId = 0;
targetDS->GetAppId(&targetAppId);
accessingDS->GetAppId(&accessingAppId);
if (targetInBrowser != accessingInBrowser ||
targetAppId != accessingAppId) {
return false;
}
}
nsCOMPtr<nsIDocShellTreeItem> accessingRoot;
@ -5207,7 +5214,7 @@ nsDocShell::SetIsActive(bool aIsActive)
continue;
}
if (!docshell->GetIsBrowserOrApp()) {
if (!docshell->GetIsContentBoundary()) {
docshell->SetIsActive(aIsActive);
}
}
@ -12283,52 +12290,19 @@ nsDocShell::GetCanExecuteScripts(bool *aResult)
}
NS_IMETHODIMP
nsDocShell::SetIsApp(uint32_t aOwnAppId)
nsDocShell::SetIsBrowserElement()
{
mOwnOrContainingAppId = aOwnAppId;
if (aOwnAppId != nsIScriptSecurityManager::NO_APP_ID &&
aOwnAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID) {
mFrameType = eFrameTypeApp;
} else {
mFrameType = eFrameTypeRegular;
if (mIsBrowserFrame) {
NS_ERROR("You should not call SetIsBrowserElement() more than once.");
return NS_OK;
}
return NS_OK;
}
mIsBrowserFrame = true;
NS_IMETHODIMP
nsDocShell::SetIsBrowserInsideApp(uint32_t aContainingAppId)
{
mOwnOrContainingAppId = aContainingAppId;
mFrameType = eFrameTypeBrowser;
return NS_OK;
}
/* [infallible] */ NS_IMETHODIMP
nsDocShell::GetIsBrowserElement(bool* aIsBrowser)
{
*aIsBrowser = (mFrameType == eFrameTypeBrowser);
return NS_OK;
}
/* [infallible] */ NS_IMETHODIMP
nsDocShell::GetIsApp(bool* aIsApp)
{
*aIsApp = (mFrameType == eFrameTypeApp);
return NS_OK;
}
/* [infallible] */ NS_IMETHODIMP
nsDocShell::GetIsBrowserOrApp(bool* aIsBrowserOrApp)
{
switch (mFrameType) {
case eFrameTypeRegular:
*aIsBrowserOrApp = false;
break;
case eFrameTypeBrowser:
case eFrameTypeApp:
*aIsBrowserOrApp = true;
break;
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
if (os) {
os->NotifyObservers(GetAsSupports(this),
"docshell-marked-as-browser-frame", NULL);
}
return NS_OK;
@ -12337,8 +12311,10 @@ nsDocShell::GetIsBrowserOrApp(bool* aIsBrowserOrApp)
nsDocShell::FrameType
nsDocShell::GetInheritedFrameType()
{
if (mFrameType != eFrameTypeRegular) {
return mFrameType;
FrameType type = GetFrameType();
if (type != eFrameTypeRegular) {
return type;
}
nsCOMPtr<nsIDocShellTreeItem> parentAsItem;
@ -12352,6 +12328,46 @@ nsDocShell::GetInheritedFrameType()
return static_cast<nsDocShell*>(parent.get())->GetInheritedFrameType();
}
nsDocShell::FrameType
nsDocShell::GetFrameType()
{
if (mAppId != nsIScriptSecurityManager::NO_APP_ID) {
return eFrameTypeApp;
}
return mIsBrowserFrame ? eFrameTypeBrowser : eFrameTypeRegular;
}
/* [infallible] */ NS_IMETHODIMP
nsDocShell::GetIsBrowserElement(bool* aIsBrowser)
{
*aIsBrowser = (GetFrameType() == eFrameTypeBrowser);
return NS_OK;
}
/* [infallible] */ NS_IMETHODIMP
nsDocShell::GetIsApp(bool* aIsApp)
{
*aIsApp = (GetFrameType() == eFrameTypeApp);
return NS_OK;
}
/* [infallible] */ NS_IMETHODIMP
nsDocShell::GetIsContentBoundary(bool* aIsContentBoundary)
{
switch (GetFrameType()) {
case eFrameTypeRegular:
*aIsContentBoundary = false;
break;
case eFrameTypeBrowser:
case eFrameTypeApp:
*aIsContentBoundary = true;
break;
}
return NS_OK;
}
/* [infallible] */ NS_IMETHODIMP
nsDocShell::GetIsInBrowserElement(bool* aIsInBrowserElement)
{
@ -12360,29 +12376,50 @@ nsDocShell::GetIsInBrowserElement(bool* aIsInBrowserElement)
}
/* [infallible] */ NS_IMETHODIMP
nsDocShell::GetIsInBrowserOrApp(bool* aIsInBrowserOrApp)
nsDocShell::GetIsInApp(bool* aIsInApp)
{
*aIsInApp = (GetInheritedFrameType() == eFrameTypeApp);
return NS_OK;
}
/* [infallible] */ NS_IMETHODIMP
nsDocShell::GetIsBelowContentBoundary(bool* aIsInContentBoundary)
{
switch (GetInheritedFrameType()) {
case eFrameTypeRegular:
*aIsInBrowserOrApp = false;
*aIsInContentBoundary = false;
break;
case eFrameTypeBrowser:
case eFrameTypeApp:
*aIsInBrowserOrApp = true;
*aIsInContentBoundary = true;
break;
}
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::SetAppId(uint32_t aAppId)
{
MOZ_ASSERT(mAppId == nsIScriptSecurityManager::NO_APP_ID);
MOZ_ASSERT(aAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID);
mAppId = aAppId;
return NS_OK;
}
/* [infallible] */ NS_IMETHODIMP
nsDocShell::GetAppId(uint32_t* aAppId)
{
if (mOwnOrContainingAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID) {
*aAppId = mOwnOrContainingAppId;
if (mAppId != nsIScriptSecurityManager::NO_APP_ID) {
MOZ_ASSERT(GetFrameType() == eFrameTypeApp);
*aAppId = mAppId;
return NS_OK;
}
MOZ_ASSERT(GetFrameType() != eFrameTypeApp);
nsCOMPtr<nsIDocShell> parent;
GetSameTypeParentIgnoreBrowserAndAppBoundaries(getter_AddRefs(parent));

View File

@ -664,12 +664,13 @@ protected:
bool JustStartedNetworkLoad();
enum FrameType {
eFrameTypeRegular,
eFrameTypeBrowser,
eFrameTypeApp
eFrameTypeRegular = 0x0, // 0000
eFrameTypeBrowser = 0x1, // 0001
eFrameTypeApp = 0x2 // 0010
};
FrameType GetInheritedFrameType();
FrameType GetFrameType();
// hash of session storages, keyed by domain
nsInterfaceHashtable<nsCStringHashKey, nsIDOMStorage> mStorages;
@ -806,6 +807,7 @@ protected:
bool mIsAppTab;
bool mUseGlobalHistory;
bool mInPrivateBrowsing;
bool mIsBrowserFrame;
// This boolean is set to true right before we fire pagehide and generally
// unset when we embed a new content viewer. While it's true no navigation
@ -842,18 +844,7 @@ protected:
nsRefPtr<nsDOMNavigationTiming> mTiming;
// Are we a regular frame, a browser frame, or an app frame?
FrameType mFrameType;
// We only expect mOwnOrContainingAppId to be something other than
// UNKNOWN_APP_ID if mFrameType != eFrameTypeRegular. For vanilla iframes
// inside an app, we'll retrieve the containing app-id by walking up the
// docshell hierarchy.
//
// (This needs to be the docshell's own /or containing/ app id because the
// containing app frame might be in another process, in which case we won't
// find it by walking up the docshell hierarchy.)
uint32_t mOwnOrContainingAppId;
uint32_t mAppId;
private:
nsCOMPtr<nsIAtom> mForcedCharset;

View File

@ -39,7 +39,7 @@ interface nsIWebBrowserPrint;
interface nsIVariant;
interface nsIPrivacyTransitionObserver;
[scriptable, builtinclass, uuid(318CE516-3F7A-41F6-8F3D-3661650F7A46)]
[scriptable, builtinclass, uuid(0132C0BE-ACB5-4D61-9B19-01C005E030DA)]
interface nsIDocShell : nsISupports
{
/**
@ -579,88 +579,72 @@ interface nsIDocShell : nsISupports
void addWeakPrivacyTransitionObserver(in nsIPrivacyTransitionObserver obs);
/**
* Returns true if this docshell corresponds to an <iframe mozbrowser>.
* (<iframe mozapp mozbrowser> is not considered a browser.)
* Mark the docshell as a browser frame.
* This should be used for <iframe mozbrowser> but not for <iframe mozapp>.
*
* This method should not be called more than once.
*/
void setIsBrowserElement();
/**
* Returns true iff the docshell is marked as a browser frame.
*/
[infallible] readonly attribute boolean isBrowserElement;
/**
* Returns true iff the docshell corresponds to an <iframe mozapp>.
* Returns true iif the docshell is marked as an app frame.
*/
[infallible] readonly attribute boolean isApp;
/**
* Returns isBrowserElement || isApp.
* Returns true iif the docshell is marked as a type that behaves like a
* content boundary.
*/
[infallible] readonly attribute boolean isBrowserOrApp;
[infallible] readonly attribute boolean isContentBoundary;
/**
* Returns true if this docshell corresponds to an <iframe mozbrowser> or if
* the docshell is contained in an <iframe mozbrowser>. (<iframe mozapp
* mozbrowser> does not count as a browser.)
*
* Our notion here of "contained in" means: Walk up the docshell hierarchy in
* this process until we hit an <iframe mozapp> or <iframe mozbrowser> (or
* until the hierarchy ends). Return true iff the docshell we stopped on has
* isBrowserElement == true.
* Returns true iif the docshell is inside a browser element.
*/
[infallible] readonly attribute boolean isInBrowserElement;
/**
* Returns true if this docshell corresponds to an <iframe mozbrowser> or
* <iframe mozap>, or if this docshell is contained in an <iframe mozbrowser>
* or <iframe mozapp>.
* Returns true iif the docshell is inside an application. However, it will
* return false if the docshell is inside a browser element that is inside
* an application.
*
* To compute this value, we walk up the docshell hierarchy. If we encounter
* a docshell with isBrowserElement or isApp before we hit the end of the
* hierarchy, we return true. Otherwise, we return false.
* Note: Do not use this method for permissions checks! An app may contain
* an <iframe> pointing at arbitrary web code. This iframe's docshell will
* have isInApp() == true, but the iframe's content is not "app code", and
* so should not be granted more trust than vanilla web content.
*
* (For example, suppose when web content calls API method X, we show a
* permission prompt, but when "app code" calls method X, we don't. In this
* case, it would be /incorrect/ to show the permission prompt if
* !isInApp().)
*
* If you're doing a security check, use the content's principal instead of
* this method.
*/
[infallible] readonly attribute boolean isInBrowserOrApp;
/**
* Indicate that this docshell corresponds to an app with the given app id.
*
* You may pass NO_APP_ID or UNKNOWN_APP_ID for containingAppId. If you
* pass NO_APP_ID, then this docshell will return NO_APP_ID for appId. If
* you pass UNKNOWN_APP_ID, then this docshell will search its hiearchy for
* an app frame and use that frame's appId.
*
* You can call this method more than once, but there's no guarantee that
* other components will update their view of the world if you change a
* docshell's app id, so tread lightly.
*
* If you call this method after calling setIsBrowserInsideApp, this
* docshell will forget the fact that it was a browser.
*/
void setIsApp(in unsigned long ownAppId);
/**
* Indicate that this docshell corresponds to a browser inside an app with
* the given ID. As with setIsApp, you may pass NO_APP_ID or
* UNKNOWN_APP_ID.
*
* As with setIsApp, you may call this more than once, but it's kind of a
* hack, so be careful.
*/
void setIsBrowserInsideApp(in unsigned long containingAppId);
[infallible] readonly attribute boolean isInApp;
/**
* Returns the id of the app associated with this docshell. If this docshell
* is an <iframe mozbrowser> inside an <iframe mozapp>, we return the app's
* appId.
*
* We compute this value by walking up the docshell hierarchy until we find a
* docshell on which setIsApp(x) or setIsBrowserInsideApp(x) was called
* (ignoring those docshells where x == UNKNOWN_APP_ID). We return the app
* id x.
*
* If we don't find a docshell with an associated app id in our hierarchy, we
* return NO_APP_ID. We never return UNKNOWN_APP_ID.
*
* Notice that a docshell may have an associated app even if it returns true
* for isBrowserElement!
* Returns if the docshell has a docshell that behaves as a content boundary
* in his parent hierarchy.
*/
[infallible] readonly attribute unsigned long appId;
[infallible] readonly attribute boolean isBelowContentBoundary;
/**
* Set the app id this docshell is associated with. The id has to be a valid
* app id. If the docshell isn't associated with any app, the value should be
* nsIScriptSecurityManager::NO_APP_ID. However, this is the default value if
* nothing is et.
*
* This method is [noscript] to reduce the scope. It should be used at very
* specific moments.
*
* Calling setAppId() will mark the frame as an app frame.
*/
[noscript] void setAppId(in unsigned long appId);
/**
* Like nsIDocShellTreeItem::GetSameTypeParent, except this ignores <iframe

View File

@ -3008,7 +3008,7 @@ nsGlobalWindow::GetScriptableParent(nsIDOMWindow** aParent)
return NS_OK;
}
if (mDocShell->GetIsBrowserOrApp()) {
if (mDocShell->GetIsContentBoundary()) {
nsCOMPtr<nsIDOMWindow> parent = static_cast<nsIDOMWindow*>(this);
parent.swap(*aParent);
return NS_OK;
@ -3113,9 +3113,9 @@ nsGlobalWindow::GetContent(nsIDOMWindow** aContent)
FORWARD_TO_OUTER(GetContent, (aContent), NS_ERROR_NOT_INITIALIZED);
*aContent = nullptr;
// If we're contained in <iframe mozbrowser> or <iframe mozapp>, then
// GetContent is the same as window.top.
if (mDocShell && mDocShell->GetIsInBrowserOrApp()) {
// If we're contained in <iframe mozbrowser>, then GetContent is the same as
// window.top.
if (mDocShell && mDocShell->GetIsBelowContentBoundary()) {
return GetScriptableTop(aContent);
}
@ -6561,7 +6561,7 @@ nsGlobalWindow::Close()
FORWARD_TO_OUTER(Close, (), NS_ERROR_NOT_INITIALIZED);
if (!mDocShell || IsInModalState() ||
(IsFrame() && !mDocShell->GetIsBrowserOrApp())) {
(IsFrame() && !mDocShell->GetIsContentBoundary())) {
// window.close() is called on a frame in a frameset, on a window
// that's already closed, or on a window for which there's
// currently a modal dialog open. Ignore such calls.
@ -7080,9 +7080,8 @@ nsGlobalWindow::CacheXBLPrototypeHandler(nsXBLPrototypeHandler* aKey,
* nsIGlobalWindow::frameElement.
*
* In contrast to GetRealFrameElement, GetScriptableFrameElement says that the
* window contained by an <iframe mozbrowser> or <iframe mozapp> has no frame
* element (effectively treating a mozbrowser the same as a content/chrome
* boundary).
* window contained by an <iframe mozbrowser> has no frame element
* (effectively treating a mozbrowser the same as a content/chrome boundary).
*/
NS_IMETHODIMP
nsGlobalWindow::GetScriptableFrameElement(nsIDOMElement** aFrameElement)
@ -7090,7 +7089,7 @@ nsGlobalWindow::GetScriptableFrameElement(nsIDOMElement** aFrameElement)
FORWARD_TO_OUTER(GetScriptableFrameElement, (aFrameElement), NS_ERROR_NOT_INITIALIZED);
*aFrameElement = NULL;
if (!mDocShell || mDocShell->GetIsBrowserOrApp()) {
if (!mDocShell || mDocShell->GetIsContentBoundary()) {
return NS_OK;
}

View File

@ -9,7 +9,7 @@
interface nsITabParent;
[scriptable, builtinclass, uuid(929AED00-3E15-49B7-8CA2-75003715B7E7)]
[scriptable, uuid(6f043e42-02c9-4e8f-8f8d-1b83c6102827)]
interface nsIMozBrowserFrame : nsIDOMMozBrowserFrame
{
/**
@ -19,7 +19,7 @@ interface nsIMozBrowserFrame : nsIDOMMozBrowserFrame
* nsIDOMMozBrowserFrame::mozbrowser attribute must be true, and the frame
* may have to pass various security checks.
*/
[infallible] readonly attribute boolean reallyIsBrowserOrApp;
readonly attribute boolean reallyIsBrowser;
/**
* Gets whether this frame really is an app frame.
@ -28,13 +28,11 @@ interface nsIMozBrowserFrame : nsIDOMMozBrowserFrame
* frame (this requirement will go away eventually), and the frame's mozapp
* attribute must point to the manifest of a valid app.
*/
[infallible] readonly attribute boolean reallyIsApp;
readonly attribute boolean reallyIsApp;
/**
* Gets this frame's app manifest URL, if the frame really is an app frame.
* Otherwise, returns the empty string.
*
* This method is guaranteed not to fail.
*/
readonly attribute AString appManifestURL;

View File

@ -27,7 +27,7 @@ AssertAppProcessPermission(PBrowserParent* aActor, const char* aPermission)
}
TabParent* tab = static_cast<TabParent*>(aActor);
nsCOMPtr<mozIApplication> app = tab->GetOwnOrContainingApp();
nsCOMPtr<mozIApplication> app = tab->GetApp();
bool hasPermission = false;
// isBrowser frames inherit their app descriptor to identify their

View File

@ -487,8 +487,7 @@ static void FirstIdle(void)
PBrowserChild*
ContentChild::AllocPBrowser(const uint32_t& aChromeFlags,
const AppToken& aOwnOrContainingAppToken,
const bool& aIsBrowserElement)
const bool& aIsBrowserElement, const AppId& aApp)
{
static bool firstIdleTaskPosted = false;
if (!firstIdleTaskPosted) {
@ -496,11 +495,8 @@ ContentChild::AllocPBrowser(const uint32_t& aChromeFlags,
firstIdleTaskPosted = true;
}
nsRefPtr<TabChild> child = TabChild::Create(
aChromeFlags,
aOwnOrContainingAppToken.get_uint32_t(),
aIsBrowserElement);
nsRefPtr<TabChild> child =
TabChild::Create(aChromeFlags, aIsBrowserElement, aApp.get_uint32_t());
// The ref here is released below.
return child.forget().get();
}

View File

@ -79,8 +79,8 @@ public:
base::ProcessId aOtherProcess) MOZ_OVERRIDE;
virtual PBrowserChild* AllocPBrowser(const uint32_t& aChromeFlags,
const AppToken& aOwnOrContainingAppToken,
const bool& aIsBrowserElement);
const bool& aIsBrowserElement,
const AppId& aAppId);
virtual bool DeallocPBrowser(PBrowserChild*);
virtual PDeviceStorageRequestChild* AllocPDeviceStorageRequest(const DeviceStorageParams&);

View File

@ -54,6 +54,7 @@
#include "nsFrameMessageManager.h"
#include "nsHashPropertyBag.h"
#include "nsIAlertsService.h"
#include "nsIAppsService.h"
#include "nsIClipboard.h"
#include "nsIConsoleService.h"
#include "nsIDOMApplicationRegistry.h"
@ -317,35 +318,27 @@ AppNeedsInheritedOSPrivileges(mozIApplication* aApp)
}
/*static*/ TabParent*
ContentParent::CreateBrowserOrApp(mozIApplication* aOwnOrContainingApp,
bool aIsBrowserElement)
ContentParent::CreateBrowser(mozIApplication* aApp, bool aIsBrowserElement)
{
uint32_t ownOrContainingAppId = nsIScriptSecurityManager::NO_APP_ID;
if (aOwnOrContainingApp) {
NS_ENSURE_SUCCESS(aOwnOrContainingApp->GetLocalId(&ownOrContainingAppId),
nullptr);
}
// We currently don't set the <app> ancestor for <browser> content
// correctly. This assertion is to notify the person who fixes
// this code that they need to reevaluate places here where we may
// make bad assumptions based on that bug.
MOZ_ASSERT(!aApp || !aIsBrowserElement);
if (aIsBrowserElement || !aOwnOrContainingApp) {
if (!aApp) {
if (ContentParent* cp = GetNewOrUsed(aIsBrowserElement)) {
nsRefPtr<TabParent> tp(new TabParent(aOwnOrContainingApp, aIsBrowserElement));
nsRefPtr<TabParent> tp(new TabParent(aApp, aIsBrowserElement));
return static_cast<TabParent*>(
cp->SendPBrowserConstructor(
// DeallocPBrowserParent() releases the ref we take here
tp.forget().get(),
/*chromeFlags*/0,
ownOrContainingAppId, aIsBrowserElement));
aIsBrowserElement, nsIScriptSecurityManager::NO_APP_ID));
}
return nullptr;
}
// If we got here, we have an app and we're not a browser element. In this
// case, we assume the app is our own app, not a containing one. That is,
// if you're a remote iframe inside an app, you must either be a browser or
// a new app; you can't be a non-browser non-app iframe.
nsCOMPtr<mozIApplication> ownApp = aOwnOrContainingApp;
uint32_t ownAppId = ownOrContainingAppId;
if (!gAppContentParents) {
gAppContentParents =
new nsDataHashtable<nsStringHashKey, ContentParent*>();
@ -354,15 +347,29 @@ ContentParent::CreateBrowserOrApp(mozIApplication* aOwnOrContainingApp,
// Each app gets its own ContentParent instance.
nsAutoString manifestURL;
if (NS_FAILED(ownApp->GetManifestURL(manifestURL))) {
if (NS_FAILED(aApp->GetManifestURL(manifestURL))) {
NS_ERROR("Failed to get manifest URL");
return nullptr;
}
nsCOMPtr<nsIAppsService> appsService = do_GetService(APPS_SERVICE_CONTRACTID);
if (!appsService) {
NS_ERROR("Failed to get apps service");
return nullptr;
}
// Send the local app ID to the new TabChild so it knows what app
// it is.
uint32_t appId;
if (NS_FAILED(appsService->GetAppLocalIdByManifestURL(manifestURL, &appId))) {
NS_ERROR("Failed to get local app ID");
return nullptr;
}
nsRefPtr<ContentParent> p = gAppContentParents->Get(manifestURL);
if (!p) {
if (AppNeedsInheritedOSPrivileges(ownApp)) {
p = new ContentParent(manifestURL, /* isBrowserElement = */ false,
if (AppNeedsInheritedOSPrivileges(aApp)) {
p = new ContentParent(manifestURL, aIsBrowserElement,
base::PRIVILEGES_INHERIT);
p->Init();
} else {
@ -371,7 +378,7 @@ ContentParent::CreateBrowserOrApp(mozIApplication* aOwnOrContainingApp,
p->SetManifestFromPreallocated(manifestURL);
} else {
NS_WARNING("Unable to use pre-allocated app process");
p = new ContentParent(manifestURL, /* isBrowserElement = */ false,
p = new ContentParent(manifestURL, aIsBrowserElement,
base::PRIVILEGES_DEFAULT);
p->Init();
}
@ -379,13 +386,12 @@ ContentParent::CreateBrowserOrApp(mozIApplication* aOwnOrContainingApp,
gAppContentParents->Put(manifestURL, p);
}
nsRefPtr<TabParent> tp(new TabParent(ownApp, /* isBrowserElement = */ false));
nsRefPtr<TabParent> tp(new TabParent(aApp, aIsBrowserElement));
return static_cast<TabParent*>(
// DeallocPBrowserParent() releases the ref we take here
p->SendPBrowserConstructor(tp.forget().get(),
/* chromeFlags = */ 0,
ownAppId,
/* isBrowserElement = */ false));
/*chromeFlags*/0,
aIsBrowserElement, appId));
}
static PLDHashOperator
@ -1144,20 +1150,18 @@ ContentParent::RecvGetProcessAttributes(uint64_t* aId, bool* aStartBackground,
PBrowserParent*
ContentParent::AllocPBrowser(const uint32_t& aChromeFlags,
const AppToken& aOwnOrContainingAppToken,
const bool& aIsBrowserElement)
const bool& aIsBrowserElement, const AppId& aApp)
{
// We only use this Alloc() method when the content processes asks
// us to open a window. In that case, we're expecting to see the
// opening PBrowser as its app descriptor, and we can trust the data
// associated with that PBrowser since it's fully owned by this
// process.
if (AppToken::TPBrowserParent != aOwnOrContainingAppToken.type()) {
if (AppId::TPBrowserParent != aApp.type()) {
NS_ERROR("Content process attempting to forge app ID");
return nullptr;
}
TabParent* opener = static_cast<TabParent*>(
aOwnOrContainingAppToken.get_PBrowserParent());
TabParent* opener = static_cast<TabParent*>(aApp.get_PBrowserParent());
// Popup windows of isBrowser frames are isBrowser if the parent
// isBrowser. Allocating a !isBrowser frame with same app ID
@ -1167,9 +1171,8 @@ ContentParent::AllocPBrowser(const uint32_t& aChromeFlags,
return nullptr;
}
nsCOMPtr<mozIApplication> app = opener ? opener->GetOwnOrContainingApp() : nullptr;
TabParent* parent = new TabParent(app, aIsBrowserElement);
TabParent* parent = new TabParent(opener ? opener->GetApp() : nullptr,
aIsBrowserElement);
// We release this ref in DeallocPBrowser()
NS_ADDREF(parent);
return parent;

View File

@ -73,15 +73,15 @@ public:
static ContentParent* GetNewOrUsed(bool aForBrowserElement = false);
/**
* Get or create a content process for the given (app, is-browser)
* descriptor.
* Get or create a content process for the given app descriptor,
* which may be null. This function will assign processes to app
* or non-app browsers by internal heuristics.
*
* The app here is inherited -- that is, <iframe mozbrowser> inside <iframe
* mozapp> must pass a non-null app. aIsBrowserElement should be true
* only for <iframe mozbrowser> frames that are not app frames.
* Currently apps are given their own process, and browser tabs
* share processes.
*/
static TabParent* CreateBrowserOrApp(mozIApplication* aOwnOrContainingApp,
bool aIsBrowserElement);
static TabParent* CreateBrowser(mozIApplication* aApp,
bool aIsBrowserFrame);
static void GetAll(nsTArray<ContentParent*>& aArray);
@ -188,8 +188,8 @@ private:
bool* aIsForBrowser) MOZ_OVERRIDE;
virtual PBrowserParent* AllocPBrowser(const uint32_t& aChromeFlags,
const AppToken& aOwnOrContainingAppToken,
const bool& aIsBrowserElement);
const bool& aIsBrowserElement,
const AppId& aApp);
virtual bool DeallocPBrowser(PBrowserParent* frame);
virtual PDeviceStorageRequestParent* AllocPDeviceStorageRequest(const DeviceStorageParams&);

View File

@ -135,9 +135,7 @@ union BlobConstructorParams
MysteryBlobConstructorParams;
};
// This struct identifies an app, by providing either a uint32_t (an appID) or a
// pointer to a PBrowser (whose appID we use to identify the app).
union AppToken {
union AppId {
uint32_t;
nullable PBrowser;
};
@ -187,13 +185,13 @@ both:
// TabChild::BrowserFrameProvideWindow, and the parent creates the
// PBrowser as part of ContentParent::CreateTab.
//
// When the parent constructs a PBrowser, the app token handed to the child
// side is trusted. In that case, |ownOrContainingApp| is a uint32_t.
// However, when the child side constructs a PBrowser, for window.open(),
// the parent must validate the app ID used on the parent side. To do so,
// the child process must pass a valid PBrowser as its |ownOrContainingApp|.
async PBrowser(uint32_t chromeFlags, AppToken ownOrContainingApp,
bool isBrowserFrame);
// When the parent constructs a PBrowser, the app ID handed to the
// child side is trusted. In that case, |appId| is uint32_t.
// However, when the child side constructs a PBrowser, for
// window.open(), the parent must validate the app ID used on the
// parent side. To do so, the child process must pass a valid
// PBrowser as its |AppId|.
async PBrowser(uint32_t chromeFlags, bool isBrowserElement, AppId appId);
async PBlob(BlobConstructorParams params);

View File

@ -134,32 +134,30 @@ TabChild::PreloadSlowThings()
/*static*/ already_AddRefed<TabChild>
TabChild::Create(uint32_t aChromeFlags,
uint32_t aOwnOrContainingAppId,
bool aIsBrowserElement)
bool aIsBrowserElement, uint32_t aAppId)
{
if (sPreallocatedTab &&
sPreallocatedTab->mChromeFlags == aChromeFlags &&
(aIsBrowserElement ||
aOwnOrContainingAppId != nsIScriptSecurityManager::NO_APP_ID)) {
(aIsBrowserElement ||
aAppId != nsIScriptSecurityManager::NO_APP_ID)) {
nsRefPtr<TabChild> child = sPreallocatedTab.get();
sPreallocatedTab = nullptr;
MOZ_ASSERT(!child->mTriedBrowserInit);
child->SetAppBrowserConfig(aOwnOrContainingAppId, aIsBrowserElement);
child->SetAppBrowserConfig(aIsBrowserElement, aAppId);
return child.forget();
}
nsRefPtr<TabChild> iframe =
new TabChild(aChromeFlags, aOwnOrContainingAppId, aIsBrowserElement);
nsRefPtr<TabChild> iframe = new TabChild(aChromeFlags, aIsBrowserElement,
aAppId);
return NS_SUCCEEDED(iframe->Init()) ? iframe.forget() : nullptr;
}
TabChild::TabChild(uint32_t aChromeFlags,
uint32_t aOwnOrContainingAppId,
bool aIsBrowserElement)
TabChild::TabChild(uint32_t aChromeFlags, bool aIsBrowserElement,
uint32_t aAppId)
: mRemoteFrame(nullptr)
, mTabChildGlobal(nullptr)
, mChromeFlags(aChromeFlags)
@ -167,9 +165,9 @@ TabChild::TabChild(uint32_t aChromeFlags,
, mInnerSize(0, 0)
, mOldViewportWidth(0.0f)
, mLastBackgroundColor(NS_RGB(255, 255, 255))
, mOwnOrContainingAppId(aOwnOrContainingAppId)
, mIsBrowserElement(aIsBrowserElement)
, mAppId(aAppId)
, mDidFakeShow(false)
, mIsBrowserElement(aIsBrowserElement)
, mNotified(false)
, mContentDocumentIsDisplayed(false)
, mTriedBrowserInit(false)
@ -532,7 +530,7 @@ TabChild::Init()
baseWindow->InitWindow(0, mWidget, 0, 0, 0, 0);
baseWindow->Create();
SetAppBrowserConfig(mOwnOrContainingAppId, mIsBrowserElement);
SetAppBrowserConfig(mIsBrowserElement, mAppId);
// IPC uses a WebBrowser object for which DNS prefetching is turned off
// by default. But here we really want it, so enable it explicitly
@ -556,27 +554,18 @@ TabChild::Init()
}
void
TabChild::SetAppBrowserConfig(uint32_t aOwnOrContainingAppId, bool aIsBrowserElement)
TabChild::SetAppBrowserConfig(bool aIsBrowserElement, uint32_t aAppId)
{
mOwnOrContainingAppId = aOwnOrContainingAppId;
mIsBrowserElement = aIsBrowserElement;
mAppId = aAppId;
nsCOMPtr<nsIDocShell> docShell = do_GetInterface(mWebNav);
MOZ_ASSERT(docShell);
// We assume here that if !aIsBrowserElement and aOwnOrContainingAppId is
// not NO_APP_ID or UNKNOWN_APP_ID then the app id is our own app id, and
// not the id of a containing app. That is, a TabChild that's contained
// inside an app must itself be an app or a browser. Put another way, you
// can't have a remote non-app non-browser iframe contained inside an app.
if (docShell) {
// nsDocShell will do the right thing if we pass NO_APP_ID or
// UNKNOWN_APP_ID for aOwnOrContainingAppId.
if (aIsBrowserElement) {
docShell->SetIsBrowserInsideApp(aOwnOrContainingAppId);
} else {
docShell->SetIsApp(aOwnOrContainingAppId);
docShell->SetAppId(mAppId);
if (mIsBrowserElement) {
docShell->SetIsBrowserElement();
}
}
}
@ -800,11 +789,11 @@ TabChild::ProvideWindow(nsIDOMWindow* aParent, uint32_t aChromeFlags,
{
*aReturn = nullptr;
// If aParent is inside an <iframe mozbrowser> or <iframe mozapp> and this
// isn't a request to open a modal-type window, we're going to create a new
// <iframe mozbrowser/mozapp> and return its window here.
// If aParent is inside an <iframe mozbrowser> and this isn't a request to
// open a modal-type window, we're going to create a new <iframe mozbrowser>
// and return its window here.
nsCOMPtr<nsIDocShell> docshell = do_GetInterface(aParent);
if (docshell && docshell->GetIsInBrowserOrApp() &&
if (docshell && docshell->GetIsBelowContentBoundary() &&
!(aChromeFlags & (nsIWebBrowserChrome::CHROME_MODAL |
nsIWebBrowserChrome::CHROME_OPENAS_DIALOG |
nsIWebBrowserChrome::CHROME_OPENAS_CHROME))) {
@ -840,15 +829,15 @@ TabChild::BrowserFrameProvideWindow(nsIDOMWindow* aOpener,
*aReturn = nullptr;
uint32_t chromeFlags = 0;
nsRefPtr<TabChild> newChild =
new TabChild(chromeFlags, mOwnOrContainingAppId, mIsBrowserElement);
nsRefPtr<TabChild> newChild = new TabChild(chromeFlags,
mIsBrowserElement, mAppId);
if (!NS_SUCCEEDED(newChild->Init())) {
return NS_ERROR_ABORT;
}
unused << Manager()->SendPBrowserConstructor(
// We release this ref in DeallocPBrowserChild
nsRefPtr<TabChild>(newChild).forget().get(),
chromeFlags, this, mIsBrowserElement);
chromeFlags, mIsBrowserElement, this);
nsAutoCString spec;
if (aURI) {
aURI->GetSpec(spec);
@ -1009,10 +998,9 @@ TabChild::~TabChild()
void
TabChild::SetProcessNameToAppName()
{
if (IsBrowserOrApp()) {
if (mIsBrowserElement || (mAppId == nsIScriptSecurityManager::NO_APP_ID)) {
return;
}
nsCOMPtr<nsIAppsService> appsService =
do_GetService(APPS_SERVICE_CONTRACTID);
if (!appsService) {
@ -1021,7 +1009,7 @@ TabChild::SetProcessNameToAppName()
}
nsresult rv;
nsCOMPtr<mozIDOMApplication> domApp;
rv = appsService->GetAppByLocalId(mOwnOrContainingAppId, getter_AddRefs(domApp));
rv = appsService->GetAppByLocalId(mAppId, getter_AddRefs(domApp));
if (NS_FAILED(rv) || !domApp) {
NS_WARNING("GetAppByLocalId failed");
return;
@ -1041,19 +1029,12 @@ TabChild::SetProcessNameToAppName()
ContentChild::GetSingleton()->SetProcessName(appName);
}
bool
TabChild::IsBrowserOrApp()
{
return mIsBrowserElement ||
mOwnOrContainingAppId != nsIScriptSecurityManager::NO_APP_ID;
}
bool
TabChild::IsRootContentDocument()
{
if (IsBrowserOrApp()) {
// The child side of a browser or app element always behaves like a root
// content document.
if (mIsBrowserElement || mAppId == nsIScriptSecurityManager::NO_APP_ID) {
// We're the child side of a browser element. This always
// behaves like a root content document.
return true;
}
@ -1706,7 +1687,7 @@ TabChild::InitTabChildGlobal(FrameScriptLoading aScriptLoading)
mTriedBrowserInit = true;
// Initialize the child side of the browser element machinery,
// if appropriate.
if (IsBrowserOrApp()) {
if (mIsBrowserElement || mAppId != nsIScriptSecurityManager::NO_APP_ID) {
RecvLoadRemoteScript(BROWSER_ELEMENT_CHILD_SCRIPT);
}
}

View File

@ -164,15 +164,11 @@ public:
/** Return a TabChild with the given attributes. */
static already_AddRefed<TabChild>
Create(uint32_t aChromeFlags, uint32_t aOwnOrContainingAppId, bool aIsBrowserElement);
Create(uint32_t aChromeFlags, bool aIsBrowserElement, uint32_t aAppId);
virtual ~TabChild();
uint32_t GetOwnOrContainingAppId() { return mOwnOrContainingAppId; }
// Does this TabChild correspond to a browser or app frame?
// Equivalent to mIsBrowserElement || GetOwnOrContainingAppId() != NO_APP_ID.
bool IsBrowserOrApp();
uint32_t GetAppId() { return mAppId; }
bool IsRootContentDocument();
@ -315,16 +311,15 @@ private:
/**
* Create a new TabChild object.
*
* |aOwnOrContainingAppId| is the app-id of our frame or of the closest app
* frame in the hierarchy which contains us.
*
* |aIsBrowserElement| indicates whether we're a browser (but not an app).
* |aIsBrowserElement| indicates whether the tab is inside an <iframe mozbrowser>.
* |aAppId| is the app id of the app containing this tab. If the tab isn't
* contained in an app, aAppId will be nsIScriptSecurityManager::NO_APP_ID.
*/
TabChild(uint32_t aChromeFlags, uint32_t aOwnOrContainingAppId, bool aIsBrowserElement);
TabChild(uint32_t aChromeFlags, bool aIsBrowserElement, uint32_t aAppId);
nsresult Init();
void SetAppBrowserConfig(uint32_t aOwnOrContainingAppId, bool aIsBrowserElement);
void SetAppBrowserConfig(bool aIsBrowserElement, uint32_t aAppId);
bool UseDirectCompositor();
@ -388,9 +383,9 @@ private:
float mOldViewportWidth;
nscolor mLastBackgroundColor;
ScrollingBehavior mScrolling;
uint32_t mOwnOrContainingAppId;
bool mIsBrowserElement;
uint32_t mAppId;
bool mDidFakeShow;
bool mIsBrowserElement;
bool mNotified;
bool mContentDocumentIsDisplayed;
bool mTriedBrowserInit;

View File

@ -73,10 +73,9 @@ TabParent *TabParent::mIMETabParent = nullptr;
NS_IMPL_ISUPPORTS3(TabParent, nsITabParent, nsIAuthPromptProvider, nsISecureBrowserUI)
TabParent::TabParent(mozIApplication* aOwnOrContainingApp, bool aIsBrowserElement)
TabParent::TabParent(mozIApplication* aApp, bool aIsBrowserElement)
: mFrameElement(NULL)
, mOwnOrContainingApp(aOwnOrContainingApp)
, mIsBrowserElement(aIsBrowserElement)
, mApp(aApp)
, mIMESelectionAnchor(0)
, mIMESelectionFocus(0)
, mIMEComposing(false)
@ -86,6 +85,7 @@ TabParent::TabParent(mozIApplication* aOwnOrContainingApp, bool aIsBrowserElemen
, mEventCaptureDepth(0)
, mDimensions(0, 0)
, mDPI(0)
, mIsBrowserElement(aIsBrowserElement)
, mShown(false)
{
}
@ -188,7 +188,7 @@ TabParent::AnswerCreateWindow(PBrowserParent** retval)
}
// Only non-app, non-browser processes may call CreateWindow.
if (IsBrowserOrApp()) {
if (GetApp() || IsBrowserElement()) {
return false;
}
@ -892,9 +892,9 @@ TabParent::RecvPIndexedDBConstructor(PIndexedDBParent* aActor,
// XXXbent Need to make sure we have a whitelist for chrome databases!
// Verify the appID in the origin first.
if (mOwnOrContainingApp && !aASCIIOrigin.EqualsLiteral("chrome")) {
if (mApp && !aASCIIOrigin.EqualsLiteral("chrome")) {
uint32_t appId;
rv = mOwnOrContainingApp->GetLocalId(&appId);
rv = mApp->GetLocalId(&appId);
NS_ENSURE_SUCCESS(rv, false);
if (!IndexedDatabaseManager::OriginMatchesApp(aASCIIOrigin, appId)) {
@ -1159,10 +1159,16 @@ TabParent::GetWidget() const
}
bool
TabParent::IsForBrowserOrApp()
TabParent::IsForMozBrowser()
{
nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(mFrameElement);
return browserFrame ? browserFrame->GetReallyIsBrowserOrApp() : false;
nsCOMPtr<nsIContent> content = do_QueryInterface(mFrameElement);
nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(content);
if (browserFrame) {
bool isBrowser = false;
browserFrame->GetReallyIsBrowser(&isBrowser);
return isBrowser;
}
return false;
}
bool
@ -1173,7 +1179,7 @@ TabParent::UseAsyncPanZoom()
Preferences::GetBool("layers.async-pan-zoom.enabled", false);
ContentParent* cp = static_cast<ContentParent*>(Manager());
return (usingOffMainThreadCompositing &&
!cp->IsForApp() && IsForBrowserOrApp() &&
!cp->IsForApp() && IsForMozBrowser() &&
asyncPanZoomEnabled);
}

View File

@ -54,7 +54,7 @@ class TabParent : public PBrowserParent
typedef mozilla::dom::ClonedMessageData ClonedMessageData;
public:
TabParent(mozIApplication* aOwnOrContainingApp, bool aIsBrowserElement);
TabParent(mozIApplication* aApp, bool aIsBrowserElement);
virtual ~TabParent();
nsIDOMElement* GetOwnerElement() { return mFrameElement; }
void SetOwnerElement(nsIDOMElement* aElement);
@ -63,9 +63,8 @@ public:
mBrowserDOMWindow = aBrowserDOMWindow;
}
mozIApplication* GetOwnOrContainingApp() { return mOwnOrContainingApp; }
mozIApplication* GetApp() { return mApp; }
bool IsBrowserElement() { return mIsBrowserElement; }
bool IsBrowserOrApp() { return GetOwnOrContainingApp() || IsBrowserElement(); }
/**
* Return the TabParent that has decided it wants to capture an
@ -262,9 +261,7 @@ protected:
uint64_t* aLayersId) MOZ_OVERRIDE;
virtual bool DeallocPRenderFrame(PRenderFrameParent* aFrame) MOZ_OVERRIDE;
nsCOMPtr<mozIApplication> mOwnOrContainingApp;
bool mIsBrowserElement;
nsCOMPtr<mozIApplication> mApp;
// IME
static TabParent *mIMETabParent;
nsString mIMECacheText;
@ -283,6 +280,7 @@ protected:
nsIntSize mDimensions;
float mDPI;
bool mIsBrowserElement;
bool mShown;
private:
@ -290,9 +288,9 @@ private:
already_AddRefed<nsIWidget> GetWidget() const;
layout::RenderFrameParent* GetRenderFrame();
void TryCacheDPI();
// Return true iff this TabParent was created for a mozbrowser or mozapp
// Return true iff this TabParent was created for a mozbrowser
// frame.
bool IsForBrowserOrApp();
bool IsForMozBrowser();
// When true, we create a pan/zoom controller for our frame and
// notify it of input events targeting us.
bool UseAsyncPanZoom();

View File

@ -1633,8 +1633,12 @@ uint32_t nsWindowWatcher::CalculateChromeFlags(nsIDOMWindow *aParent,
// Disable CHROME_OPENAS_DIALOG if the window is inside <iframe mozbrowser>.
// It's up to the embedder to interpret what dialog=1 means.
nsCOMPtr<nsIDocShell> docshell = do_GetInterface(aParent);
if (docshell && docshell->GetIsInBrowserOrApp()) {
chromeFlags &= ~nsIWebBrowserChrome::CHROME_OPENAS_DIALOG;
if (docshell) {
bool belowContentBoundary = false;
docshell->GetIsBelowContentBoundary(&belowContentBoundary);
if (belowContentBoundary) {
chromeFlags &= ~nsIWebBrowserChrome::CHROME_OPENAS_DIALOG;
}
}
return chromeFlags;

View File

@ -851,7 +851,7 @@ nsContentTreeOwner::ProvideWindow(nsIDOMWindow* aParent,
// open a modal-type window, we're going to create a new <iframe mozbrowser>
// and return its window here.
nsCOMPtr<nsIDocShell> docshell = do_GetInterface(aParent);
if (docshell && docshell->GetIsInBrowserOrApp() &&
if (docshell && docshell->GetIsBelowContentBoundary() &&
!(aChromeFlags & (nsIWebBrowserChrome::CHROME_MODAL |
nsIWebBrowserChrome::CHROME_OPENAS_DIALOG |
nsIWebBrowserChrome::CHROME_OPENAS_CHROME))) {