Land the remote-tab code from tmp-electrolysis.

This commit is contained in:
Benjamin Smedberg 2009-06-30 16:39:22 -04:00
Родитель 40fee97f07
Коммит 9759711d04
25 изменённых файлов: 1222 добавлений и 3 удалений

Просмотреть файл

@ -183,6 +183,8 @@ FORCE_STATIC_LIB = 1
EXTRA_COMPONENTS = $(srcdir)/nsBadCertHandler.js EXTRA_COMPONENTS = $(srcdir)/nsBadCertHandler.js
include $(topsrcdir)/config/config.mk
include $(topsrcdir)/ipc/chromium/chromium-config.mk
include $(topsrcdir)/config/rules.mk include $(topsrcdir)/config/rules.mk
INCLUDES += \ INCLUDES += \
@ -198,6 +200,7 @@ INCLUDES += \
-I$(srcdir)/../../../dom/base \ -I$(srcdir)/../../../dom/base \
-I$(srcdir)/../../xml/document/src \ -I$(srcdir)/../../xml/document/src \
-I$(topsrcdir)/xpcom/io \ -I$(topsrcdir)/xpcom/io \
-I$(topsrcdir)/dom/ipc \
$(NULL) $(NULL)
DEFINES += -D_IMPL_NS_LAYOUT DEFINES += -D_IMPL_NS_LAYOUT

Просмотреть файл

@ -83,6 +83,17 @@
#include "nsINameSpaceManager.h" #include "nsINameSpaceManager.h"
#include "nsThreadUtils.h" #include "nsThreadUtils.h"
#include "nsIView.h"
#include "TabParent.h"
#include "mozcontainer.h"
#include <gdk/gdkx.h>
#include <gtk/gtk.h>
using namespace mozilla;
using namespace mozilla::tabs;
class nsAsyncDocShellDestroyer : public nsRunnable class nsAsyncDocShellDestroyer : public nsRunnable
{ {
@ -193,6 +204,18 @@ nsresult
nsFrameLoader::ReallyStartLoading() nsFrameLoader::ReallyStartLoading()
{ {
NS_ENSURE_STATE(mURIToLoad && mOwnerContent && mOwnerContent->IsInDoc()); NS_ENSURE_STATE(mURIToLoad && mOwnerContent && mOwnerContent->IsInDoc());
if (!mTriedNewProcess) {
TryNewProcess();
mTriedNewProcess = PR_TRUE;
}
if (mChildProcess) {
// FIXME get error codes from child
mChildProcess->LoadURL(mURIToLoad);
return NS_OK;
}
// Just to be safe, recheck uri. // Just to be safe, recheck uri.
nsresult rv = CheckURILoad(mURIToLoad); nsresult rv = CheckURILoad(mURIToLoad);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
@ -1007,3 +1030,103 @@ nsFrameLoader::CheckForRecursiveLoad(nsIURI* aURI)
return NS_OK; return NS_OK;
} }
PRBool
nsFrameLoader::TryNewProcess()
{
nsIDocument* doc = mOwnerContent->GetDocument();
if (!doc) {
return NS_ERROR_UNEXPECTED;
}
if (doc->GetDisplayDocument()) {
// Don't allow subframe loads in external reference documents
return NS_ERROR_NOT_AVAILABLE;
}
nsCOMPtr<nsIWebNavigation> parentAsWebNav =
do_GetInterface(doc->GetScriptGlobalObject());
if (!parentAsWebNav) {
return PR_FALSE;
}
nsCOMPtr<nsIDocShellTreeItem> parentAsItem(do_QueryInterface(parentAsWebNav));
PRInt32 parentType;
parentAsItem->GetItemType(&parentType);
if (parentType != nsIDocShellTreeItem::typeChrome) {
return PR_FALSE;
}
if (!mOwnerContent->IsNodeOfType(nsINode::eXUL)) {
return PR_FALSE;
}
NS_ERROR("trying to start new process");
nsAutoString value;
mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::type, value);
if (!value.LowerCaseEqualsLiteral("content") &&
!StringBeginsWith(value, NS_LITERAL_STRING("content-"),
nsCaseInsensitiveStringComparator())) {
return PR_FALSE;
}
// FIXME shouldn't need to launch a new process every time get here
// XXXnasty hack get our (parent) widget
doc->FlushPendingNotifications(Flush_Layout);
nsIFrame* ourFrame =
doc->GetPrimaryShell()->GetPrimaryFrameFor(mOwnerContent);
nsIView* ancestorView = ourFrame->GetView();
nsIView* firstChild = ancestorView->GetFirstChild();
if (!firstChild) {
NS_ERROR("no first child");
return PR_FALSE;
}
nsIWidget* w = firstChild->GetWidget();
if (!w) {
NS_ERROR("we're stuffed!");
return PR_FALSE;
}
// FIXME check that this widget has the size and position we expect for
// this iframe?
GdkWindow* parent_win =
static_cast<GdkWindow*>(w->GetNativeData(NS_NATIVE_WINDOW));
gpointer user_data = nsnull;
gdk_window_get_user_data(parent_win, &user_data);
MozContainer* parentMozContainer = MOZ_CONTAINER(user_data);
GtkContainer* container = GTK_CONTAINER(parentMozContainer);
// create the widget for the child and add it to the parent's window
GtkWidget* socket = gtk_socket_new();
gtk_widget_set_parent_window(socket, parent_win);
gtk_container_add(container, socket);
gtk_widget_realize(socket);
// set the child window's size and position
nsPresContext* presContext = ourFrame->PresContext();
GtkAllocation alloc;
alloc.x = 0; // setting position doesn't look necessary
alloc.y = 0;
alloc.width = presContext->AppUnitsToDevPixels(ourFrame->GetSize().width);
alloc.height = presContext->AppUnitsToDevPixels(ourFrame->GetSize().height);
gtk_widget_size_allocate(socket, &alloc);
gtk_widget_show(socket);
GdkNativeWindow id = gtk_socket_get_id((GtkSocket*)socket);
mChildProcess = new TabParent(id);
mChildProcess->Move(0, 0, alloc.width, alloc.height);
return PR_TRUE;
}

Просмотреть файл

@ -48,9 +48,15 @@
#include "nsStringFwd.h" #include "nsStringFwd.h"
#include "nsIFrameLoader.h" #include "nsIFrameLoader.h"
#include "nsIURI.h" #include "nsIURI.h"
#include "nsAutoPtr.h"
class nsIContent; class nsIContent;
class nsIURI; class nsIURI;
namespace mozilla {
namespace tabs {
class TabParent;
}
}
class nsFrameLoader : public nsIFrameLoader class nsFrameLoader : public nsIFrameLoader
{ {
@ -61,7 +67,9 @@ public:
mIsTopLevelContent(PR_FALSE), mIsTopLevelContent(PR_FALSE),
mDestroyCalled(PR_FALSE), mDestroyCalled(PR_FALSE),
mNeedsAsyncDestroy(PR_FALSE), mNeedsAsyncDestroy(PR_FALSE),
mInSwap(PR_FALSE) mInSwap(PR_FALSE),
mChildProcess(nsnull),
mTriedNewProcess(PR_FALSE)
{} {}
~nsFrameLoader() { ~nsFrameLoader() {
@ -89,6 +97,9 @@ private:
NS_HIDDEN_(void) GetURL(nsString& aURL); NS_HIDDEN_(void) GetURL(nsString& aURL);
nsresult CheckURILoad(nsIURI* aURI); nsresult CheckURILoad(nsIURI* aURI);
// True means new process started; nothing else to do
PRBool TryNewProcess();
nsCOMPtr<nsIDocShell> mDocShell; nsCOMPtr<nsIDocShell> mDocShell;
nsCOMPtr<nsIURI> mURIToLoad; nsCOMPtr<nsIURI> mURIToLoad;
nsIContent *mOwnerContent; // WEAK nsIContent *mOwnerContent; // WEAK
@ -97,6 +108,10 @@ private:
PRPackedBool mDestroyCalled : 1; PRPackedBool mDestroyCalled : 1;
PRPackedBool mNeedsAsyncDestroy : 1; PRPackedBool mNeedsAsyncDestroy : 1;
PRPackedBool mInSwap : 1; PRPackedBool mInSwap : 1;
// XXX leaking
mozilla::tabs::TabParent* mChildProcess;
PRBool mTriedNewProcess;
}; };
#endif #endif

Просмотреть файл

@ -9845,10 +9845,13 @@ nsDocShell::EnsureScriptEnvironment()
NS_ENSURE_TRUE(factory, NS_ERROR_FAILURE); NS_ENSURE_TRUE(factory, NS_ERROR_FAILURE);
nsCOMPtr<nsIWebBrowserChrome> browserChrome(do_GetInterface(mTreeOwner)); nsCOMPtr<nsIWebBrowserChrome> browserChrome(do_GetInterface(mTreeOwner));
NS_ENSURE_TRUE(browserChrome, NS_ERROR_NOT_AVAILABLE);
PRUint32 chromeFlags; PRUint32 chromeFlags;
if (browserChrome) {
browserChrome->GetChromeFlags(&chromeFlags); browserChrome->GetChromeFlags(&chromeFlags);
} else {
chromeFlags = 0;
}
PRBool isModalContentWindow = PRBool isModalContentWindow =
(chromeFlags & nsIWebBrowserChrome::CHROME_MODAL) && (chromeFlags & nsIWebBrowserChrome::CHROME_MODAL) &&

Просмотреть файл

@ -84,6 +84,7 @@ DIRS += \
ifdef MOZ_IPC ifdef MOZ_IPC
DIRS += \ DIRS += \
plugins \ plugins \
ipc \
$(NULL) $(NULL)
endif endif

Просмотреть файл

@ -0,0 +1,13 @@
using MagicWindowHandle;
rpc protocol IFrameEmbedding
{
rpc out init(MagicWindowHandle parentWidget);
rpc out loadURL(String uri);
rpc out move(uint32_t x,
uint32_t y,
uint32_t width,
uint32_t height);
};

Просмотреть файл

@ -0,0 +1,150 @@
//
// Automatically generated by ipdlc.
// Edit at your own risk.
//
#ifndef IFrameEmbeddingProtocol_h
#define IFrameEmbeddingProtocol_h
#include "nscore.h"
#include "IPC/IPCMessageUtils.h"
#include "mozilla/ipc/MessageTypes.h"
typedef mozilla::ipc::String String;
typedef mozilla::ipc::StringArray StringArray;
class NS_FINAL_CLASS IFrameEmbeddingProtocol
{
public:
/*interface*/ class Parent
{
public:
protected:
Parent() { }
virtual ~Parent() { }
Parent(const Parent&);
Parent& operator=(const Parent&);
};
/*interface*/ class Child
{
public:
virtual nsresult init(
const MagicWindowHandle& parentWidget) = 0;
virtual nsresult loadURL(
const String& uri) = 0;
virtual nsresult move(
const uint32_t& x, const uint32_t& y, const uint32_t& width, const uint32_t& height) = 0;
protected:
Child() { }
virtual ~Child() { }
Child(const Child&);
Child& operator=(const Child&);
};
enum State { };
private:
IFrameEmbeddingProtocol();
virtual ~IFrameEmbeddingProtocol() = 0;
};
// Parent->child messages
enum IFrameEmbedding_ParentToChildMsgType {
IFrameEmbedding_ParentToChildStart = IFrameEmbedding_ParentToChildMsgStart << 12,
IFrameEmbedding_ParentToChildPreStart = (IFrameEmbedding_ParentToChildMsgStart << 12) - 1,
IFrameEmbedding_ParentToChildMsg_init__ID,
IFrameEmbedding_ParentToChildMsg_loadURL__ID,
IFrameEmbedding_ParentToChildMsg_move__ID,
IFrameEmbedding_ParentToChildEnd
};
class IFrameEmbedding_ParentToChildMsg_init :
public IPC::MessageWithTuple<MagicWindowHandle>
{
public:
enum { ID = IFrameEmbedding_ParentToChildMsg_init__ID };
IFrameEmbedding_ParentToChildMsg_init(
const MagicWindowHandle& parentWidget) :
IPC::MessageWithTuple<MagicWindowHandle>(
MSG_ROUTING_CONTROL, ID,
parentWidget)
{ }
};
class IFrameEmbedding_ParentToChildMsg_loadURL :
public IPC::MessageWithTuple<String>
{
public:
enum { ID = IFrameEmbedding_ParentToChildMsg_loadURL__ID };
IFrameEmbedding_ParentToChildMsg_loadURL(
const String& uri) :
IPC::MessageWithTuple<String>(
MSG_ROUTING_CONTROL, ID,
uri)
{ }
};
class IFrameEmbedding_ParentToChildMsg_move :
public IPC::MessageWithTuple< Tuple4 <
uint32_t, uint32_t, uint32_t, uint32_t> >
{
public:
enum { ID = IFrameEmbedding_ParentToChildMsg_move__ID };
IFrameEmbedding_ParentToChildMsg_move(
const uint32_t& x, const uint32_t& y, const uint32_t& width, const uint32_t& height) :
IPC::MessageWithTuple< Tuple4 <
uint32_t, uint32_t, uint32_t, uint32_t> >(
MSG_ROUTING_CONTROL, ID,
MakeTuple(
x, y, width, height))
{ }
};
// Child->parent messages
enum IFrameEmbedding_ChildToParentMsgType {
IFrameEmbedding_ChildToParentStart = IFrameEmbedding_ChildToParentMsgStart << 12,
IFrameEmbedding_ChildToParentPreStart = (IFrameEmbedding_ChildToParentMsgStart << 12) - 1,
IFrameEmbedding_ChildToParentMsg_Reply_init__ID,
IFrameEmbedding_ChildToParentMsg_Reply_loadURL__ID,
IFrameEmbedding_ChildToParentMsg_Reply_move__ID,
IFrameEmbedding_ChildToParentEnd
};
class IFrameEmbedding_ChildToParentMsg_Reply_init :
public IPC::Message
{
public:
enum { ID = IFrameEmbedding_ChildToParentMsg_Reply_init__ID };
IFrameEmbedding_ChildToParentMsg_Reply_init() :
IPC::Message(MSG_ROUTING_CONTROL, ID, PRIORITY_NORMAL)
{ }
};
class IFrameEmbedding_ChildToParentMsg_Reply_loadURL :
public IPC::Message
{
public:
enum { ID = IFrameEmbedding_ChildToParentMsg_Reply_loadURL__ID };
IFrameEmbedding_ChildToParentMsg_Reply_loadURL() :
IPC::Message(MSG_ROUTING_CONTROL, ID, PRIORITY_NORMAL)
{ }
};
class IFrameEmbedding_ChildToParentMsg_Reply_move :
public IPC::Message
{
public:
enum { ID = IFrameEmbedding_ChildToParentMsg_Reply_move__ID };
IFrameEmbedding_ChildToParentMsg_Reply_move() :
IPC::Message(MSG_ROUTING_CONTROL, ID, PRIORITY_NORMAL)
{ }
};
#endif // ifndef IFrameEmbeddingProtocol_h

Просмотреть файл

@ -0,0 +1,88 @@
//
// Automatically generated by ipdlc.
// Edit at your own risk.
//
#include "IFrameEmbeddingProtocol.h"
#include "mozilla/ipc/RPCChannel.h"
using mozilla::ipc::RPCChannel;
using IPC::Message;
class NS_FINAL_CLASS IFrameEmbeddingProtocolChild :
public IFrameEmbeddingProtocol::Parent,
public RPCChannel::Listener
{
public:
IFrameEmbeddingProtocolChild(IFrameEmbeddingProtocol::Child* aChild) :
mChild(aChild),
mRpc(this)
{ }
bool Open(IPC::Channel* aChannel, MessageLoop* aIOLoop)
{
return mRpc.Open(aChannel, aIOLoop);
}
void Close()
{
mRpc.Close();
}
virtual Result OnCallReceived(const Message& msg, Message** reply)
{
switch (msg.type()) {
case IFrameEmbedding_ParentToChildMsg_init__ID: {
MagicWindowHandle parentWidget;
MagicWindowHandle p;
IFrameEmbedding_ParentToChildMsg_init::Read(&msg, &p);
parentWidget = p;
nsresult _rv = mChild->init(
parentWidget);
*reply = new IFrameEmbedding_ChildToParentMsg_Reply_init();
(*reply)->set_reply();
return MsgProcessed;
}
case IFrameEmbedding_ParentToChildMsg_loadURL__ID: {
String uri;
String p;
IFrameEmbedding_ParentToChildMsg_loadURL::Read(&msg, &p);
uri = p;
nsresult _rv = mChild->loadURL(
uri);
*reply = new IFrameEmbedding_ChildToParentMsg_Reply_loadURL();
(*reply)->set_reply();
return MsgProcessed;
}
case IFrameEmbedding_ParentToChildMsg_move__ID: {
uint32_t x;
uint32_t y;
uint32_t width;
uint32_t height;
IFrameEmbedding_ParentToChildMsg_move::Param p;
IFrameEmbedding_ParentToChildMsg_move::Read(&msg, &p);
x = p.a;
y = p.b;
width = p.c;
height = p.d;
nsresult _rv = mChild->move(
x, y, width, height);
*reply = new IFrameEmbedding_ChildToParentMsg_Reply_move();
(*reply)->set_reply();
return MsgProcessed;
}
default: {
return MsgNotKnown;
}
}
}
private:
IFrameEmbeddingProtocol::Child* mChild;
RPCChannel mRpc;
};

Просмотреть файл

@ -0,0 +1,82 @@
//
// Automatically generated by ipdlc.
// Edit at your own risk.
//
#include "IFrameEmbeddingProtocol.h"
#include "mozilla/ipc/RPCChannel.h"
using mozilla::ipc::RPCChannel;
using IPC::Message;
class NS_FINAL_CLASS IFrameEmbeddingProtocolParent :
public IFrameEmbeddingProtocol::Child,
public RPCChannel::Listener
{
public:
IFrameEmbeddingProtocolParent(IFrameEmbeddingProtocol::Parent* aParent) :
mParent(aParent),
mRpc(this)
{ }
bool Open(IPC::Channel* aChannel)
{
return mRpc.Open(aChannel);
}
void Close()
{
mRpc.Close();
}
virtual nsresult init(
const MagicWindowHandle& parentWidget)
{
Message reply;
nsresult _rv = mRpc.Call(new IFrameEmbedding_ParentToChildMsg_init(
parentWidget)
, &reply);
if (NS_OK == _rv) {
}
return _rv;
}
virtual nsresult loadURL(
const String& uri)
{
Message reply;
nsresult _rv = mRpc.Call(new IFrameEmbedding_ParentToChildMsg_loadURL(
uri)
, &reply);
if (NS_OK == _rv) {
}
return _rv;
}
virtual nsresult move(
const uint32_t& x, const uint32_t& y, const uint32_t& width, const uint32_t& height)
{
Message reply;
nsresult _rv = mRpc.Call(new IFrameEmbedding_ParentToChildMsg_move(
x, y, width, height)
, &reply);
if (NS_OK == _rv) {
}
return _rv;
}
virtual Result OnCallReceived(const Message& msg, Message** reply)
{
switch (msg.type()) {
default: {
return MsgNotKnown;
}
}
}
private:
IFrameEmbeddingProtocol::Parent* mParent;
RPCChannel mRpc;
};

27
dom/ipc/Makefile.in Normal file
Просмотреть файл

@ -0,0 +1,27 @@
DEPTH = ../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = dom
LIBRARY_NAME = domipc_s
LIBXUL_LIBRARY = 1
FORCE_STATIC_LIB = 1
EXPORT_LIBRARY = 1
CPPSRCS = \
TabParent.cpp \
TabProcessParent.cpp \
TabChild.cpp \
TabThread.cpp \
$(NULL)
TOOL_DIRS = app
include $(topsrcdir)/config/config.mk
include $(topsrcdir)/ipc/chromium/chromium-config.mk
include $(topsrcdir)/config/rules.mk
DEFINES += -DBIN_SUFFIX='"$(BIN_SUFFIX)"'

84
dom/ipc/TabChild.cpp Normal file
Просмотреть файл

@ -0,0 +1,84 @@
/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8; -*- */
#include "TabChild.h"
#include "nsIWebBrowser.h"
#include "nsEmbedCID.h"
#include "nsComponentManagerUtils.h"
#include "nsIBaseWindow.h"
#include "nsIDocShellTreeItem.h"
#include "nsThreadUtils.h"
#include <gdk/gdkx.h>
#include <gtk/gtk.h>
using namespace mozilla::tabs;
TabChild::TabChild()
: mWidget(0)
, mChild(this)
{
}
TabChild::~TabChild()
{
// TODObsmedberg: destroy the window!
}
bool
TabChild::Init(MessageLoop* aIOLoop, IPC::Channel* aChannel)
{
mChild.Open(aChannel, aIOLoop);
return true;
}
nsresult
TabChild::init(const MagicWindowHandle& parentWidget)
{
printf("creating %d!\n", NS_IsMainThread());
gtk_init(NULL, NULL);
nsCOMPtr<nsIWebBrowser> webBrowser(do_CreateInstance(NS_WEBBROWSER_CONTRACTID));
nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(webBrowser);
GtkWidget* win = gtk_plug_new((GdkNativeWindow)parentWidget);
gtk_widget_show(win);
baseWindow->InitWindow(win, 0, 0, 0, 0, 0);
nsCOMPtr<nsIDocShellTreeItem> docShellItem(do_QueryInterface(baseWindow));
docShellItem->SetItemType(nsIDocShellTreeItem::typeContentWrapper);
baseWindow->Create();
baseWindow->SetVisibility(PR_TRUE);
mWebNav = do_QueryInterface(webBrowser);
// TODObz: create and embed a window!
return NS_ERROR_NOT_IMPLEMENTED;
}
nsresult
TabChild::loadURL(const String& uri)
{
printf("loading %s, %d\n", uri.c_str(), NS_IsMainThread());
return mWebNav->LoadURI(NS_ConvertUTF8toUTF16(uri.c_str()).get(),
nsIWebNavigation::LOAD_FLAGS_NONE,
NULL, NULL, NULL);
}
nsresult
TabChild::move(const uint32_t& x,
const uint32_t& y,
const uint32_t& width,
const uint32_t& height)
{
printf("[TabChild] MOVE to (x,y)=(%ud, %ud), (w,h)= (%ud, %ud)\n",
x, y, width, height);
nsCOMPtr<nsIBaseWindow> baseWin = do_QueryInterface(mWebNav);
baseWin->SetPositionAndSize(x, y, width, height, PR_TRUE);
return NS_OK;
}

45
dom/ipc/TabChild.h Normal file
Просмотреть файл

@ -0,0 +1,45 @@
/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8; -*- */
#ifndef mozilla_tabs_TabChild_h
#define mozilla_tabs_TabChild_h
#include "TabTypes.h"
#include "IFrameEmbeddingProtocol.h"
#include "IFrameEmbeddingProtocolChild.h"
#include "nsIWebNavigation.h"
#include "nsCOMPtr.h"
namespace mozilla {
namespace tabs {
class TabChild
: public IFrameEmbeddingProtocol::Child
{
private:
typedef mozilla::ipc::String String;
public:
TabChild();
virtual ~TabChild();
bool Init(MessageLoop* aIOLoop, IPC::Channel* aChannel);
virtual nsresult init(const MagicWindowHandle& parentWidget);
virtual nsresult loadURL(const String& uri);
virtual nsresult move(const uint32_t& x,
const uint32_t& y,
const uint32_t& width,
const uint32_t& height);
private:
MagicWindowHandle mWidget;
IFrameEmbeddingProtocolChild mChild;
nsCOMPtr<nsIWebNavigation> mWebNav;
DISALLOW_EVIL_CONSTRUCTORS(TabChild);
};
}
}
#endif // mozilla_tabs_TabChild_h

64
dom/ipc/TabParent.cpp Normal file
Просмотреть файл

@ -0,0 +1,64 @@
#include "TabParent.h"
#include "mozilla/ipc/GeckoThread.h"
#include "nsIURI.h"
using mozilla::ipc::BrowserProcessSubThread;
template<>
struct RunnableMethodTraits<mozilla::tabs::TabParent>
{
static void RetainCallee(mozilla::tabs::TabParent* obj) { }
static void ReleaseCallee(mozilla::tabs::TabParent* obj) { }
};
namespace mozilla {
namespace tabs {
TabParent::TabParent(MagicWindowHandle parentWidget)
: mSubprocess()
, mParent(this)
, mMonitor("mozilla.dom.ipc.TabParent")
{
{
MonitorAutoEnter mon(mMonitor);
BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)->
PostTask(FROM_HERE, NewRunnableMethod(this, &TabParent::LaunchSubprocess));
mon.Wait();
}
mParent.Open(mSubprocess.GetChannel());
mParent.init(parentWidget);
}
TabParent::~TabParent()
{
}
void
TabParent::LaunchSubprocess()
{
MonitorAutoEnter mon(mMonitor);
mSubprocess.Launch();
mon.Notify();
}
void
TabParent::LoadURL(nsIURI* aURI)
{
nsCString spec;
aURI->GetSpec(spec);
mParent.loadURL(spec.get());
}
void
TabParent::Move(PRUint32 x, PRUint32 y, PRUint32 width, PRUint32 height)
{
mParent.move(x, y, width, height);
}
} // namespace tabs
} // namespace mozilla

41
dom/ipc/TabParent.h Normal file
Просмотреть файл

@ -0,0 +1,41 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: sw=4 ts=4 et : */
#ifndef mozilla_tabs_TabParent_h
#define mozilla_tabs_TabParent_h
#include "TabTypes.h"
#include "IFrameEmbeddingProtocol.h"
#include "IFrameEmbeddingProtocolParent.h"
#include "TabProcessParent.h"
#include "mozilla/Monitor.h"
class nsIURI;
namespace mozilla {
namespace tabs {
class TabParent
: private IFrameEmbeddingProtocol::Parent
{
public:
TabParent(MagicWindowHandle parentWidget);
virtual ~TabParent();
void LoadURL(nsIURI* aURI);
void Move(PRUint32 x, PRUint32 y, PRUint32 width, PRUint32 height);
private:
void LaunchSubprocess();
TabProcessParent mSubprocess;
IFrameEmbeddingProtocolParent mParent;
mozilla::Monitor mMonitor;
};
} // namespace tabs
} // namespace mozilla
#endif

Просмотреть файл

@ -0,0 +1,55 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: sw=4 ts=4 et : */
#include "TabProcessParent.h"
#include "chrome/common/chrome_switches.h"
namespace mozilla {
namespace tabs {
char const *const TabProcessParent::kTabProcessName = "gecko-iframe" BIN_SUFFIX;
TabProcessParent::TabProcessParent()
{
}
TabProcessParent::~TabProcessParent()
{
}
bool TabProcessParent::Launch()
{
if (!CreateChannel())
return false;
FilePath exePath =
FilePath::FromWStringHack(CommandLine::ForCurrentProcess()->program());
exePath = exePath.DirName();
exePath = exePath.AppendASCII(kTabProcessName);
#if defined(OS_POSIX)
int srcChannelFd, dstChannelFd;
channel().GetClientFileDescriptorMapping(&srcChannelFd, &dstChannelFd);
mFileMap.push_back(std::pair<int,int>(srcChannelFd, dstChannelFd));
#endif
CommandLine cmdLine(exePath.ToWStringHack());
cmdLine.AppendSwitchWithValue(switches::kProcessChannelID, channel_id());
base::ProcessHandle process;
#if defined(OS_POSIX)
base::LaunchApp(cmdLine.argv(), mFileMap, false, &process);
#else
#error Loser
#endif
if (!process)
return false;
SetHandle(process);
return true;
}
} // namespace tabs
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,45 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: sw=4 ts=4 et : */
#ifndef mozilla_tabs_TabProcessParent_h
#define mozilla_tabs_TabProcessParent_h
#include "mozilla/ipc/GeckoChildProcessHost.h"
namespace mozilla {
namespace tabs {
class TabProcessParent
: private mozilla::ipc::GeckoChildProcessHost
{
public:
TabProcessParent();
~TabProcessParent();
/**
* Asynchronously launch the plugin process.
*/
bool Launch();
IPC::Channel* GetChannel() {
return channelp();
}
virtual bool CanShutdown() {
return true;
}
base::WaitableEvent* GetShutDownEvent() {
return GetProcessEvent();
}
private:
static char const *const kTabProcessName;
DISALLOW_EVIL_CONSTRUCTORS(TabProcessParent);
};
}
}
#endif

82
dom/ipc/TabThread.cpp Normal file
Просмотреть файл

@ -0,0 +1,82 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: sw=4 ts=4 et :
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Plugin App.
*
* The Initial Developer of the Original Code is
* Ben Turner <bent.mozilla@gmail.com>.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Chris Jones <jones.chris.g@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "TabThread.h"
#include "prlink.h"
#include "base/command_line.h"
#include "base/string_util.h"
#include "chrome/common/child_process.h"
#include "chrome/common/chrome_switches.h"
using mozilla::ipc::GeckoThread;
namespace mozilla {
namespace tabs {
TabThread::TabThread() :
GeckoThread(),
mTab()
{
}
TabThread::~TabThread()
{
}
void
TabThread::Init()
{
GeckoThread::Init();
// FIXME/cjones: set up channel stuff, etc.
// FIXME owner_loop() is bad here
mTab.Init(owner_loop(), channel());
}
void
TabThread::CleanUp()
{
GeckoThread::CleanUp();
}
} // namespace tabs
} // namespace mozilla

77
dom/ipc/TabThread.h Normal file
Просмотреть файл

@ -0,0 +1,77 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: sw=4 ts=4 et :
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Plugin App.
*
* The Initial Developer of the Original Code is
* Ben Turner <bent.mozilla@gmail.com>.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Chris Jones <jones.chris.g@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef dom_tabs_TabThread_h
#define dom_tabs_TabThread_h 1
#include "chrome/common/child_thread.h"
#include "base/file_path.h"
#include "mozilla/ipc/GeckoThread.h"
#include "TabChild.h"
#undef _MOZ_LOG
#define _MOZ_LOG(s) printf("[TabThread] %s", s)
namespace mozilla {
namespace tabs {
//-----------------------------------------------------------------------------
// The TabThread class represents a background thread where tab instances
// live.
class TabThread : public mozilla::ipc::GeckoThread {
public:
TabThread();
~TabThread();
private:
// Thread implementation:
virtual void Init();
virtual void CleanUp();
TabChild mTab;
IPC::Channel* mChannel;
DISALLOW_EVIL_CONSTRUCTORS(TabThread);
};
} // namespace tabs
} // namespace mozilla
#endif // ifndef dom_tabs_TabThread_h

16
dom/ipc/TabTypes.h Normal file
Просмотреть файл

@ -0,0 +1,16 @@
#ifndef mozilla_tabs_TabTypes_h
#define mozilla_tabs_TabTypes_h
#ifdef XP_WIN
#include <windows.h>
typedef HWND MagicWindowHandle;
#elif defined(MOZ_WIDGET_GTK2)
#include <X11/X.h>
typedef XID MagicWindowHandle;
#else
#error Not implemented, stooge
#endif
#endif

105
dom/ipc/app/Makefile.in Normal file
Просмотреть файл

@ -0,0 +1,105 @@
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is Mozilla Plugin App.
#
# The Initial Developer of the Original Code is
# Ben Turner <bent.mozilla@gmail.com>.
# Portions created by the Initial Developer are Copyright (C) 2009
# the Initial Developer. All Rights Reserved.
# Chris Jones <jones.chris.g@gmail.com>
#
# Contributor(s):
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = dom
##
## Build the child process that runs plugins
##
DEFINES += -DNO_NSPR_10_SUPPORT=1
PROGRAM = gecko-iframe$(BIN_SUFFIX)
CPPSRCS = \
TabApp.cpp \
$(NULL)
LIBS += \
$(XPCOM_LIBS) \
$(NSPR_LIBS) \
$(NULL)
# This switches $(INSTALL) to copy mode, like $(SYSINSTALL), so things that
# shouldn't get 755 perms need $(IFLAGS1) for either way of calling nsinstall.
NSDISTMODE = copy
include $(topsrcdir)/config/config.mk
include $(topsrcdir)/ipc/chromium/chromium-config.mk
ifdef _MSC_VER
# Always enter a Windows program through wmain, whether or not we're
# a console application.
ifdef WINCE
WIN32_EXE_LDFLAGS += -ENTRY:mainWCRTStartup
else
WIN32_EXE_LDFLAGS += -ENTRY:wmainCRTStartup
endif
endif
ifdef WINCE
EXTRA_DSO_LDOPTS += $(call EXPAND_LIBNAME,corelibc)
endif
ifeq ($(OS_ARCH),WINNT)
OS_LIBS += $(call EXPAND_LIBNAME,comctl32 comdlg32 uuid shell32 ole32 oleaut32 version winspool)
OS_LIBS += $(call EXPAND_LIBNAME,usp10 msimg32)
endif
include $(topsrcdir)/config/rules.mk
ifeq ($(OS_ARCH),WINNT)
#
# Control the default heap size.
# This is the heap returned by GetProcessHeap().
# As we use the CRT heap, the default size is too large and wastes VM.
#
# The default heap size is 1MB on Win32.
# The heap will grow if need be.
#
# Set it to 256k. See bug 127069.
#
ifndef GNU_CC
LDFLAGS += /HEAP:0x40000
endif
endif

67
dom/ipc/app/TabApp.cpp Normal file
Просмотреть файл

@ -0,0 +1,67 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: sw=4 ts=4 et :
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Plugin App.
*
* The Initial Developer of the Original Code is
* Ben Turner <bent.mozilla@gmail.com>.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Chris Jones <jones.chris.g@gmail.com>.
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsXPCOM.h"
#include "nsXULAppAPI.h"
// FIXME/cjones testing
#include <unistd.h>
#ifdef XP_WIN
#include <windows.h>
// we want a wmain entry point
#include "nsWindowsWMain.cpp"
#endif
class ScopedLogging
{
public:
ScopedLogging() { NS_LogInit(); }
~ScopedLogging() { NS_LogTerm(); }
};
int
main(int argc, char* argv[])
{
ScopedLogging log;
nsresult rv = XRE_InitChildProcess(argc, argv, "TabThread");
NS_ENSURE_SUCCESS(rv, 1);
}

26
dom/ipc/test.xul Normal file
Просмотреть файл

@ -0,0 +1,26 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
width="800" height="800" onload="setTimeout(restart, 0)" orient="vertical">
<script>
function restart() {
var y = document.getElementById('page');
var p = y.parentNode;
p.removeChild(y);
p.appendChild(y);
}
function loadURL(url) {
document.getElementById('page').setAttribute('src', url);
}
</script>
<toolbar id="controls">
<toolbarbutton label="Back"/>
<toolbarbutton label="Forward"/>
<textbox onchange="loadURL(this.value)" flex="1" id="URL"/>
<toolbarbutton onclick="restart()" label="Recover"/>
</toolbar>
<iframe type="content" src="http://www.google.com/" flex="1" id="page"/>
</window>

Просмотреть файл

@ -93,6 +93,7 @@ endif
# dependent libraries # dependent libraries
ifdef MOZ_IPC ifdef MOZ_IPC
STATIC_LIBS += \ STATIC_LIBS += \
domipc_s \
domplugins_s \ domplugins_s \
mozipc_s \ mozipc_s \
chromium_s \ chromium_s \

Просмотреть файл

@ -209,6 +209,8 @@ include $(topsrcdir)/config/config.mk
include $(topsrcdir)/ipc/chromium/chromium-config.mk include $(topsrcdir)/ipc/chromium/chromium-config.mk
include $(topsrcdir)/config/rules.mk include $(topsrcdir)/config/rules.mk
LOCAL_INCLUDES += -I$(topsrcdir)/dom/ipc
ifdef BUILD_STATIC_LIBS ifdef BUILD_STATIC_LIBS
export:: export::
@$(PERL) -I$(MOZILLA_DIR)/config $(MOZILLA_DIR)/config/build-list.pl $(FINAL_LINK_COMP_NAMES) Apprunner @$(PERL) -I$(MOZILLA_DIR)/config $(MOZILLA_DIR)/config/build-list.pl $(FINAL_LINK_COMP_NAMES) Apprunner

Просмотреть файл

@ -68,6 +68,7 @@
#include "ScopedXREEmbed.h" #include "ScopedXREEmbed.h"
#include "mozilla/plugins/PluginThreadChild.h" #include "mozilla/plugins/PluginThreadChild.h"
#include "TabThread.h"
using mozilla::ipc::BrowserProcessSubThread; using mozilla::ipc::BrowserProcessSubThread;
using mozilla::ipc::GeckoChildProcessHost; using mozilla::ipc::GeckoChildProcessHost;
@ -75,6 +76,7 @@ using mozilla::ipc::GeckoThread;
using mozilla::ipc::ScopedXREEmbed; using mozilla::ipc::ScopedXREEmbed;
using mozilla::plugins::PluginThreadChild; using mozilla::plugins::PluginThreadChild;
using mozilla::tabs::TabThread;
static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID); static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
@ -213,6 +215,8 @@ XRE_InitChildProcess(int aArgc,
mainThread = new GeckoThread(); mainThread = new GeckoThread();
else if (!strcmp("PluginThreadChild", aMainThreadClass)) else if (!strcmp("PluginThreadChild", aMainThreadClass))
mainThread = new PluginThreadChild(); mainThread = new PluginThreadChild();
else if (!strcmp("TabThread", aMainThreadClass))
mainThread = new TabThread();
else { else {
NS_RUNTIMEABORT("Unknown main thread class"); NS_RUNTIMEABORT("Unknown main thread class");
} }