Bug 802366 - The main event: Let a browser process inherit its app's id. r=bz,cjones

The main bug fixed here is that in half of our interfaces, we use "is browser frame/element" to mean "browser or app", and in the other half, we use it to mean "is browser not app".

There's a related, functional bug also fixed here, which is that a browser process doesn't inherit its parent's app-id.  This causes problems e.g. for IndexedDB: If a browser inside an app uses IndexedDB, the DB should have the app's app-id.

I also modified Tab{Parent,Child} and nsFrameLoader to call "app" "ownOrContainingApp", to emphasize that we might have inherited the app from a parent process.  I left nsIDocShell::appId alone, because changing that would have necessitated changing nsILoadGroup and therefore a /lot/ of users in Necko; it's also not clear it would have clarified anything in those cases.
This commit is contained in:
Justin Lebar
2012-11-10 10:32:37 -08:00
parent 039984213c
commit f4dad2e81e
29 changed files with 1028 additions and 472 deletions

View File

@@ -730,6 +730,7 @@ nsDocShell::nsDocShell():
mCharsetReloadState(eCharsetReloadInit),
mChildOffset(0),
mBusyFlags(BUSY_FLAGS_NONE),
mFrameType(eFrameTypeRegular),
mAppType(nsIDocShell::APP_TYPE_UNKNOWN),
mLoadType(0),
mMarginWidth(-1),
@@ -767,7 +768,7 @@ nsDocShell::nsDocShell():
#ifdef DEBUG
mInEnsureScriptEnv(false),
#endif
mAppId(nsIScriptSecurityManager::NO_APP_ID),
mOwnOrContainingAppId(nsIScriptSecurityManager::UNKNOWN_APP_ID),
mParentCharsetSource(0)
{
mHistoryID = ++gDocshellIDCounter;
@@ -2150,7 +2151,7 @@ nsDocShell::GetFullscreenAllowed(bool* aFullscreenAllowed)
{
NS_ENSURE_ARG_POINTER(aFullscreenAllowed);
// Content boundaries have their mFullscreenAllowed retrieved from their
// Browsers and apps have their mFullscreenAllowed retrieved from their
// corresponding iframe in their parent upon creation.
if (mFullscreenAllowed != CHECK_ATTRIBUTES) {
*aFullscreenAllowed = (mFullscreenAllowed == PARENT_ALLOWS);
@@ -2160,9 +2161,9 @@ nsDocShell::GetFullscreenAllowed(bool* aFullscreenAllowed)
// Assume false until we determine otherwise...
*aFullscreenAllowed = false;
// For non-content boundaries, check that the enclosing iframe element
// For non-browsers/apps, check that the enclosing iframe element
// has the allowfullscreen attribute set to true. If any ancestor
// iframe does not have allowfullscreen=true, then fullscreen is
// iframe does not have mozallowfullscreen=true, then fullscreen is
// prohibited.
nsCOMPtr<nsPIDOMWindow> win = do_GetInterface(GetAsSupports(this));
if (!win) {
@@ -2199,7 +2200,7 @@ nsDocShell::GetFullscreenAllowed(bool* aFullscreenAllowed)
NS_IMETHODIMP
nsDocShell::SetFullscreenAllowed(bool aFullscreenAllowed)
{
if (!nsIDocShell::GetIsContentBoundary()) {
if (!nsIDocShell::GetIsBrowserOrApp()) {
// 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
@@ -2811,7 +2812,7 @@ nsDocShell::GetSameTypeParent(nsIDocShellTreeItem ** aParent)
NS_ENSURE_ARG_POINTER(aParent);
*aParent = nullptr;
if (mIsBrowserFrame) {
if (nsIDocShell::GetIsBrowserOrApp()) {
return NS_OK;
}
@@ -2933,19 +2934,11 @@ nsDocShell::CanAccessItem(nsIDocShellTreeItem* aTargetItem,
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;
}
if (targetDS && accessingDS &&
(targetDS->GetIsInBrowserElement() !=
accessingDS->GetIsInBrowserElement() ||
targetDS->GetAppId() != accessingDS->GetAppId())) {
return false;
}
nsCOMPtr<nsIDocShellTreeItem> accessingRoot;
@@ -5229,7 +5222,7 @@ nsDocShell::SetIsActive(bool aIsActive)
continue;
}
if (!docshell->GetIsContentBoundary()) {
if (!docshell->GetIsBrowserOrApp()) {
docshell->SetIsActive(aIsActive);
}
}
@@ -12311,19 +12304,52 @@ nsDocShell::GetCanExecuteScripts(bool *aResult)
}
NS_IMETHODIMP
nsDocShell::SetIsBrowserElement()
nsDocShell::SetIsApp(uint32_t aOwnAppId)
{
if (mIsBrowserFrame) {
NS_ERROR("You should not call SetIsBrowserElement() more than once.");
return NS_OK;
mOwnOrContainingAppId = aOwnAppId;
if (aOwnAppId != nsIScriptSecurityManager::NO_APP_ID &&
aOwnAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID) {
mFrameType = eFrameTypeApp;
} else {
mFrameType = eFrameTypeRegular;
}
mIsBrowserFrame = true;
return NS_OK;
}
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
if (os) {
os->NotifyObservers(GetAsSupports(this),
"docshell-marked-as-browser-frame", NULL);
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;
}
return NS_OK;
@@ -12332,10 +12358,8 @@ nsDocShell::SetIsBrowserElement()
nsDocShell::FrameType
nsDocShell::GetInheritedFrameType()
{
FrameType type = GetFrameType();
if (type != eFrameTypeRegular) {
return type;
if (mFrameType != eFrameTypeRegular) {
return mFrameType;
}
nsCOMPtr<nsIDocShellTreeItem> parentAsItem;
@@ -12349,46 +12373,6 @@ 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)
{
@@ -12397,50 +12381,29 @@ nsDocShell::GetIsInBrowserElement(bool* aIsInBrowserElement)
}
/* [infallible] */ NS_IMETHODIMP
nsDocShell::GetIsInApp(bool* aIsInApp)
{
*aIsInApp = (GetInheritedFrameType() == eFrameTypeApp);
return NS_OK;
}
/* [infallible] */ NS_IMETHODIMP
nsDocShell::GetIsBelowContentBoundary(bool* aIsInContentBoundary)
nsDocShell::GetIsInBrowserOrApp(bool* aIsInBrowserOrApp)
{
switch (GetInheritedFrameType()) {
case eFrameTypeRegular:
*aIsInContentBoundary = false;
*aIsInBrowserOrApp = false;
break;
case eFrameTypeBrowser:
case eFrameTypeApp:
*aIsInContentBoundary = true;
*aIsInBrowserOrApp = 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 (mAppId != nsIScriptSecurityManager::NO_APP_ID) {
MOZ_ASSERT(GetFrameType() == eFrameTypeApp);
*aAppId = mAppId;
if (mOwnOrContainingAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID) {
*aAppId = mOwnOrContainingAppId;
return NS_OK;
}
MOZ_ASSERT(GetFrameType() != eFrameTypeApp);
nsCOMPtr<nsIDocShell> parent;
GetSameTypeParentIgnoreBrowserAndAppBoundaries(getter_AddRefs(parent));