Backed out 12 changesets (bug 806127, bug 802366, bug 806168) for Windows build bustage.

--HG--
rename : dom/indexedDB/test/webapp_clearBrowserData.js => dom/indexedDB/test/test_webapp_clearBrowserData.html
This commit is contained in:
Ryan VanderMeulen 2012-11-09 20:14:40 -05:00
parent 9a60759573
commit f774dcd8ba
52 changed files with 758 additions and 1493 deletions

View File

@ -21,7 +21,7 @@ interface nsIContentSecurityPolicy;
[ptr] native JSPrincipals(JSPrincipals);
[ptr] native PrincipalArray(nsTArray<nsCOMPtr<nsIPrincipal> >);
[scriptable, builtinclass, uuid(011966C0-8564-438D-B37A-08D7E1195E5A)]
[scriptable, uuid(3a283dc9-f733-4618-a36f-e2b68c280ab7)]
interface nsIPrincipal : nsISerializable
{
/**
@ -159,66 +159,78 @@ interface nsIPrincipal : nsISerializable
const short APP_STATUS_CERTIFIED = 3;
/**
* Gets the principal's app status, which indicates whether the principal
* corresponds to "app code", and if it does, how privileged that code is.
* This method returns one of the APP_STATUS constants above.
*
* Note that a principal may have
*
* appId != nsIScriptSecurityManager::NO_APP_ID &&
* appId != nsIScriptSecurityManager::UNKNOWN_APP_ID
*
* and still have appStatus == APP_STATUS_NOT_INSTALLED. That's because
* appId identifies the app that contains this principal, but a window
* might be contained in an app and not be running code that the app has
* vouched for. For example, the window might be inside an <iframe
* mozbrowser>, or the window's origin might not match the app's origin.
*
* If you're doing a check to determine "does this principal correspond to
* app code?", you must check appStatus; checking appId != NO_APP_ID is not
* sufficient.
* Shows the status of the app.
* Can be: APP_STATUS_NOT_INSTALLED, APP_STATUS_INSTALLED,
* APP_STATUS_PRIVILEGED or APP_STATUS_CERTIFIED.
*/
[infallible] readonly attribute unsigned short appStatus;
readonly attribute unsigned short appStatus;
%{C++
uint16_t GetAppStatus()
{
uint16_t appStatus;
nsresult rv = GetAppStatus(&appStatus);
if (NS_FAILED(rv)) {
return APP_STATUS_NOT_INSTALLED;
}
return appStatus;
}
%}
/**
* Gets the id of the app this principal is inside. If this principal is
* not inside an app, returns nsIScriptSecurityManager::NO_APP_ID.
*
* Note that this principal does not necessarily have the permissions of
* the app identified by appId. For example, this principal might
* correspond to an iframe whose origin differs from that of the app frame
* containing it. In this case, the iframe will have the appId of its
* containing app frame, but the iframe must not run with the app's
* permissions.
*
* Similarly, this principal might correspond to an <iframe mozbrowser>
* inside an app frame; in this case, the content inside the iframe should
* not have any of the app's permissions, even if the iframe is at the same
* origin as the app.
*
* If you're doing a security check based on appId, you must check
* appStatus as well.
* Returns the app id the principal is in, or returns
* nsIScriptSecurityManager::NO_APP_ID if this principal isn't part of an
* app.
*/
[infallible] readonly attribute unsigned long appId;
readonly attribute unsigned long appId;
%{C++
uint32_t GetAppId()
{
uint32_t appId;
mozilla::DebugOnly<nsresult> rv = GetAppId(&appId);
MOZ_ASSERT(NS_SUCCEEDED(rv));
return appId;
}
%}
/**
* Returns true iff the principal is inside a browser element. (<iframe
* mozbrowser mozapp> does not count as a browser element.)
* Returns true iif the principal is inside a browser element.
*/
[infallible] readonly attribute boolean isInBrowserElement;
readonly attribute boolean isInBrowserElement;
%{C++
bool GetIsInBrowserElement()
{
bool isInBrowserElement;
mozilla::DebugOnly<nsresult> rv = GetIsInBrowserElement(&isInBrowserElement);
MOZ_ASSERT(NS_SUCCEEDED(rv));
return isInBrowserElement;
}
%}
/**
* Returns true if this principal has an unknown appId. This shouldn't
* generally be used. We only expose it due to not providing the correct
* appId everywhere where we construct principals.
*/
[infallible] readonly attribute boolean unknownAppId;
readonly attribute boolean unknownAppId;
%{C++
bool GetUnknownAppId()
{
bool unkwnownAppId;
mozilla::DebugOnly<nsresult> rv = GetUnknownAppId(&unkwnownAppId);
MOZ_ASSERT(NS_SUCCEEDED(rv));
return unkwnownAppId;
}
%}
/**
* Returns true iff this principal is a null principal (corresponding to an
* unknown, hence assumed minimally privileged, security context).
*/
[infallible] readonly attribute boolean isNullPrincipal;
readonly attribute boolean isNullPrincipal;
};
/**

View File

@ -335,15 +335,19 @@ nsScriptSecurityManager::GetChannelPrincipal(nsIChannel* aChannel,
nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
uint32_t appId = UNKNOWN_APP_ID;
bool isInBrowserElement = false;
nsCOMPtr<nsIDocShell> docShell;
NS_QueryNotificationCallbacks(aChannel, docShell);
if (docShell) {
return GetDocShellCodebasePrincipal(uri, docShell, aPrincipal);
docShell->GetAppId(&appId);
docShell->GetIsInBrowserElement(&isInBrowserElement);
}
return GetCodebasePrincipalInternal(uri, UNKNOWN_APP_ID,
/* isInBrowserElement */ false, aPrincipal);
return GetCodebasePrincipalInternal(uri, appId, isInBrowserElement,
aPrincipal);
}
NS_IMETHODIMP
@ -1899,9 +1903,14 @@ nsScriptSecurityManager::GetDocShellCodebasePrincipal(nsIURI* aURI,
nsIDocShell* aDocShell,
nsIPrincipal** aPrincipal)
{
return GetCodebasePrincipalInternal(aURI,
aDocShell->GetAppId(),
aDocShell->GetIsInBrowserElement(),
MOZ_ASSERT(aDocShell);
uint32_t appId;
bool isInBrowserElement;
aDocShell->GetAppId(&appId);
aDocShell->GetIsInBrowserElement(&isInBrowserElement);
return GetCodebasePrincipalInternal(aURI, appId, isInBrowserElement,
aPrincipal);
}

View File

@ -115,9 +115,7 @@ ThirdPartyUtil::IsThirdPartyWindow(nsIDOMWindow* aWindow,
nsCOMPtr<nsIDOMWindow> current = aWindow, parent;
nsCOMPtr<nsIURI> parentURI;
do {
// We use GetScriptableParent rather than GetParent because we consider
// <iframe mozbrowser/mozapp> to be a top-level frame.
rv = current->GetScriptableParent(getter_AddRefs(parent));
rv = current->GetParent(getter_AddRefs(parent));
NS_ENSURE_SUCCESS(rv, rv);
if (SameCOMIdentity(parent, current)) {
@ -212,9 +210,7 @@ ThirdPartyUtil::IsThirdPartyChannel(nsIChannel* aChannel,
ctx->GetAssociatedWindow(getter_AddRefs(ourWin));
if (!ourWin) return NS_ERROR_INVALID_ARG;
// We use GetScriptableParent rather than GetParent because we consider
// <iframe mozbrowser/mozapp> to be a top-level frame.
ourWin->GetScriptableParent(getter_AddRefs(parentWin));
ourWin->GetParent(getter_AddRefs(parentWin));
NS_ENSURE_TRUE(parentWin, NS_ERROR_INVALID_ARG);
// Check whether this is the document channel for this window (representing a

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,50 +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::GetContainingApp()
{
// 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);
nsCOMPtr<mozIApplication> app = do_QueryInterface(domApp);
MOZ_ASSERT_IF(domApp, app);
return app.forget();
}
bool
nsFrameLoader::ShouldUseRemoteProcess()
{
@ -1482,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);
@ -1490,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,
@ -1537,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) {
@ -1638,38 +1614,13 @@ 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 = GetContainingApp();
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),
"in-process-browser-or-app-frame-shown", NULL);
"in-process-browser-frame-shown", NULL);
}
if (mMessageManager) {
@ -1997,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);
@ -2033,18 +1984,35 @@ nsFrameLoader::TryRemoteBrowser()
return false;
}
MutableTabContext context;
nsCOMPtr<mozIApplication> ownApp = GetOwnApp();
nsCOMPtr<mozIApplication> containingApp = GetContainingApp();
if (ownApp) {
context.SetTabContextForAppFrame(ownApp, containingApp);
} else if (OwnerIsBrowserFrame()) {
// The |else| above is unnecessary; OwnerIsBrowserFrame() implies !ownApp.
context.SetTabContextForBrowserFrame(containingApp);
bool isBrowserElement = false;
nsCOMPtr<mozIApplication> app;
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(context);
if (mRemoteBrowser) {
if ((mRemoteBrowser = ContentParent::CreateBrowser(app, isBrowserElement))) {
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(mOwnerContent);
mRemoteBrowser->SetOwnerElement(element);
@ -2354,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,29 +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 app which contains this frame. This is the app associated with
* the frame element's principal.
*/
already_AddRefed<mozIApplication> GetContainingApp();
/**
* 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

@ -730,7 +730,6 @@ nsDocShell::nsDocShell():
mCharsetReloadState(eCharsetReloadInit),
mChildOffset(0),
mBusyFlags(BUSY_FLAGS_NONE),
mFrameType(eFrameTypeRegular),
mAppType(nsIDocShell::APP_TYPE_UNKNOWN),
mLoadType(0),
mMarginWidth(-1),
@ -768,7 +767,7 @@ nsDocShell::nsDocShell():
#ifdef DEBUG
mInEnsureScriptEnv(false),
#endif
mOwnOrContainingAppId(nsIScriptSecurityManager::UNKNOWN_APP_ID),
mAppId(nsIScriptSecurityManager::NO_APP_ID),
mParentCharsetSource(0)
{
mHistoryID = ++gDocshellIDCounter;
@ -2151,7 +2150,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);
@ -2161,9 +2160,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) {
@ -2200,7 +2199,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
@ -2812,7 +2811,7 @@ nsDocShell::GetSameTypeParent(nsIDocShellTreeItem ** aParent)
NS_ENSURE_ARG_POINTER(aParent);
*aParent = nullptr;
if (nsIDocShell::GetIsBrowserOrApp()) {
if (mIsBrowserFrame) {
return NS_OK;
}
@ -2831,7 +2830,7 @@ nsDocShell::GetSameTypeParent(nsIDocShellTreeItem ** aParent)
}
NS_IMETHODIMP
nsDocShell::GetSameTypeParentIgnoreBrowserAndAppBoundaries(nsIDocShell** aParent)
nsDocShell::GetParentIgnoreBrowserFrame(nsIDocShell** aParent)
{
NS_ENSURE_ARG_POINTER(aParent);
*aParent = nullptr;
@ -2934,11 +2933,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;
@ -5222,7 +5229,7 @@ nsDocShell::SetIsActive(bool aIsActive)
continue;
}
if (!docshell->GetIsBrowserOrApp()) {
if (!docshell->GetIsContentBoundary()) {
docshell->SetIsActive(aIsActive);
}
}
@ -12304,52 +12311,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;
@ -12358,8 +12332,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;
@ -12373,6 +12349,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)
{
@ -12381,31 +12397,52 @@ 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));
GetParentIgnoreBrowserFrame(getter_AddRefs(parent));
if (!parent) {
*aAppId = nsIScriptSecurityManager::NO_APP_ID;

View File

@ -665,12 +665,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;
@ -807,6 +808,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
@ -843,18 +845,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(e93b2f6a-c543-448b-9239-55c96e31672e)]
interface nsIDocShell : nsISupports
{
/**
@ -579,101 +579,91 @@ 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.
* Returns if the docshell has a docshell that behaves as a content boundary
* in his parent hierarchy.
*/
[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.
*
* 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.
* This method is [noscript] to reduce the scope. It should be used at very
* specific moments.
*
* 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!
* Calling setAppId() will mark the frame as an app frame.
*/
[noscript] void setAppId(in unsigned long appId);
/**
* Returns the app id of the app the docshell is in. Returns
* nsIScriptSecurityManager::NO_APP_ID if the docshell is not in an app.
*/
[infallible] readonly attribute unsigned long appId;
/**
* Like nsIDocShellTreeItem::GetSameTypeParent, except this ignores <iframe
* mozbrowser> and <iframe mozapp> boundaries.
*/
nsIDocShell getSameTypeParentIgnoreBrowserAndAppBoundaries();
/**
* True iff asynchronous panning and zooming is enabled for this
* docshell.
*/
readonly attribute bool asyncPanZoomEnabled;
/**
* Like GetSameTypeParent, except this ignores <iframe mozbrowser>
* boundaries.
*/
nsIDocShell getParentIgnoreBrowserFrame();
/**
* The sandbox flags on the docshell. These reflect the value of the sandbox
* attribute of the associated IFRAME or CSP-protectable content, if

View File

@ -53,11 +53,10 @@ interface nsIDocShellTreeItem : nsIDocShellTreeNode
readonly attribute nsIDocShellTreeItem parent;
/*
This getter returns the same thing parent does however if the parent
is of a different itemType, or if the parent is an <iframe mozbrowser>
or <iframe mozapp>, it will instead return nullptr. This call is a
convience function for those wishing to not cross the boundaries at
which item types change.
This is call returns the same thing parent does however if the parent is
of a different itemType, it will instead return nullptr. This call is a
convience function for those wishing to not cross the boundaries at which
item types change.
*/
readonly attribute nsIDocShellTreeItem sameTypeParent;

View File

@ -83,7 +83,7 @@ interface nsILoadContext : nsISupports
[noscript] void SetPrivateBrowsing(in boolean aInPrivateBrowsing);
/**
* Returns true iff the load is occurring inside a browser element.
* Returns true iif the load is occurring inside a browser element.
*/
readonly attribute boolean isInBrowserElement;

View File

@ -1834,6 +1834,10 @@ this.DOMApplicationRegistry = {
switch (message.name) {
case "Webapps:ClearBrowserData":
this._clearPrivateData(appId, true);
// XXXbent This is a hack until bug 802366 is fixed. Currently all data
// loaded in mozbrowser frames within an app believe that their
// appId is 0.
this._clearPrivateData(0, true);
break;
}
},

View File

@ -2924,7 +2924,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;
@ -2948,7 +2948,7 @@ nsGlobalWindow::GetRealParent(nsIDOMWindow** aParent)
}
nsCOMPtr<nsIDocShell> parent;
mDocShell->GetSameTypeParentIgnoreBrowserAndAppBoundaries(getter_AddRefs(parent));
mDocShell->GetParentIgnoreBrowserFrame(getter_AddRefs(parent));
if (parent) {
nsCOMPtr<nsIScriptGlobalObject> globalObject(do_GetInterface(parent));
@ -3029,9 +3029,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);
}
@ -6488,7 +6488,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.
@ -7007,9 +7007,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)
@ -7017,7 +7016,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;
}
@ -7040,7 +7039,7 @@ nsGlobalWindow::GetRealFrameElement(nsIDOMElement** aFrameElement)
}
nsCOMPtr<nsIDocShell> parent;
mDocShell->GetSameTypeParentIgnoreBrowserAndAppBoundaries(getter_AddRefs(parent));
mDocShell->GetParentIgnoreBrowserFrame(getter_AddRefs(parent));
if (!parent || parent == mDocShell) {
// We're at a chrome boundary, don't expose the chrome iframe

View File

@ -120,7 +120,7 @@ BrowserElementParentFactory.prototype = {
var os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
os.addObserver(this, 'remote-browser-frame-shown', /* ownsWeak = */ true);
os.addObserver(this, 'in-process-browser-or-app-frame-shown', /* ownsWeak = */ true);
os.addObserver(this, 'in-process-browser-frame-shown', /* ownsWeak = */ true);
},
_browserFramesPrefEnabled: function() {
@ -161,7 +161,7 @@ BrowserElementParentFactory.prototype = {
case 'remote-browser-frame-shown':
this._observeRemoteBrowserFrameShown(subject);
break;
case 'in-process-browser-or-app-frame-shown':
case 'in-process-browser-frame-shown':
this._observeInProcessBrowserFrameShown(subject);
break;
case 'content-document-global-created':

View File

@ -90,9 +90,6 @@ MOCHITEST_FILES = \
test_browserElement_inproc_PromptCheck.html \
browserElement_PromptConfirm.js \
test_browserElement_inproc_PromptConfirm.html \
browserElement_CookiesNotThirdParty.js \
file_browserElement_CookiesNotThirdParty.html \
test_browserElement_inproc_CookiesNotThirdParty.html \
browserElement_Close.js \
test_browserElement_inproc_Close.html \
browserElement_CloseFromOpener.js \
@ -199,7 +196,6 @@ MOCHITEST_FILES += \
test_browserElement_oop_TargetBlank.html \
test_browserElement_oop_PromptCheck.html \
test_browserElement_oop_PromptConfirm.html \
test_browserElement_oop_CookiesNotThirdParty.html \
test_browserElement_oop_Close.html \
test_browserElement_oop_CloseFromOpener.html \
test_browserElement_oop_CloseApp.html \

View File

@ -1,50 +0,0 @@
/* Any copyright is dedicated to the public domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Bug 806127 - Test that cookies set by <iframe mozbrowser> are not considered
// third-party.
"use strict";
SimpleTest.waitForExplicitFinish();
function runTest() {
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
const innerPage = 'http://example.com/tests/dom/browser-element/mochitest/file_browserElement_CookiesNotThirdParty.html';
var iframe = document.createElement('iframe');
iframe.mozbrowser = true;
iframe.addEventListener('mozbrowsershowmodalprompt', function(e) {
if (e.detail.message == 'next') {
iframe.src = innerPage + '?step=2';
return;
}
if (e.detail.message.startsWith('success:')) {
ok(true, e.detail.message);
return;
}
if (e.detail.message.startsWith('failure:')) {
ok(false, e.detail.message);
return;
}
if (e.detail.message == 'finish') {
SimpleTest.finish();
}
});
// innerPage will set a cookie and then alert('next'). We'll load
// innerPage?step=2. That page will check that the cooke exists (despite the
// fact that we've disabled third-party cookies) and alert('success:') or
// alert('failure:'), as appropriate. Finally, the page will
// alert('finish');
iframe.src = innerPage;
document.body.appendChild(iframe);
}
// Disable third-party cookies for this test.
SpecialPowers.pushPrefEnv({'set': [['network.cookie.cookieBehavior', 1]]}, runTest);

View File

@ -1,25 +0,0 @@
<html>
<body>
file_browserElement_CookiesNotThirdParty.html
<script type='text/javascript;version=1.7'>
if (location.search != '?step=2') {
// Step 1: Set a cookie.
document.cookie = 'file_browserElement_CookiesNotThirdParty';
alert('next');
}
else {
// Step 2: Read the cookie.
if (document.cookie == 'file_browserElement_CookiesNotThirdParty') {
alert('success: got the correct cookie');
}
else {
alert('failure: got unexpected cookie: "' + document.cookie + '"');
}
alert('finish');
}
</script>
</body>
</html>

View File

@ -1,13 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for Bug 806127</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<script type="application/javascript;version=1.7" src="browserElement_CookiesNotThirdParty.js">
</script>
</body>
</html>

View File

@ -1,13 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for Bug 806127</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<script type="application/javascript;version=1.7" src="browserElement_CookiesNotThirdParty.js">
</script>
</body>
</html>

View File

@ -22,7 +22,6 @@
#include "nsITimer.h"
#include "mozilla/dom/file/FileService.h"
#include "mozilla/dom/TabContext.h"
#include "mozilla/LazyIdleThread.h"
#include "mozilla/Preferences.h"
#include "mozilla/Services.h"
@ -197,6 +196,13 @@ GetOriginPatternString(uint32_t aAppId, MozBrowserPatternFlag aBrowserFlag,
_retval = aOrigin;
}
void
GetOriginPatternString(uint32_t aAppId, nsAutoCString& _retval)
{
return GetOriginPatternString(aAppId, IgnoreMozBrowser, EmptyCString(),
_retval);
}
void
GetOriginPatternString(uint32_t aAppId, bool aBrowserOnly,
nsAutoCString& _retval)
@ -618,29 +624,33 @@ IndexedDatabaseManager::FireWindowOnError(nsPIDOMWindow* aOwner,
// static
bool
IndexedDatabaseManager::TabContextMayAccessOrigin(const TabContext& aContext,
const nsACString& aOrigin)
IndexedDatabaseManager::OriginMatchesApp(const nsACString& aOrigin,
uint32_t aAppId)
{
NS_ASSERTION(!aOrigin.IsEmpty(), "Empty origin!");
NS_ASSERTION(aAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID,
"Bad appId!");
nsAutoCString pattern;
GetOriginPatternString(aContext.OwnOrContainingAppId(),
aContext.IsBrowserElement(),
pattern);
if (PatternMatchesOrigin(pattern, aOrigin)) {
return true;
}
GetOriginPatternString(aAppId, pattern);
// If aContext is not for a browser element, then it's allowed to access
// is-browser-element origins.
if (!aContext.IsBrowserElement()) {
GetOriginPatternString(aContext.OwnOrContainingAppId(),
/* isBrowser */ true,
pattern);
return PatternMatchesOrigin(pattern, aOrigin);
}
return PatternMatchesOrigin(pattern, aOrigin);
}
return false;
// static
bool
IndexedDatabaseManager::OriginMatchesApp(const nsACString& aOrigin,
uint32_t aAppId,
bool aInMozBrowser)
{
NS_ASSERTION(!aOrigin.IsEmpty(), "Empty origin!");
NS_ASSERTION(aAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID,
"Bad appId!");
nsAutoCString pattern;
GetOriginPatternString(aAppId, aInMozBrowser, pattern);
return PatternMatchesOrigin(pattern, aOrigin);
}
bool

View File

@ -30,13 +30,6 @@ class nsITimer;
class nsPIDOMWindow;
class nsEventChainPostVisitor;
namespace mozilla {
namespace dom {
class TabContext;
}
}
BEGIN_INDEXEDDB_NAMESPACE
class AsyncConnectionHelper;
@ -211,8 +204,13 @@ public:
nsEventChainPostVisitor& aVisitor);
static bool
TabContextMayAccessOrigin(const TabContext& aContext,
const nsACString& aOrigin);
OriginMatchesApp(const nsACString& aOrigin,
uint32_t aAppId);
static bool
OriginMatchesApp(const nsACString& aOrigin,
uint32_t aAppId,
bool aInMozBrowser);
private:
IndexedDatabaseManager();

View File

@ -104,14 +104,11 @@ MOCHITEST_FILES = \
test_setVersion_events.html \
test_setVersion_exclusion.html \
test_unique_index_update.html \
test_webapp_clearBrowserData_inproc_oop.html \
test_webapp_clearBrowserData_oop_inproc.html \
test_webapp_clearBrowserData_inproc_inproc.html \
test_webapp_clearBrowserData.html \
third_party_iframe1.html \
third_party_iframe2.html \
test_app_isolation_inproc.html \
test_app_isolation_oop.html \
webapp_clearBrowserData.js \
webapp_clearBrowserData_appFrame.html \
webapp_clearBrowserData_browserFrame.html \
$(NULL)

View File

@ -0,0 +1,137 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>Indexed Database Clear Browser Data Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7">
"use strict";
const appDomain = "example.org";
const manifestURL =
location.protocol + "//" + appDomain + "/manifest.webapp";
function testSteps()
{
const objectStoreName = "foo";
const testKey = 1;
const testValue = objectStoreName;
let request = indexedDB.open(window.location.pathname, 1);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = unexpectedSuccessHandler;
let event = yield;
let db = event.target.result;
db.onerror = errorHandler;
db.onversionchange = function(event) {
event.target.close();
}
let objectStore = db.createObjectStore(objectStoreName);
objectStore.add(testValue, testKey);
request.onsuccess = grabEventAndContinueHandler;
event = yield;
let srcURL =
location.protocol + "//" + appDomain +
location.pathname.replace("test_webapp_clearBrowserData.html",
"webapp_clearBrowserData_appFrame.html");
let iframe = document.createElement("iframe");
iframe.setAttribute("mozbrowser", "");
iframe.setAttribute("mozapp", manifestURL);
iframe.setAttribute("src", srcURL);
iframe.setAttribute("remote", "true");
iframe.addEventListener("mozbrowsershowmodalprompt", function(event) {
let message = JSON.parse(event.detail.message);
switch (message.type) {
case "info":
case "ok":
window[message.type].apply(window, message.args);
break;
case "done":
continueToNextStepSync();
break;
default:
throw "unknown message";
}
});
info("loading app frame");
document.body.appendChild(iframe);
yield;
request = indexedDB.open(window.location.pathname, 1);
request.onerror = errorHandler;
request.onupgradeneeded = unexpectedSuccessHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield;
db = event.target.result;
db.onerror = errorHandler;
objectStore =
db.transaction(objectStoreName).objectStore(objectStoreName);
objectStore.get(testKey).onsuccess = grabEventAndContinueHandler;
event = yield;
ok(testValue == event.target.result, "data still exists");
finishTest();
yield;
}
function start()
{
if (!SpecialPowers.isMainProcess()) {
todo(false, "Test disabled in child processes, for now");
SimpleTest.finish();
return;
}
SpecialPowers.addPermission("browser", true, document);
SpecialPowers.addPermission("browser", true, { manifestURL: manifestURL,
isInBrowserElement: false });
SpecialPowers.addPermission("embed-apps", true, document);
let Webapps = {};
SpecialPowers.wrap(Components)
.utils.import("resource://gre/modules/Webapps.jsm", Webapps);
let appRegistry = SpecialPowers.wrap(Webapps.DOMApplicationRegistry);
let originalAllAppsLaunchable = appRegistry.allAppsLaunchable;
appRegistry.allAppsLaunchable = true;
window.addEventListener("unload", function cleanup(event) {
if (event.target == document) {
window.removeEventListener("unload", cleanup, false);
SpecialPowers.removePermission("browser", location.href);
SpecialPowers.removePermission("browser",
location.protocol + "//" + appDomain);
SpecialPowers.removePermission("embed-apps", location.href);
appRegistry.allAppsLaunchable = originalAllAppsLaunchable;
}
}, false);
SpecialPowers.pushPrefEnv({
"set": [["dom.mozBrowserFramesEnabled", true]]
}, runTest);
}
</script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="start();"></body>
</html>

View File

@ -1,33 +0,0 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!--
We have three similar tests here which each check that indexedDB data for a
browser inside an app is cleared upon request:
1) test_webapp_clearBrowserData_inproc_oop.html,
2) test_webapp_clearBrowserData_oop_inproc.html, and
3) test_webapp_clearBrowserData_inproc_inproc.html.
The only difference between these is that the first constructs an in-process
app frame which contains an out-of-process browser frame, the second
constructs an out-of-process app frame which contains an in-process browser
frame, and the third has both frames in process.
The tests share all their JS code. webapp_clearBrowserData.js determines
which frames are in- and out-of-process by looking at the test's filename.
-->
<html>
<head>
<title>Indexed Database Clear Browser Data Test inproc/inproc</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7" src="webapp_clearBrowserData.js"></script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="start();">
</body>
</html>

View File

@ -1,21 +0,0 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!--
See comment in test_webapp_clearBrowserData_inproc_inproc.html for an
explanation of what's going on here.
-->
<html>
<head>
<title>Indexed Database Clear Browser Data Test inproc/oop</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript;version=1.7" src="webapp_clearBrowserData.js"></script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body onload="start();">
</body>
</html>

View File

@ -1,21 +0,0 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!--
See comment in test_webapp_clearBrowserData_inproc_inproc.html for an
explanation of what's going on here.
-->
<html>
<head>
<title>Indexed Database Clear Browser Data Test oop/inproc</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript;version=1.7" src="webapp_clearBrowserData.js"></script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body onload="start();">
</body>
</html>

View File

@ -1,147 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const appDomain = "example.org";
const manifestURL =
location.protocol + "//" + appDomain + "/manifest.webapp";
function testSteps()
{
const objectStoreName = "foo";
const testKey = 1;
const testValue = objectStoreName;
// Determine whether the app and browser frames should be in or
// out-of-process.
let remote_app, remote_browser;
if (window.location.href.indexOf("inproc_oop") != -1) {
remote_app = false;
remote_browser = true;
}
else if (window.location.href.indexOf("oop_inproc") != -1) {
remote_app = true;
remote_browser = false;
}
else if (window.location.href.indexOf("inproc_inproc") != -1) {
remote_app = false;
remote_browser = false;
}
else {
ok(false, "Bad test filename!");
return;
}
let request = indexedDB.open(window.location.pathname, 1);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = unexpectedSuccessHandler;
let event = yield;
let db = event.target.result;
db.onerror = errorHandler;
db.onversionchange = function(event) {
event.target.close();
}
let objectStore = db.createObjectStore(objectStoreName);
objectStore.add(testValue, testKey);
request.onsuccess = grabEventAndContinueHandler;
event = yield;
// We need to send both remote_browser and remote_app in the querystring
// because webapp_clearBrowserData_appFrame uses the path + querystring to
// create and open a database which it checks no other test has touched. If
// we sent only remote_browser, then we wouldn't be able to test both
// (remote_app==false, remote_browser==false) and (remote_app==true,
// remote_browser==false).
let srcURL = location.protocol + "//" + appDomain +
location.pathname.substring(0, location.pathname.lastIndexOf('/')) +
"/webapp_clearBrowserData_appFrame.html?" +
"remote_browser=" + remote_browser + "&" +
"remote_app=" + remote_app;
let iframe = document.createElement("iframe");
iframe.setAttribute("mozbrowser", "");
iframe.setAttribute("mozapp", manifestURL);
iframe.setAttribute("src", srcURL);
iframe.setAttribute("remote", remote_app);
iframe.addEventListener("mozbrowsershowmodalprompt", function(event) {
let message = JSON.parse(event.detail.message);
switch (message.type) {
case "info":
case "ok":
window[message.type].apply(window, message.args);
break;
case "done":
continueToNextStepSync();
break;
default:
throw "unknown message";
}
});
info("loading app frame");
document.body.appendChild(iframe);
yield;
request = indexedDB.open(window.location.pathname, 1);
request.onerror = errorHandler;
request.onupgradeneeded = unexpectedSuccessHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield;
db = event.target.result;
db.onerror = errorHandler;
objectStore =
db.transaction(objectStoreName).objectStore(objectStoreName);
objectStore.get(testKey).onsuccess = grabEventAndContinueHandler;
event = yield;
ok(testValue == event.target.result, "data still exists");
finishTest();
yield;
}
function start()
{
if (!SpecialPowers.isMainProcess()) {
todo(false, "Test disabled in child processes, for now");
SimpleTest.finish();
return;
}
SpecialPowers.addPermission("browser", true, document);
SpecialPowers.addPermission("browser", true, { manifestURL: manifestURL,
isInBrowserElement: false });
SpecialPowers.addPermission("embed-apps", true, document);
let Webapps = {};
SpecialPowers.wrap(Components)
.utils.import("resource://gre/modules/Webapps.jsm", Webapps);
let appRegistry = SpecialPowers.wrap(Webapps.DOMApplicationRegistry);
let originalAllAppsLaunchable = appRegistry.allAppsLaunchable;
appRegistry.allAppsLaunchable = true;
window.addEventListener("unload", function cleanup(event) {
if (event.target == document) {
window.removeEventListener("unload", cleanup, false);
SpecialPowers.removePermission("browser", location.href);
SpecialPowers.removePermission("browser",
location.protocol + "//" + appDomain);
SpecialPowers.removePermission("embed-apps", location.href);
appRegistry.allAppsLaunchable = originalAllAppsLaunchable;
}
}, false);
SpecialPowers.pushPrefEnv({
"set": [["dom.mozBrowserFramesEnabled", true]]
}, runTest);
}

View File

@ -33,23 +33,8 @@
const objectStoreName = "foo";
const testKey = 1;
const testValue = objectStoreName;
const dbName = location.pathname + location.search;
// Determine whether our parent iframe asked us to create a remote
// browser frame here.
let remote_browser;
if (location.search.indexOf("remote_browser=true") != -1) {
remote_browser = true;
}
else if (location.search.indexOf("remote_browser=false") != -1) {
remote_browser = false;
}
else {
ok(false, "Expected remote_browser={true,false} in query string.");
return;
}
let request = indexedDB.open(dbName, 1);
let request = indexedDB.open(window.location.pathname, 1);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = unexpectedSuccessHandler;
@ -78,11 +63,7 @@
let iframe = document.createElement("iframe");
iframe.setAttribute("mozbrowser", "");
// Send our querystring to the subframe because
// webapp_clearBrowserData_browserFrame uses its pathname + querystring to
// open a database which it assumes hasn't been touched by another test.
iframe.setAttribute("src", "webapp_clearBrowserData_browserFrame.html" + location.search);
iframe.setAttribute("remote", remote_browser);
iframe.setAttribute("src", "webapp_clearBrowserData_browserFrame.html");
iframe.addEventListener("mozbrowsershowmodalprompt", function(event) {
let message = JSON.parse(event.detail.message);
switch (message.type) {
@ -115,7 +96,7 @@
document.body.appendChild(iframe);
yield;
request = indexedDB.open(dbName, 1);
request = indexedDB.open(window.location.pathname, 1);
request.onerror = errorHandler;
request.onupgradeneeded = unexpectedSuccessHandler;
request.onsuccess = grabEventAndContinueHandler;

View File

@ -43,9 +43,8 @@
const objectStoreName = "foo";
const testKey = 1;
const testValue = objectStoreName;
const dbName = window.location.pathname + window.location.search;
let request = indexedDB.open(dbName, 1);
let request = indexedDB.open(window.location.pathname, 1);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = unexpectedSuccessHandler;
@ -74,7 +73,7 @@
block();
request = indexedDB.open(dbName, 1);
request = indexedDB.open(window.location.pathname, 1);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = unexpectedSuccessHandler;

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

@ -231,11 +231,13 @@ ConsoleListener::Observe(nsIConsoleMessage* aMessage)
ContentChild* ContentChild::sSingleton;
ContentChild::ContentChild()
: TabContext()
, mID(uint64_t(-1))
:
mID(uint64_t(-1))
#ifdef ANDROID
,mScreenSize(0, 0)
#endif
, mIsForApp(false)
, mIsForBrowser(false)
{
// This process is a content process, so it's clearly running in
// multiprocess mode!
@ -299,7 +301,7 @@ ContentChild::Init(MessageLoop* aIOLoop,
startBackground ? hal::PROCESS_PRIORITY_BACKGROUND:
hal::PROCESS_PRIORITY_FOREGROUND);
if (mIsForApp && !mIsForBrowser) {
SetProcessName(NS_LITERAL_STRING("(Preallocated app)"));
SetProcessName(NS_LITERAL_STRING("(App)"));
} else {
SetProcessName(NS_LITERAL_STRING("Browser"));
}
@ -487,8 +489,8 @@ static void FirstIdle(void)
}
PBrowserChild*
ContentChild::AllocPBrowser(const IPCTabContext& aContext,
const uint32_t& aChromeFlags)
ContentChild::AllocPBrowser(const uint32_t& aChromeFlags,
const bool& aIsBrowserElement, const AppId& aApp)
{
static bool firstIdleTaskPosted = false;
if (!firstIdleTaskPosted) {
@ -496,12 +498,8 @@ ContentChild::AllocPBrowser(const IPCTabContext& aContext,
firstIdleTaskPosted = true;
}
// We'll happily accept any kind of IPCTabContext here; we don't need to
// check that it's of a certain type for security purposes, because we
// believe whatever the parent process tells us.
nsRefPtr<TabChild> child = TabChild::Create(TabContext(aContext), aChromeFlags);
nsRefPtr<TabChild> child =
TabChild::Create(aChromeFlags, aIsBrowserElement, aApp.get_uint32_t());
// The ref here is released below.
return child.forget().get();
}

View File

@ -9,7 +9,6 @@
#include "mozilla/Attributes.h"
#include "mozilla/dom/PContentChild.h"
#include "mozilla/dom/TabContext.h"
#include "mozilla/dom/ipc/Blob.h"
#include "nsTArray.h"
@ -41,7 +40,6 @@ class PStorageChild;
class ClonedMessageData;
class ContentChild : public PContentChild
, public TabContext
{
typedef mozilla::dom::ClonedMessageData ClonedMessageData;
typedef mozilla::ipc::OptionalURIParams OptionalURIParams;
@ -80,8 +78,9 @@ public:
AllocPImageBridge(mozilla::ipc::Transport* aTransport,
base::ProcessId aOtherProcess) MOZ_OVERRIDE;
virtual PBrowserChild* AllocPBrowser(const IPCTabContext &aContext,
const uint32_t &chromeFlags);
virtual PBrowserChild* AllocPBrowser(const uint32_t& aChromeFlags,
const bool& aIsBrowserElement,
const AppId& aAppId);
virtual bool DeallocPBrowser(PBrowserChild*);
virtual PDeviceStorageRequestChild* AllocPDeviceStorageRequest(const DeviceStorageParams&);
@ -196,6 +195,9 @@ public:
uint64_t GetID() { return mID; }
bool IsForApp() { return mIsForApp; }
bool IsForBrowser() { return mIsForBrowser; }
BlobChild* GetOrCreateActorForBlob(nsIDOMBlob* aBlob);
private:

View File

@ -55,6 +55,7 @@
#include "nsFrameMessageManager.h"
#include "nsHashPropertyBag.h"
#include "nsIAlertsService.h"
#include "nsIAppsService.h"
#include "nsIClipboard.h"
#include "nsIDOMApplicationRegistry.h"
#include "nsIDOMGeoGeolocation.h"
@ -316,25 +317,27 @@ AppNeedsInheritedOSPrivileges(mozIApplication* aApp)
}
/*static*/ TabParent*
ContentParent::CreateBrowserOrApp(const TabContext& aContext)
ContentParent::CreateBrowser(mozIApplication* aApp, bool aIsBrowserElement)
{
if (aContext.IsBrowserElement() || !aContext.HasOwnApp()) {
if (ContentParent* cp = GetNewOrUsed(aContext.IsBrowserElement())) {
nsRefPtr<TabParent> tp(new TabParent(aContext));
PBrowserParent* browser = cp->SendPBrowserConstructor(
tp.forget().get(), // DeallocPBrowserParent() releases this ref.
aContext.AsIPCTabContext(),
/* chromeFlags */ 0);
return static_cast<TabParent*>(browser);
// 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 (!aApp) {
if (ContentParent* cp = GetNewOrUsed(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,
aIsBrowserElement, nsIScriptSecurityManager::NO_APP_ID));
}
return nullptr;
}
// If we got here, we have an app and we're not a browser element. ownApp
// shouldn't be null, because we otherwise would have gone into the
// !HasOwnApp() branch above.
nsCOMPtr<mozIApplication> ownApp = aContext.GetOwnApp();
if (!gAppContentParents) {
gAppContentParents =
new nsDataHashtable<nsStringHashKey, ContentParent*>();
@ -343,15 +346,29 @@ ContentParent::CreateBrowserOrApp(const TabContext& aContext)
// 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 {
@ -360,7 +377,7 @@ ContentParent::CreateBrowserOrApp(const TabContext& aContext)
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();
}
@ -368,12 +385,12 @@ ContentParent::CreateBrowserOrApp(const TabContext& aContext)
gAppContentParents->Put(manifestURL, p);
}
nsRefPtr<TabParent> tp = new TabParent(aContext);
PBrowserParent* browser = p->SendPBrowserConstructor(
tp.forget().get(), // DeallocPBrowserParent() releases this ref.
aContext.AsIPCTabContext(),
/* chromeFlags */ 0);
return static_cast<TabParent*>(browser);
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,
aIsBrowserElement, appId));
}
static PLDHashOperator
@ -1146,37 +1163,30 @@ ContentParent::RecvGetXPCOMProcessAttributes(bool* aIsOffline)
}
PBrowserParent*
ContentParent::AllocPBrowser(const IPCTabContext& aContext,
const uint32_t &aChromeFlags)
ContentParent::AllocPBrowser(const uint32_t& aChromeFlags,
const bool& aIsBrowserElement, const AppId& aApp)
{
unused << aChromeFlags;
// 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 (AppId::TPBrowserParent != aApp.type()) {
NS_ERROR("Content process attempting to forge app ID");
return nullptr;
}
TabParent* opener = static_cast<TabParent*>(aApp.get_PBrowserParent());
// We don't trust the IPCTabContext we receive from the child, so we'll bail
// if we receive an IPCTabContext that's not a PopupIPCTabContext.
// (PopupIPCTabContext lets the child process prove that it has access to
// the app it's trying to open.)
if (aContext.type() != IPCTabContext::TPopupIPCTabContext) {
NS_ERROR("Unexpected IPCTabContext type. Aborting AllocPBrowser.");
// Popup windows of isBrowser frames are isBrowser if the parent
// isBrowser. Allocating a !isBrowser frame with same app ID
// would allow the content to access data it's not supposed to.
if (opener && opener->IsBrowserElement() && !aIsBrowserElement) {
NS_ERROR("Content process attempting to escalate data access privileges");
return nullptr;
}
const PopupIPCTabContext& popupContext = aContext.get_PopupIPCTabContext();
TabParent* opener = static_cast<TabParent*>(popupContext.openerParent());
if (!opener) {
NS_ERROR("Got null opener from child; aborting AllocPBrowser.");
return nullptr;
}
// Popup windows of isBrowser frames must be isBrowser if the parent
// isBrowser. Allocating a !isBrowser frame with same app ID would allow
// the content to access data it's not supposed to.
if (!popupContext.isBrowserElement() && opener->IsBrowserElement()) {
NS_ERROR("Child trying to escalate privileges! Aborting AllocPBrowser.");
return nullptr;
}
TabParent* parent = new TabParent(TabContext(aContext));
TabParent* parent = new TabParent(opener ? opener->GetApp() : nullptr,
aIsBrowserElement);
// We release this ref in DeallocPBrowser()
NS_ADDREF(parent);
return parent;

View File

@ -11,7 +11,6 @@
#include "mozilla/dom/PContentParent.h"
#include "mozilla/dom/PMemoryReportRequestParent.h"
#include "mozilla/dom/TabContext.h"
#include "mozilla/ipc/GeckoChildProcessHost.h"
#include "mozilla/dom/ipc/Blob.h"
#include "mozilla/Attributes.h"
@ -75,9 +74,15 @@ public:
static ContentParent* GetNewOrUsed(bool aForBrowserElement = false);
/**
* Get or create a content process for the given TabContext.
* 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.
*
* Currently apps are given their own process, and browser tabs
* share processes.
*/
static TabParent* CreateBrowserOrApp(const TabContext& aContext);
static TabParent* CreateBrowser(mozIApplication* aApp,
bool aIsBrowserFrame);
static void GetAll(nsTArray<ContentParent*>& aArray);
@ -184,8 +189,9 @@ private:
bool* aIsForBrowser) MOZ_OVERRIDE;
virtual bool RecvGetXPCOMProcessAttributes(bool* aIsOffline) MOZ_OVERRIDE;
virtual PBrowserParent* AllocPBrowser(const IPCTabContext& aContext,
const uint32_t& aChromeFlags);
virtual PBrowserParent* AllocPBrowser(const uint32_t& aChromeFlags,
const bool& aIsBrowserElement,
const AppId& aApp);
virtual bool DeallocPBrowser(PBrowserParent* frame);
virtual PDeviceStorageRequestParent* AllocPDeviceStorageRequest(const DeviceStorageParams&);

View File

@ -42,7 +42,6 @@ EXPORTS_mozilla/dom = \
StructuredCloneUtils.h \
TabParent.h \
TabChild.h \
TabContext.h \
TabMessageUtils.h \
$(NULL)
@ -65,7 +64,6 @@ CPPSRCS = \
StructuredCloneUtils.cpp \
TabParent.cpp \
TabChild.cpp \
TabContext.cpp \
TabMessageUtils.cpp \
$(NULL)

View File

@ -135,60 +135,9 @@ union BlobConstructorParams
MysteryBlobConstructorParams;
};
// An IPCTabContext which corresponds to a PBrowser opened by a child when it
// receives window.open().
//
// If isBrowserElement is false, this PopupIPCTabContext corresponds to an app
// frame, and the frame's app-id and app-frame-owner-app-id will be equal to the
// opener's values.
//
// If isBrowserElement is true, the frame's browserFrameOwnerAppId will be equal
// to the opener's app-id.
//
// It's an error to set isBrowserElement == false if opener is a browser
// element. Such a PopupIPCTabContext should be rejected by code which receives
// it.
struct PopupIPCTabContext
{
PBrowser opener;
bool isBrowserElement;
};
// An IPCTabContext which corresponds to an app frame.
struct AppFrameIPCTabContext
{
// The ID of the app this frame corresponds to. May be NO_APP_ID.
uint32_t ownAppId;
// The ID of the app containing this frame. May be NO_APP_ID.
uint32_t appFrameOwnerAppId;
};
// An IPCTabContext which corresponds to a browser frame.
struct BrowserFrameIPCTabContext
{
// The ID of the app which contains this browser frame. May be NO_APP_ID.
uint32_t browserFrameOwnerAppId;
};
// This is equivalent to AppFrameIPCTabContext with all fields set to NO_APP_ID.
struct VanillaFrameIPCTabContext
{};
// IPCTabContext is an analog to mozilla::dom::TabContext. Both specify an
// iframe/PBrowser's own and containing app-ids and tell you whether the
// iframe/PBrowser is a browser frame. But only IPCTabContext is allowed to
// travel over IPC.
//
// We need IPCTabContext (specifically, PopupIPCTabContext) to prevent a
// privilege escalation attack by a compromised child process. See the comment
// on AllocPBrowser for details.
union IPCTabContext
{
PopupIPCTabContext;
AppFrameIPCTabContext;
BrowserFrameIPCTabContext;
VanillaFrameIPCTabContext;
union AppId {
uint32_t;
nullable PBrowser;
};
union PrefValue {
@ -233,26 +182,16 @@ both:
// created from either the child or parent process!
//
// The child creates the PBrowser as part of
// TabChild::BrowserFrameProvideWindow (which happens when the child's
// content calls window.open()), and the parent creates the PBrowser as part
// of ContentParent::CreateTab.
// TabChild::BrowserFrameProvideWindow, and the parent creates the
// PBrowser as part of ContentParent::CreateTab.
//
// When the parent constructs a PBrowser, the child trusts the app token it
// receives from the parent. In that case, context can be any of the
// IPCTabContext subtypes.
//
// When the child constructs a PBrowser, the parent doesn't trust the app
// token it receives from the child. In this case, context must have type
// PopupIPCTabContext. The browser created using a PopupIPCTabContext has
// the opener PBrowser's app-id and containing-app-id. The parent checks
// that if the opener is a browser element, the context is also for a
// browser element.
//
// This allows the parent to prevent a malicious child from escalating its
// privileges by requesting a PBrowser corresponding to a highly-privileged
// app; the child can only request privileges for an app which the child has
// access to (in the form of a TabChild).
async PBrowser(IPCTabContext context, uint32_t chromeFlags);
// 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

@ -120,7 +120,8 @@ TabChild::PreloadSlowThings()
{
MOZ_ASSERT(!sPreallocatedTab);
nsRefPtr<TabChild> tab(new TabChild(TabContext(), /* chromeFlags */ 0));
nsRefPtr<TabChild> tab(new TabChild(0, false,
nsIScriptSecurityManager::NO_APP_ID));
if (!NS_SUCCEEDED(tab->Init()) ||
!tab->InitTabChildGlobal(DONT_LOAD_SCRIPTS)) {
return;
@ -132,37 +133,41 @@ TabChild::PreloadSlowThings()
}
/*static*/ already_AddRefed<TabChild>
TabChild::Create(const TabContext &aContext, uint32_t aChromeFlags)
TabChild::Create(uint32_t aChromeFlags,
bool aIsBrowserElement, uint32_t aAppId)
{
if (sPreallocatedTab &&
sPreallocatedTab->mChromeFlags == aChromeFlags &&
aContext.IsBrowserOrApp()) {
(aIsBrowserElement ||
aAppId != nsIScriptSecurityManager::NO_APP_ID)) {
nsRefPtr<TabChild> child = sPreallocatedTab.get();
sPreallocatedTab = nullptr;
MOZ_ASSERT(!child->mTriedBrowserInit);
child->SetTabContext(aContext);
child->NotifyTabContextUpdated();
child->SetAppBrowserConfig(aIsBrowserElement, aAppId);
return child.forget();
}
nsRefPtr<TabChild> iframe = new TabChild(aContext, aChromeFlags);
nsRefPtr<TabChild> iframe = new TabChild(aChromeFlags, aIsBrowserElement,
aAppId);
return NS_SUCCEEDED(iframe->Init()) ? iframe.forget() : nullptr;
}
TabChild::TabChild(const TabContext& aContext, uint32_t aChromeFlags)
: TabContext(aContext)
, mRemoteFrame(nullptr)
TabChild::TabChild(uint32_t aChromeFlags, bool aIsBrowserElement,
uint32_t aAppId)
: mRemoteFrame(nullptr)
, mTabChildGlobal(nullptr)
, mChromeFlags(aChromeFlags)
, mOuterRect(0, 0, 0, 0)
, mInnerSize(0, 0)
, mOldViewportWidth(0.0f)
, mLastBackgroundColor(NS_RGB(255, 255, 255))
, mAppId(aAppId)
, mDidFakeShow(false)
, mIsBrowserElement(aIsBrowserElement)
, mNotified(false)
, mContentDocumentIsDisplayed(false)
, mTriedBrowserInit(false)
@ -525,7 +530,7 @@ TabChild::Init()
baseWindow->InitWindow(0, mWidget, 0, 0, 0, 0);
baseWindow->Create();
NotifyTabContextUpdated();
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
@ -549,18 +554,18 @@ TabChild::Init()
}
void
TabChild::NotifyTabContextUpdated()
TabChild::SetAppBrowserConfig(bool aIsBrowserElement, uint32_t aAppId)
{
mIsBrowserElement = aIsBrowserElement;
mAppId = aAppId;
nsCOMPtr<nsIDocShell> docShell = do_GetInterface(mWebNav);
MOZ_ASSERT(docShell);
if (docShell) {
// nsDocShell will do the right thing if we pass NO_APP_ID or
// UNKNOWN_APP_ID for aOwnOrContainingAppId.
if (IsBrowserElement()) {
docShell->SetIsBrowserInsideApp(BrowserOwnerAppId());
} else {
docShell->SetIsApp(OwnAppId());
docShell->SetAppId(mAppId);
if (mIsBrowserElement) {
docShell->SetIsBrowserElement();
}
}
}
@ -784,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))) {
@ -823,25 +828,16 @@ TabChild::BrowserFrameProvideWindow(nsIDOMWindow* aOpener,
{
*aReturn = nullptr;
nsRefPtr<TabChild> newChild =
new TabChild(/* TabContext */ *this, /* chromeFlags */ 0);
uint32_t chromeFlags = 0;
nsRefPtr<TabChild> newChild = new TabChild(chromeFlags,
mIsBrowserElement, mAppId);
if (!NS_SUCCEEDED(newChild->Init())) {
return NS_ERROR_ABORT;
}
// We must use PopupIPCTabContext here; ContentParent will not accept the
// result of this->AsIPCTabContext() (which will be a
// BrowserFrameIPCTabContext or an AppFrameIPCTabContext), for security
// reasons.
PopupIPCTabContext context;
context.openerChild() = this;
context.isBrowserElement() = IsBrowserElement();
unused << Manager()->SendPBrowserConstructor(
// We release this ref in DeallocPBrowserChild
nsRefPtr<TabChild>(newChild).forget().get(),
context, /* chromeFlags */ 0);
chromeFlags, mIsBrowserElement, this);
nsAutoCString spec;
if (aURI) {
aURI->GetSpec(spec);
@ -1002,13 +998,29 @@ TabChild::~TabChild()
void
TabChild::SetProcessNameToAppName()
{
nsCOMPtr<mozIApplication> app = GetOwnApp();
if (!app) {
if (mIsBrowserElement || (mAppId == nsIScriptSecurityManager::NO_APP_ID)) {
return;
}
nsCOMPtr<nsIAppsService> appsService =
do_GetService(APPS_SERVICE_CONTRACTID);
if (!appsService) {
NS_WARNING("No AppsService");
return;
}
nsresult rv;
nsCOMPtr<mozIDOMApplication> domApp;
rv = appsService->GetAppByLocalId(mAppId, getter_AddRefs(domApp));
if (NS_FAILED(rv) || !domApp) {
NS_WARNING("GetAppByLocalId failed");
return;
}
nsCOMPtr<mozIApplication> app = do_QueryInterface(domApp);
if (!app) {
NS_WARNING("app isn't a mozIApplication");
return;
}
nsAutoString appName;
nsresult rv = app->GetName(appName);
rv = app->GetName(appName);
if (NS_FAILED(rv)) {
NS_WARNING("Failed to retrieve app name");
return;
@ -1020,25 +1032,19 @@ TabChild::SetProcessNameToAppName()
bool
TabChild::IsRootContentDocument()
{
// A TabChild is a "root content document" if it's
//
// - <iframe mozapp> not inside another <iframe mozapp>,
// - <iframe mozbrowser> (not mozapp), or
// - a vanilla remote frame (<html:iframe remote=true> or <xul:browser
// remote=true>).
//
// Put another way, an iframe is /not/ a "root content document" iff it's a
// mozapp inside a mozapp. (This corresponds exactly to !HasAppOwnerApp.)
//
// Note that we're lying through our teeth here (thus the scare quotes).
// <html:iframe remote=true> or <xul:browser remote=true> inside another
// content iframe is not actually a root content document, but we say it is.
//
// We do this because we make a remote frame opaque iff
// IsRootContentDocument(), and making vanilla remote frames transparent
// breaks our remote reftests.
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;
}
return !HasAppOwnerApp();
// Otherwise, we're the child side of an <html:app remote=true>
// embedded in an outer <html:app>. These don't behave like root
// content documents in nested contexts. Because of bug 761935,
// <html:browser remote> and <html:app remote> can't nest, so we
// assume this isn't the root. When that bug is fixed, we need to
// revisit that assumption.
return false;
}
bool
@ -1696,7 +1702,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

@ -51,7 +51,6 @@
#include "mozilla/Attributes.h"
#include "FrameMetrics.h"
#include "ProcessUtils.h"
#include "mozilla/dom/TabContext.h"
struct gfxMatrix;
@ -150,8 +149,7 @@ class TabChild : public PBrowserChild,
public nsIDialogCreator,
public nsITabChild,
public nsIObserver,
public ipc::MessageManagerCallback,
public TabContext
public mozilla::dom::ipc::MessageManagerCallback
{
typedef mozilla::layout::RenderFrameChild RenderFrameChild;
typedef mozilla::dom::ClonedMessageData ClonedMessageData;
@ -166,10 +164,12 @@ public:
/** Return a TabChild with the given attributes. */
static already_AddRefed<TabChild>
Create(const TabContext& aContext, uint32_t aChromeFlags);
Create(uint32_t aChromeFlags, bool aIsBrowserElement, uint32_t aAppId);
virtual ~TabChild();
uint32_t GetAppId() { return mAppId; }
bool IsRootContentDocument();
NS_DECL_ISUPPORTS
@ -320,21 +320,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(const TabContext& aContext, uint32_t aChromeFlags);
TabChild(uint32_t aChromeFlags, bool aIsBrowserElement, uint32_t aAppId);
nsresult Init();
// Notify others that our TabContext has been updated. (At the moment, this
// sets the appropriate app-id and is-browser flags on our docshell.)
//
// You should call this after calling TabContext::SetTabContext(). We also
// call this during Init().
void NotifyTabContextUpdated();
void SetAppBrowserConfig(bool aIsBrowserElement, uint32_t aAppId);
bool UseDirectCompositor();
@ -398,7 +392,9 @@ private:
float mOldViewportWidth;
nscolor mLastBackgroundColor;
ScrollingBehavior mScrolling;
uint32_t mAppId;
bool mDidFakeShow;
bool mIsBrowserElement;
bool mNotified;
bool mContentDocumentIsDisplayed;
bool mTriedBrowserInit;

View File

@ -1,292 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et tw=80 : */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/TabContext.h"
#include "mozilla/dom/TabParent.h"
#include "mozilla/dom/TabChild.h"
#include "nsIAppsService.h"
using namespace mozilla::dom::ipc;
namespace mozilla {
namespace dom {
TabContext::TabContext()
: mInitialized(false)
, mOwnAppId(nsIScriptSecurityManager::NO_APP_ID)
, mContainingAppId(nsIScriptSecurityManager::NO_APP_ID)
, mIsBrowser(false)
{
}
TabContext::TabContext(const IPCTabContext& aParams)
: mInitialized(true)
{
switch(aParams.type()) {
case IPCTabContext::TPopupIPCTabContext: {
const PopupIPCTabContext &ipcContext = aParams.get_PopupIPCTabContext();
TabContext *context;
if (ipcContext.openerParent()) {
context = static_cast<TabParent*>(ipcContext.openerParent());
if (context->IsBrowserElement() && !ipcContext.isBrowserElement()) {
// If the TabParent 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.
MOZ_CRASH();
}
}
else if (ipcContext.openerChild()) {
context = static_cast<TabChild*>(ipcContext.openerChild());
}
else {
// This should be unreachable because PopupIPCTabContext::opener is not a
// nullable field.
MOZ_CRASH();
}
// If ipcContext is a browser element, then the opener's app-id becomes
// our containing app-id. Otherwise, our own and containing app-ids are
// directly inherited from our opener.
if (ipcContext.isBrowserElement()) {
mIsBrowser = true;
mOwnAppId = nsIScriptSecurityManager::NO_APP_ID;
mContainingAppId = context->OwnAppId();
}
else {
mIsBrowser = false;
mOwnAppId = context->mOwnAppId;
mContainingAppId = context->mContainingAppId;
}
break;
}
case IPCTabContext::TAppFrameIPCTabContext: {
const AppFrameIPCTabContext &ipcContext =
aParams.get_AppFrameIPCTabContext();
mIsBrowser = false;
mOwnAppId = ipcContext.ownAppId();
mContainingAppId = ipcContext.appFrameOwnerAppId();
break;
}
case IPCTabContext::TBrowserFrameIPCTabContext: {
const BrowserFrameIPCTabContext &ipcContext =
aParams.get_BrowserFrameIPCTabContext();
mIsBrowser = true;
mOwnAppId = nsIScriptSecurityManager::NO_APP_ID;
mContainingAppId = ipcContext.browserFrameOwnerAppId();
break;
}
case IPCTabContext::TVanillaFrameIPCTabContext: {
mIsBrowser = false;
mOwnAppId = nsIScriptSecurityManager::NO_APP_ID;
mContainingAppId = nsIScriptSecurityManager::NO_APP_ID;
break;
}
default: {
MOZ_CRASH();
}
}
}
bool
TabContext::IsBrowserElement() const
{
return mIsBrowser;
}
bool
TabContext::IsBrowserOrApp() const
{
return HasOwnApp() || IsBrowserElement();
}
uint32_t
TabContext::OwnAppId() const
{
return mOwnAppId;
}
already_AddRefed<mozIApplication>
TabContext::GetOwnApp() const
{
return GetAppForId(OwnAppId());
}
bool
TabContext::HasOwnApp() const
{
return mOwnAppId != nsIScriptSecurityManager::NO_APP_ID;
}
uint32_t
TabContext::BrowserOwnerAppId() const
{
if (mIsBrowser) {
return mContainingAppId;
}
return nsIScriptSecurityManager::NO_APP_ID;
}
already_AddRefed<mozIApplication>
TabContext::GetBrowserOwnerApp() const
{
return GetAppForId(BrowserOwnerAppId());
}
bool
TabContext::HasBrowserOwnerApp() const
{
return BrowserOwnerAppId() != nsIScriptSecurityManager::NO_APP_ID;
}
uint32_t
TabContext::AppOwnerAppId() const
{
if (mOwnAppId != nsIScriptSecurityManager::NO_APP_ID) {
return mContainingAppId;
}
return nsIScriptSecurityManager::NO_APP_ID;
}
already_AddRefed<mozIApplication>
TabContext::GetAppOwnerApp() const
{
return GetAppForId(AppOwnerAppId());
}
bool
TabContext::HasAppOwnerApp() const
{
return AppOwnerAppId() != nsIScriptSecurityManager::NO_APP_ID;
}
uint32_t
TabContext::OwnOrContainingAppId() const
{
if (mIsBrowser) {
MOZ_ASSERT(mOwnAppId == nsIScriptSecurityManager::NO_APP_ID);
return mContainingAppId;
}
if (mOwnAppId) {
return mOwnAppId;
}
return mContainingAppId;
}
already_AddRefed<mozIApplication>
TabContext::GetOwnOrContainingApp() const
{
return GetAppForId(OwnOrContainingAppId());
}
bool
TabContext::HasOwnOrContainingApp() const
{
return OwnOrContainingAppId() != nsIScriptSecurityManager::NO_APP_ID;
}
bool
TabContext::SetTabContext(const TabContext& aContext)
{
NS_ENSURE_FALSE(mInitialized, false);
// Verify that we can actually get apps for the given ids. This step gives us
// confidence that HasX() returns true iff GetX() returns true.
if (aContext.mOwnAppId != nsIScriptSecurityManager::NO_APP_ID) {
nsCOMPtr<mozIApplication> app = GetAppForId(aContext.mOwnAppId);
NS_ENSURE_TRUE(app, false);
}
if (aContext.mContainingAppId != nsIScriptSecurityManager::NO_APP_ID) {
nsCOMPtr<mozIApplication> app = GetAppForId(aContext.mContainingAppId);
NS_ENSURE_TRUE(app, false);
}
mInitialized = true;
mIsBrowser = aContext.mIsBrowser;
mOwnAppId = aContext.mOwnAppId;
mContainingAppId = aContext.mContainingAppId;
return true;
}
bool
TabContext::SetTabContextForAppFrame(mozIApplication* aOwnApp, mozIApplication* aAppFrameOwnerApp)
{
NS_ENSURE_FALSE(mInitialized, false);
// Get ids for both apps and only write to our member variables after we've
// verified that this worked.
uint32_t ownAppId = nsIScriptSecurityManager::NO_APP_ID;
if (aOwnApp) {
nsresult rv = aOwnApp->GetLocalId(&ownAppId);
NS_ENSURE_SUCCESS(rv, false);
}
uint32_t containingAppId = nsIScriptSecurityManager::NO_APP_ID;
if (aAppFrameOwnerApp) {
nsresult rv = aOwnApp->GetLocalId(&containingAppId);
NS_ENSURE_SUCCESS(rv, false);
}
mInitialized = true;
mIsBrowser = false;
mOwnAppId = ownAppId;
mContainingAppId = containingAppId;
return true;
}
bool
TabContext::SetTabContextForBrowserFrame(mozIApplication* aBrowserFrameOwnerApp)
{
NS_ENSURE_FALSE(mInitialized, false);
uint32_t containingAppId = nsIScriptSecurityManager::NO_APP_ID;
if (aBrowserFrameOwnerApp) {
nsresult rv = aBrowserFrameOwnerApp->GetLocalId(&containingAppId);
NS_ENSURE_SUCCESS(rv, false);
}
mInitialized = true;
mIsBrowser = true;
mOwnAppId = nsIScriptSecurityManager::NO_APP_ID;
mContainingAppId = containingAppId;
return true;
}
IPCTabContext
TabContext::AsIPCTabContext() const
{
if (mIsBrowser) {
return BrowserFrameIPCTabContext(mContainingAppId);
}
return AppFrameIPCTabContext(mOwnAppId, mContainingAppId);
}
already_AddRefed<mozIApplication>
TabContext::GetAppForId(uint32_t aAppId) const
{
if (aAppId == nsIScriptSecurityManager::NO_APP_ID) {
return nullptr;
}
nsCOMPtr<nsIAppsService> appsService = do_GetService(APPS_SERVICE_CONTRACTID);
NS_ENSURE_TRUE(appsService, nullptr);
nsCOMPtr<mozIDOMApplication> domApp;
appsService->GetAppByLocalId(aAppId, getter_AddRefs(domApp));
nsCOMPtr<mozIApplication> app = do_QueryInterface(domApp);
return app.forget();
}
} // namespace dom
} // namespace mozilla

View File

@ -1,209 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et tw=80 : */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_TabContext_h
#define mozilla_dom_TabContext_h
#include "mozilla/Assertions.h"
#include "mozilla/dom/PContent.h"
#include "mozilla/dom/PBrowser.h"
#include "nsIScriptSecurityManager.h"
#include "mozIApplication.h"
namespace mozilla {
namespace dom {
/**
* TabContext encapsulates information about an iframe that may be a mozbrowser
* or mozapp. You can ask whether a TabContext correspodns to a mozbrowser or
* mozapp, get the app that contains the browser, and so on.
*
* TabParent and TabChild both inherit from TabContext, and you can also have
* standalone TabContext objects.
*
* This class is immutable except by calling one of the protected
* SetTabContext*() methods (and those methods can only be called once). See
* also MutableTabContext.
*/
class TabContext
{
public:
/**
* This constructor sets is-browser to false, and sets all relevant apps to
* NO_APP_ID. If you inherit from TabContext, you can mutate this object
* exactly once by calling one of the protected SetTabContext*() methods.
*/
TabContext();
/**
* This constructor copies the information in aContext. The TabContext is
* immutable after calling this method; you won't be able call any of the
* protected SetTabContext*() methods on an object constructed using this
* constructor.
*
* If aContext is a PopupIPCTabContext with isBrowserElement false and whose
* openerParent is a browser element, this constructor will crash (even in
* release builds). So please check that case before calling this method.
*/
TabContext(const IPCTabContext& aContext);
/**
* Generates IPCTabContext of type BrowserFrameIPCTabContext or
* AppFrameIPCTabContext from this TabContext's information.
*/
IPCTabContext AsIPCTabContext() const;
/**
* Does this TabContext correspond to a mozbrowser? (<iframe mozbrowser
* mozapp> is not a browser.)
*
* If IsBrowserElement() is true, HasOwnApp() and HasAppOwnerApp() are
* guaranteed to be false.
*
* If IsBrowserElement() is false, HasBrowserOwnerApp() is guaranteed to be
* false.
*/
bool IsBrowserElement() const;
/**
* Does this TabContext correspond to a mozbrowser or mozapp? This is
* equivalent to IsBrowserElement() || HasOwnApp().
*/
bool IsBrowserOrApp() const;
/**
* OwnAppId() returns the id of the app which directly corresponds to this
* context's frame. GetOwnApp() returns the corresponding app object, and
* HasOwnApp() returns true iff GetOwnApp() would return a non-null value.
*
* If HasOwnApp() is true, IsBrowserElement() is guaranteed to be false.
*/
uint32_t OwnAppId() const;
already_AddRefed<mozIApplication> GetOwnApp() const;
bool HasOwnApp() const;
/**
* BrowserOwnerAppId() gets the ID of the app which contains this browser
* frame. If this is not a browser frame (i.e., if !IsBrowserElement()), then
* BrowserOwnerAppId() is guaranteed to return NO_APP_ID.
*
* Even if we are a browser frame, BrowserOwnerAppId() may still return
* NO_APP_ID, if this browser frame is not contained inside an app.
*/
uint32_t BrowserOwnerAppId() const;
already_AddRefed<mozIApplication> GetBrowserOwnerApp() const;
bool HasBrowserOwnerApp() const;
/**
* AppOwnerAppId() gets the ID of the app which contains this app frame. If
* this is not an app frame (i.e., if !HasOwnApp()), then AppOwnerAppId() is
* guaranteed to return NO_APP_ID.
*
* Even if we are an app frame, AppOwnerAppId() may still return NO_APP_ID, if
* this app frame is not contained inside an app.
*/
uint32_t AppOwnerAppId() const;
already_AddRefed<mozIApplication> GetAppOwnerApp() const;
bool HasAppOwnerApp() const;
/**
* OwnOrContainingAppId() gets the ID of this frame, if HasOwnApp(). If this
* frame does not have its own app, it gets the ID of the app which contains
* this frame (i.e., the result of {Browser,App}OwnerAppId(), as applicable).
*/
uint32_t OwnOrContainingAppId() const;
already_AddRefed<mozIApplication> GetOwnOrContainingApp() const;
bool HasOwnOrContainingApp() const;
protected:
/**
* These protected mutator methods let you modify a TabContext once. Further
* attempts to modify a given TabContext will fail (the method will return
* false).
*
* These mutators will also fail if the TabContext was created with anything
* other than the no-args constructor.
*/
/**
* Set this TabContext to match the given TabContext.
*/
bool SetTabContext(const TabContext& aContext);
/**
* Set this TabContext to be an app frame (with the given own app) inside the
* given app. Either or both apps may be null.
*/
bool SetTabContextForAppFrame(mozIApplication* aOwnApp,
mozIApplication* aAppFrameOwnerApp);
/**
* Set this TabContext to be a browser frame inside the given app (which may
* be null).
*/
bool SetTabContextForBrowserFrame(mozIApplication* aBrowserFrameOwnerApp);
private:
/**
* Translate an appId into a mozIApplication.
*/
already_AddRefed<mozIApplication> GetAppForId(uint32_t aAppId) const;
/**
* Has this TabContext been initialized? If so, mutator methods will fail.
*/
bool mInitialized;
/**
* This TabContext's own app id. If this is something other than NO_APP_ID,
* then this TabContext corresponds to an app, and mIsBrowser must be false.
*/
uint32_t mOwnAppId;
/**
* The id of the app which contains this TabContext's frame. If mIsBrowser,
* this corresponds to the ID of the app which contains the browser frame;
* otherwise, this correspodns to the ID of the app which contains the app
* frame.
*/
uint32_t mContainingAppId;
/**
* Does this TabContext correspond to a browser element?
*
* If this is true, mOwnAppId must be NO_APP_ID.
*/
bool mIsBrowser;
};
/**
* MutableTabContext is the same as TabContext, except the mutation methods are
* public instead of protected. You can still only call these mutation methods
* once on a given object.
*/
class MutableTabContext : public TabContext
{
public:
bool SetTabContext(const TabContext& aContext)
{
return TabContext::SetTabContext(aContext);
}
bool SetTabContextForAppFrame(mozIApplication* aOwnApp, mozIApplication* aAppFrameOwnerApp)
{
return TabContext::SetTabContextForAppFrame(aOwnApp, aAppFrameOwnerApp);
}
bool SetTabContextForBrowserFrame(mozIApplication* aBrowserFrameOwnerApp)
{
return TabContext::SetTabContextForBrowserFrame(aBrowserFrameOwnerApp);
}
};
} // namespace dom
} // namespace mozilla
#endif

View File

@ -73,9 +73,9 @@ TabParent *TabParent::mIMETabParent = nullptr;
NS_IMPL_ISUPPORTS3(TabParent, nsITabParent, nsIAuthPromptProvider, nsISecureBrowserUI)
TabParent::TabParent(const TabContext& aContext)
: TabContext(aContext)
, mFrameElement(NULL)
TabParent::TabParent(mozIApplication* aApp, bool aIsBrowserElement)
: mFrameElement(NULL)
, mApp(aApp)
, mIMESelectionAnchor(0)
, mIMESelectionFocus(0)
, mIMEComposing(false)
@ -85,6 +85,7 @@ TabParent::TabParent(const TabContext& aContext)
, mEventCaptureDepth(0)
, mDimensions(0, 0)
, mDPI(0)
, mIsBrowserElement(aIsBrowserElement)
, mShown(false)
{
}
@ -187,7 +188,7 @@ TabParent::AnswerCreateWindow(PBrowserParent** retval)
}
// Only non-app, non-browser processes may call CreateWindow.
if (IsBrowserOrApp()) {
if (GetApp() || IsBrowserElement()) {
return false;
}
@ -895,15 +896,17 @@ TabParent::RecvPIndexedDBConstructor(PIndexedDBParent* aActor,
// XXXbent Need to make sure we have a whitelist for chrome databases!
// Verify that the child is requesting to access a database it's allowed to
// see. (aASCIIOrigin here specifies a TabContext + a website origin, and
// we're checking that the TabContext may access it.)
if (!aASCIIOrigin.EqualsLiteral("chrome") &&
!IndexedDatabaseManager::TabContextMayAccessOrigin(*this, aASCIIOrigin)) {
// Verify the appID in the origin first.
if (mApp && !aASCIIOrigin.EqualsLiteral("chrome")) {
uint32_t appId;
rv = mApp->GetLocalId(&appId);
NS_ENSURE_SUCCESS(rv, false);
NS_WARNING("App attempted to open databases that it does not have "
"permission to access!");
return false;
if (!IndexedDatabaseManager::OriginMatchesApp(aASCIIOrigin, appId)) {
NS_WARNING("App attempted to open databases that it does not have "
"permission to access!");
return false;
}
}
nsCOMPtr<nsINode> node = do_QueryInterface(GetOwnerElement());
@ -1160,14 +1163,29 @@ TabParent::GetWidget() const
return widget.forget();
}
bool
TabParent::IsForMozBrowser()
{
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
TabParent::UseAsyncPanZoom()
{
bool usingOffMainThreadCompositing = !!CompositorParent::CompositorLoop();
bool asyncPanZoomEnabled =
Preferences::GetBool("layers.async-pan-zoom.enabled", false);
ContentParent* cp = static_cast<ContentParent*>(Manager());
return (usingOffMainThreadCompositing &&
IsBrowserElement() && asyncPanZoomEnabled);
!cp->IsForApp() && IsForMozBrowser() &&
asyncPanZoomEnabled);
}
void

View File

@ -12,7 +12,6 @@
#include "jsapi.h"
#include "mozilla/dom/PBrowserParent.h"
#include "mozilla/dom/PContentDialogParent.h"
#include "mozilla/dom/TabContext.h"
#include "mozilla/ipc/GeckoChildProcessHost.h"
#include "nsCOMPtr.h"
#include "nsIAuthPromptProvider.h"
@ -51,12 +50,11 @@ class TabParent : public PBrowserParent
, public nsITabParent
, public nsIAuthPromptProvider
, public nsISecureBrowserUI
, public TabContext
{
typedef mozilla::dom::ClonedMessageData ClonedMessageData;
public:
TabParent(const TabContext& aContext);
TabParent(mozIApplication* aApp, bool aIsBrowserElement);
virtual ~TabParent();
nsIDOMElement* GetOwnerElement() { return mFrameElement; }
void SetOwnerElement(nsIDOMElement* aElement);
@ -64,6 +62,9 @@ public:
void SetBrowserDOMWindow(nsIBrowserDOMWindow* aBrowserDOMWindow) {
mBrowserDOMWindow = aBrowserDOMWindow;
}
mozIApplication* GetApp() { return mApp; }
bool IsBrowserElement() { return mIsBrowserElement; }
/**
* Return the TabParent that has decided it wants to capture an
@ -261,6 +262,7 @@ protected:
uint64_t* aLayersId) MOZ_OVERRIDE;
virtual bool DeallocPRenderFrame(PRenderFrameParent* aFrame) MOZ_OVERRIDE;
nsCOMPtr<mozIApplication> mApp;
// IME
static TabParent *mIMETabParent;
nsString mIMECacheText;
@ -279,6 +281,7 @@ protected:
nsIntSize mDimensions;
float mDPI;
bool mIsBrowserElement;
bool mShown;
private:
@ -286,7 +289,9 @@ private:
already_AddRefed<nsIWidget> GetWidget() const;
layout::RenderFrameParent* GetRenderFrame();
void TryCacheDPI();
// Return true iff this TabParent was created for a mozbrowser
// frame.
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

@ -196,8 +196,9 @@ gfxAndroidPlatform::FontHintingEnabled()
#else
// Otherwise, enable hinting unless we're in a content process
// that might be used for non-reflowing zoom.
return XRE_GetProcessType() != GeckoProcessType_Content ||
ContentChild::GetSingleton()->HasOwnApp();
return (XRE_GetProcessType() != GeckoProcessType_Content ||
(ContentChild::GetSingleton()->IsForApp() &&
!ContentChild::GetSingleton()->IsForBrowser()));
#endif // MOZ_USING_ANDROID_JAVA_WIDGETS
}

View File

@ -152,9 +152,7 @@
"dom/indexedDB/test/test_event_propagation.html": "TIMED_OUT, bug 780855",
"dom/indexedDB/test/test_app_isolation_inproc.html": "TIMED_OUT",
"dom/indexedDB/test/test_app_isolation_oop.html": "TIMED_OUT",
"dom/indexedDB/test/test_webapp_clearBrowserData_inproc_inproc.html": "No test app installed",
"dom/indexedDB/test/test_webapp_clearBrowserData_inproc_oop.html": "No test app installed",
"dom/indexedDB/test/test_webapp_clearBrowserData_oop_inproc.html": "No test app installed",
"dom/indexedDB/test/test_webapp_clearBrowserData.html": "No test app installed",
"dom/network/tests/test_network_basics.html": "",
"dom/permission/tests/test_permission_basics.html": "",
"dom/sms/tests/test_sms_basics.html": "",

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))) {