зеркало из https://github.com/mozilla/gecko-dev.git
Bug 776649, part 2: Refactor content-process/browser creation to use mozIApplication for passing app info. r=jlebar
This commit is contained in:
Родитель
5fa558d5d4
Коммит
d870f5de82
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include "prenv.h"
|
||||
|
||||
#include "mozIApplication.h"
|
||||
#include "nsIDOMHTMLIFrameElement.h"
|
||||
#include "nsIDOMHTMLFrameElement.h"
|
||||
#include "nsIDOMMozBrowserFrame.h"
|
||||
|
@ -31,6 +32,7 @@
|
|||
#include "nsIDocShellTreeNode.h"
|
||||
#include "nsIDocShellTreeOwner.h"
|
||||
#include "nsIDocShellLoadInfo.h"
|
||||
#include "nsIDOMApplicationRegistry.h"
|
||||
#include "nsIBaseWindow.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIXPConnect.h"
|
||||
|
@ -1973,9 +1975,8 @@ nsFrameLoader::TryRemoteBrowser()
|
|||
return false;
|
||||
}
|
||||
|
||||
PRUint32 appId = 0;
|
||||
bool isBrowserElement = false;
|
||||
|
||||
nsCOMPtr<mozIApplication> app;
|
||||
if (OwnerIsBrowserFrame()) {
|
||||
isBrowserElement = true;
|
||||
|
||||
|
@ -1989,24 +1990,21 @@ nsFrameLoader::TryRemoteBrowser()
|
|||
return false;
|
||||
}
|
||||
|
||||
appsService->GetAppLocalIdByManifestURL(manifest, &appId);
|
||||
|
||||
// If the frame is actually an app, we should not mark it as a browser.
|
||||
if (appId != nsIScriptSecurityManager::NO_APP_ID) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If our owner has no app manifest URL, then this is equivalent to
|
||||
// ContentParent::GetNewOrUsed().
|
||||
nsAutoString appManifest;
|
||||
GetOwnerAppManifestURL(appManifest);
|
||||
ContentParent* parent = ContentParent::GetForApp(appManifest);
|
||||
|
||||
NS_ASSERTION(parent->IsAlive(), "Process parent should be alive; something is very wrong!");
|
||||
mRemoteBrowser = parent->CreateTab(chromeFlags, isBrowserElement, appId);
|
||||
if (mRemoteBrowser) {
|
||||
if ((mRemoteBrowser = ContentParent::CreateBrowser(app, isBrowserElement))) {
|
||||
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(mOwnerContent);
|
||||
mRemoteBrowser->SetOwnerElement(element);
|
||||
|
||||
|
@ -2019,8 +2017,8 @@ nsFrameLoader::TryRemoteBrowser()
|
|||
nsCOMPtr<nsIBrowserDOMWindow> browserDOMWin;
|
||||
rootChromeWin->GetBrowserDOMWindow(getter_AddRefs(browserDOMWin));
|
||||
mRemoteBrowser->SetBrowserDOMWindow(browserDOMWin);
|
||||
|
||||
mChildHost = parent;
|
||||
|
||||
mChildHost = static_cast<ContentParent*>(mRemoteBrowser->Manager());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "nsIObserverService.h"
|
||||
#include "nsTObserverArray.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
@ -402,10 +403,11 @@ ContentChild::AllocPCompositor(mozilla::ipc::Transport* aTransport,
|
|||
|
||||
PBrowserChild*
|
||||
ContentChild::AllocPBrowser(const PRUint32& aChromeFlags,
|
||||
const bool& aIsBrowserElement,
|
||||
const PRUint32& aAppId)
|
||||
const bool& aIsBrowserElement, const AppId& aApp)
|
||||
{
|
||||
nsRefPtr<TabChild> iframe = new TabChild(aChromeFlags, aIsBrowserElement, aAppId);
|
||||
PRUint32 appId = aApp.get_uint32_t();
|
||||
nsRefPtr<TabChild> iframe = new TabChild(aChromeFlags, aIsBrowserElement,
|
||||
appId);
|
||||
return NS_SUCCEEDED(iframe->Init()) ? iframe.forget().get() : NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ public:
|
|||
|
||||
virtual PBrowserChild* AllocPBrowser(const PRUint32& aChromeFlags,
|
||||
const bool& aIsBrowserElement,
|
||||
const PRUint32& aAppId);
|
||||
const AppId& aAppId);
|
||||
virtual bool DeallocPBrowser(PBrowserChild*);
|
||||
|
||||
virtual PDeviceStorageRequestChild* AllocPDeviceStorageRequest(const DeviceStorageParams&);
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "IDBFactory.h"
|
||||
#include "IndexedDBParent.h"
|
||||
#include "IndexedDatabaseManager.h"
|
||||
#include "mozIApplication.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Services.h"
|
||||
|
@ -49,8 +50,10 @@
|
|||
#include "nsFrameMessageManager.h"
|
||||
#include "nsHashPropertyBag.h"
|
||||
#include "nsIAlertsService.h"
|
||||
#include "nsIAppsService.h"
|
||||
#include "nsIClipboard.h"
|
||||
#include "nsIConsoleService.h"
|
||||
#include "nsIDOMApplicationRegistry.h"
|
||||
#include "nsIDOMGeoGeolocation.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsIFilePicker.h"
|
||||
|
@ -59,6 +62,7 @@
|
|||
#include "nsIPresShell.h"
|
||||
#include "nsIRemoteBlob.h"
|
||||
#include "nsIScriptError.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsIWindowWatcher.h"
|
||||
#include "nsMemoryReporterManager.h"
|
||||
|
@ -149,7 +153,7 @@ nsTArray<ContentParent*>* ContentParent::gPrivateContent;
|
|||
// The first content child has ID 1, so the chrome process can have ID 0.
|
||||
static PRUint64 gContentChildID = 1;
|
||||
|
||||
ContentParent*
|
||||
/*static*/ ContentParent*
|
||||
ContentParent::GetNewOrUsed()
|
||||
{
|
||||
if (!gNonAppContentParents)
|
||||
|
@ -165,7 +169,7 @@ ContentParent::GetNewOrUsed()
|
|||
NS_ASSERTION(p->IsAlive(), "Non-alive contentparent in gNonAppContentParents?");
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
nsRefPtr<ContentParent> p =
|
||||
new ContentParent(/* appManifestURL = */ EmptyString());
|
||||
p->Init();
|
||||
|
@ -173,11 +177,20 @@ ContentParent::GetNewOrUsed()
|
|||
return p;
|
||||
}
|
||||
|
||||
ContentParent*
|
||||
ContentParent::GetForApp(const nsAString& aAppManifestURL)
|
||||
/*static*/ TabParent*
|
||||
ContentParent::CreateBrowser(mozIApplication* aApp, bool aIsBrowserElement)
|
||||
{
|
||||
if (aAppManifestURL.IsEmpty()) {
|
||||
return GetNewOrUsed();
|
||||
if (!aApp) {
|
||||
if (ContentParent* cp = GetNewOrUsed()) {
|
||||
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 (!gAppContentParents) {
|
||||
|
@ -187,14 +200,39 @@ ContentParent::GetForApp(const nsAString& aAppManifestURL)
|
|||
}
|
||||
|
||||
// Each app gets its own ContentParent instance.
|
||||
ContentParent* p = gAppContentParents->Get(aAppManifestURL);
|
||||
if (!p) {
|
||||
p = new ContentParent(aAppManifestURL);
|
||||
p->Init();
|
||||
gAppContentParents->Put(aAppManifestURL, p);
|
||||
nsAutoString manifestURL;
|
||||
if (NS_FAILED(aApp->GetManifestURL(manifestURL))) {
|
||||
NS_ERROR("Failed to get manifest URL");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return p;
|
||||
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.
|
||||
PRUint32 appId;
|
||||
if (NS_FAILED(appsService->GetAppLocalIdByManifestURL(manifestURL, &appId))) {
|
||||
NS_ERROR("Failed to get local app ID");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ContentParent* p = gAppContentParents->Get(manifestURL);
|
||||
if (!p) {
|
||||
p = new ContentParent(manifestURL);
|
||||
p->Init();
|
||||
gAppContentParents->Put(manifestURL, p);
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -455,12 +493,6 @@ ContentParent::ActorDestroy(ActorDestroyReason why)
|
|||
NS_DispatchToCurrentThread(new DelayedDeleteContentParentTask(this));
|
||||
}
|
||||
|
||||
TabParent*
|
||||
ContentParent::CreateTab(PRUint32 aChromeFlags, bool aIsBrowserElement, PRUint32 aAppId)
|
||||
{
|
||||
return static_cast<TabParent*>(SendPBrowserConstructor(aChromeFlags, aIsBrowserElement, aAppId));
|
||||
}
|
||||
|
||||
void
|
||||
ContentParent::NotifyTabDestroyed(PBrowserParent* aTab)
|
||||
{
|
||||
|
@ -862,22 +894,40 @@ ContentParent::AllocPCompositor(mozilla::ipc::Transport* aTransport,
|
|||
|
||||
PBrowserParent*
|
||||
ContentParent::AllocPBrowser(const PRUint32& aChromeFlags,
|
||||
const bool& aIsBrowserElement,
|
||||
const PRUint32& aAppId)
|
||||
const bool& aIsBrowserElement, const AppId& aApp)
|
||||
{
|
||||
TabParent* parent = new TabParent();
|
||||
if (parent){
|
||||
// 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());
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
TabParent* parent = new TabParent(opener ? opener->GetApp() : nullptr,
|
||||
aIsBrowserElement);
|
||||
// We release this ref in DeallocPBrowser()
|
||||
NS_ADDREF(parent);
|
||||
}
|
||||
return parent;
|
||||
return parent;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::DeallocPBrowser(PBrowserParent* frame)
|
||||
{
|
||||
TabParent* parent = static_cast<TabParent*>(frame);
|
||||
NS_RELEASE(parent);
|
||||
return true;
|
||||
TabParent* parent = static_cast<TabParent*>(frame);
|
||||
NS_RELEASE(parent);
|
||||
return true;
|
||||
}
|
||||
|
||||
PDeviceStorageRequestParent*
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "nsInterfaceHashtable.h"
|
||||
#include "nsHashKeys.h"
|
||||
|
||||
class mozIApplication;
|
||||
class nsFrameMessageManager;
|
||||
class nsIDOMBlob;
|
||||
|
||||
|
@ -60,13 +61,16 @@ public:
|
|||
static ContentParent* GetNewOrUsed();
|
||||
|
||||
/**
|
||||
* Get or create a content process for the given app. A given app
|
||||
* (identified by its manifest URL) gets one process all to itself.
|
||||
* 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.
|
||||
*
|
||||
* If the given manifest is the empty string, then this method is equivalent
|
||||
* to GetNewOrUsed().
|
||||
* Currently apps are given their own process, and browser tabs
|
||||
* share processes.
|
||||
*/
|
||||
static ContentParent* GetForApp(const nsAString& aManifestURL);
|
||||
static TabParent* CreateBrowser(mozIApplication* aApp,
|
||||
bool aIsBrowserFrame);
|
||||
|
||||
static void GetAll(nsTArray<ContentParent*>& aArray);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -74,14 +78,6 @@ public:
|
|||
NS_DECL_NSITHREADOBSERVER
|
||||
NS_DECL_NSIDOMGEOPOSITIONCALLBACK
|
||||
|
||||
/**
|
||||
* Create a new tab.
|
||||
*
|
||||
* |aIsBrowserElement| indicates whether this tab is part of an
|
||||
* <iframe mozbrowser>.
|
||||
* |aAppId| indicates which app the tab belongs to.
|
||||
*/
|
||||
TabParent* CreateTab(PRUint32 aChromeFlags, bool aIsBrowserElement, PRUint32 aAppId);
|
||||
/** Notify that a tab was destroyed during normal operation. */
|
||||
void NotifyTabDestroyed(PBrowserParent* aTab);
|
||||
|
||||
|
@ -143,7 +139,9 @@ private:
|
|||
PCompositorParent* AllocPCompositor(mozilla::ipc::Transport* aTransport,
|
||||
base::ProcessId aOtherProcess) MOZ_OVERRIDE;
|
||||
|
||||
virtual PBrowserParent* AllocPBrowser(const PRUint32& aChromeFlags, const bool& aIsBrowserElement, const PRUint32& aAppId);
|
||||
virtual PBrowserParent* AllocPBrowser(const PRUint32& aChromeFlags,
|
||||
const bool& aIsBrowserElement,
|
||||
const AppId& aApp);
|
||||
virtual bool DeallocPBrowser(PBrowserParent* frame);
|
||||
|
||||
virtual PDeviceStorageRequestParent* AllocPDeviceStorageRequest(const DeviceStorageParams&);
|
||||
|
|
|
@ -122,6 +122,11 @@ union BlobConstructorParams
|
|||
MysteryBlobConstructorParams;
|
||||
};
|
||||
|
||||
union AppId {
|
||||
uint32_t;
|
||||
nullable PBrowser;
|
||||
};
|
||||
|
||||
rpc protocol PContent
|
||||
{
|
||||
parent opens PCompositor;
|
||||
|
@ -145,9 +150,16 @@ both:
|
|||
// created from either the child or parent process!
|
||||
//
|
||||
// The child creates the PBrowser as part of
|
||||
// TabChild::BrowserFrameProvideWindow, and the parent creates the PBrowser
|
||||
// as part of ContentParent::CreateTab.
|
||||
async PBrowser(PRUint32 chromeFlags, bool isBrowserElement, PRUint32 appId);
|
||||
// TabChild::BrowserFrameProvideWindow, and the parent creates the
|
||||
// PBrowser as part of ContentParent::CreateTab.
|
||||
//
|
||||
// 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(PRUint32 chromeFlags, bool isBrowserElement, AppId appId);
|
||||
|
||||
async PBlob(BlobConstructorParams params);
|
||||
|
||||
|
|
|
@ -422,10 +422,13 @@ TabChild::BrowserFrameProvideWindow(nsIDOMWindow* aOpener,
|
|||
{
|
||||
*aReturn = nullptr;
|
||||
|
||||
nsRefPtr<TabChild> newChild =
|
||||
static_cast<TabChild*>(Manager()->SendPBrowserConstructor(
|
||||
/* aChromeFlags = */ 0, mIsBrowserElement, mAppId));
|
||||
|
||||
PRUint32 chromeFlags = 0;
|
||||
nsRefPtr<TabChild> newChild = new TabChild(chromeFlags,
|
||||
mIsBrowserElement, mAppId);
|
||||
static_cast<TabChild*>(Manager()->SendPBrowserConstructor(
|
||||
// We release this ref in DeallocPBrowserChild
|
||||
nsRefPtr<TabChild>(newChild).forget().get(),
|
||||
chromeFlags, mIsBrowserElement, this));
|
||||
nsCAutoString spec;
|
||||
if (aURI) {
|
||||
aURI->GetSpec(spec);
|
||||
|
|
|
@ -158,6 +158,8 @@ public:
|
|||
virtual ~TabChild();
|
||||
nsresult Init();
|
||||
|
||||
PRUint32 GetAppId() { return mAppId; }
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIWEBBROWSERCHROME
|
||||
NS_DECL_NSIWEBBROWSERCHROME2
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "Blob.h"
|
||||
#include "IDBFactory.h"
|
||||
#include "IndexedDBParent.h"
|
||||
#include "mozIApplication.h"
|
||||
#include "mozilla/BrowserElementParent.h"
|
||||
#include "mozilla/docshell/OfflineCacheUpdateParent.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
|
@ -27,6 +28,7 @@
|
|||
#include "nsFocusManager.h"
|
||||
#include "nsFrameLoader.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDOMApplicationRegistry.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMEvent.h"
|
||||
#include "nsIDOMEventTarget.h"
|
||||
|
@ -36,6 +38,7 @@
|
|||
#include "nsIPromptFactory.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIMozBrowserFrame.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsIViewManager.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsIWindowWatcher.h"
|
||||
|
@ -52,6 +55,7 @@ using namespace mozilla::dom;
|
|||
using namespace mozilla::ipc;
|
||||
using namespace mozilla::layers;
|
||||
using namespace mozilla::layout;
|
||||
using namespace mozilla::services;
|
||||
using namespace mozilla::widget;
|
||||
using namespace mozilla::dom::indexedDB;
|
||||
|
||||
|
@ -66,8 +70,9 @@ TabParent *TabParent::mIMETabParent = nullptr;
|
|||
|
||||
NS_IMPL_ISUPPORTS3(TabParent, nsITabParent, nsIAuthPromptProvider, nsISecureBrowserUI)
|
||||
|
||||
TabParent::TabParent()
|
||||
TabParent::TabParent(mozIApplication* aApp, bool aIsBrowserElement)
|
||||
: mFrameElement(NULL)
|
||||
, mApp(aApp)
|
||||
, mIMESelectionAnchor(0)
|
||||
, mIMESelectionFocus(0)
|
||||
, mIMEComposing(false)
|
||||
|
@ -76,6 +81,7 @@ TabParent::TabParent()
|
|||
, mIMESeqno(0)
|
||||
, mDPI(0)
|
||||
, mActive(false)
|
||||
, mIsBrowserElement(aIsBrowserElement)
|
||||
, mShown(false)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
struct gfxMatrix;
|
||||
struct JSContext;
|
||||
struct JSObject;
|
||||
class mozIApplication;
|
||||
class nsFrameLoader;
|
||||
class nsIDOMElement;
|
||||
class nsIURI;
|
||||
|
@ -53,7 +54,7 @@ class TabParent : public PBrowserParent
|
|||
typedef mozilla::dom::ClonedMessageData ClonedMessageData;
|
||||
|
||||
public:
|
||||
TabParent();
|
||||
TabParent(mozIApplication* aApp, bool aIsBrowserElement);
|
||||
virtual ~TabParent();
|
||||
nsIDOMElement* GetOwnerElement() { return mFrameElement; }
|
||||
void SetOwnerElement(nsIDOMElement* aElement);
|
||||
|
@ -62,6 +63,9 @@ public:
|
|||
mBrowserDOMWindow = aBrowserDOMWindow;
|
||||
}
|
||||
|
||||
mozIApplication* GetApp() { return mApp; }
|
||||
bool IsBrowserElement() { return mIsBrowserElement; }
|
||||
|
||||
void Destroy();
|
||||
|
||||
virtual bool RecvMoveFocus(const bool& aForward);
|
||||
|
@ -225,6 +229,7 @@ protected:
|
|||
uint64_t* aLayersId) MOZ_OVERRIDE;
|
||||
virtual bool DeallocPRenderFrame(PRenderFrameParent* aFrame) MOZ_OVERRIDE;
|
||||
|
||||
nsCOMPtr<mozIApplication> mApp;
|
||||
// IME
|
||||
static TabParent *mIMETabParent;
|
||||
nsString mIMECacheText;
|
||||
|
@ -240,6 +245,7 @@ protected:
|
|||
|
||||
float mDPI;
|
||||
bool mActive;
|
||||
bool mIsBrowserElement;
|
||||
bool mShown;
|
||||
|
||||
private:
|
||||
|
|
Загрузка…
Ссылка в новой задаче