mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
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:
parent
9a60759573
commit
f774dcd8ba
@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -8359,7 +8359,7 @@ HasCrossProcessParent(nsIDocument* aDocument)
|
||||
if (!docShell) {
|
||||
return false;
|
||||
}
|
||||
return docShell->GetIsBrowserOrApp();
|
||||
return docShell->GetIsContentBoundary();
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
},
|
||||
|
@ -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
|
||||
|
@ -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':
|
||||
|
@ -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 \
|
||||
|
@ -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);
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
|
137
dom/indexedDB/test/test_webapp_clearBrowserData.html
Normal file
137
dom/indexedDB/test/test_webapp_clearBrowserData.html
Normal 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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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);
|
||||
}
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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&);
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
@ -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
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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": "",
|
||||
|
@ -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))) {
|
||||
|
Loading…
Reference in New Issue
Block a user