Discussion:
E10s: "content driver"
Smaug
2009-10-25 17:37:41 UTC
Permalink
Hi all,

I've been thinking about the content-to-chrome event handling,
and serializing and de-serializing event would be otherwise
pretty easy, but handling event targets is tricky.
(I'm going to implement serialization for MozAfterPaint etc so that we
can prototype some Fennec-like implementation.)

So I've tried to come up with something where event target handling
would happen mainly in content process.
The idea is to hook content process WindowRoot's event handling related
methods to a new JS context. That context should have access to content
DOM and to an API to send messages to chrome process, but no chrome
privileges.

When content process is initialized, chrome would activate
event listeners in this new layer (I've used "content chrome" name
before, but perhaps "content driver" is better.)
Also extensions could send new event listeners to the content driver.
Event listeners could then communicate with chrome using "remote
chrome" API, which would probably look a bit like
nsIWebBrowserChrome/nsIEmbeddingSiteWindow/nsIWebBrowserChromeFocus
/nsIContextMenuListener/nsITooltipListener/nsIWebProgressListener.
The API should also have some generic way to send and receive JSON
data.

I *think* without some kind of content driver layer we'll end up having
something pretty close to
http://mxr.mozilla.org/seamonkey/source/ipc/ipcd/, especially dconnect.

But, content driver makes it harder to develop extensions and FF
UI. Developer needs to split code to be executed in chrome and in
content driver.

Comments?


-Olli
Benjamin Smedberg
2009-10-26 14:02:55 UTC
Permalink
Post by Smaug
I've been thinking about the content-to-chrome event handling,
and serializing and de-serializing event would be otherwise
pretty easy, but handling event targets is tricky.
(I'm going to implement serialization for MozAfterPaint etc so that we
can prototype some Fennec-like implementation.)
So I've tried to come up with something where event target handling
would happen mainly in content process.
The idea is to hook content process WindowRoot's event handling related
methods to a new JS context. That context should have access to content
DOM and to an API to send messages to chrome process, but no chrome
privileges.
Fennec doesn't need access to the remote event.target right now, so for the
time being we can either make it null or make it the chrome-side
<xul:{iframe,browser}> hosting the remote content.

In terms of programming idiom I was thinking of something like this for
asynchronous event handling in chrome:

contentWindow.addAsyncChromeEventHandler("event-type",
"resource://app/modules/browser-handlers.js#functionName", false,
function(result) {
// do something with `result`. I'm not sure whether result is plain-JSON,
// or whether it also allows JPW references.
});

This would install an event listener in the content process which would have
the full use of XPCOM (at least in theory). When events were fired it would
run the function named `functionName` in browser-handlers.js. That function
can optionally send a data structure back to chrome which ends up calling
the fourth element of .addAsyncChromeEventHandler.

I don't know in this proposal whether the result function should be called
with RPC or async dispatch... we'll probably have to wait for some
real-world experience to see what the UI code actually needs.
Post by Smaug
Also extensions could send new event listeners to the content driver.
Event listeners could then communicate with chrome using "remote
chrome" API, which would probably look a bit like
nsIWebBrowserChrome/nsIEmbeddingSiteWindow/nsIWebBrowserChromeFocus
/nsIContextMenuListener/nsITooltipListener/nsIWebProgressListener.
The API should also have some generic way to send and receive JSON
data.
I think that we'd be better off without this form of communication, and only
allow the resultFunction
Post by Smaug
I *think* without some kind of content driver layer we'll end up having
something pretty close to
http://mxr.mozilla.org/seamonkey/source/ipc/ipcd/, especially dconnect.
Yes, we definitely do not want an arbitrary remoting layer a-la dconnect.
The only arbitrary-remoting layer we're going to allow is JPW, and that's
mainly one-way chrome calling content, not content calling chrome.
Post by Smaug
But, content driver makes it harder to develop extensions and FF
UI. Developer needs to split code to be executed in chrome and in
content driver.
I think that for extensions, something like
xulbrowser.contentWindow.addEventListener (or maybe event
xulbrowser.addEventListener) should continue to "just work"... the
event.target would be a reference to a JPW, and it would be dispatched with
RPC semantics. This would *only* be allowed on the one object, and not on
arbitrary DOM nodes within the tree (meaning we can avoid most issues with
reference cycles).

But long-term we'd like to move most extension over to be jetpacks, which
can block without actually blocking the browser UI:
https://developer.mozilla.org/en/Multi-Process_Architecture/Jetpack (this
could be in a separate thread or a separate process: I've just specified a
separate process because of the added crash and memory protection it provides).

--BDS
Smaug
2009-10-26 14:19:01 UTC
Permalink
Post by Benjamin Smedberg
Post by Smaug
I've been thinking about the content-to-chrome event handling,
and serializing and de-serializing event would be otherwise
pretty easy, but handling event targets is tricky.
(I'm going to implement serialization for MozAfterPaint etc so that we
can prototype some Fennec-like implementation.)
So I've tried to come up with something where event target handling
would happen mainly in content process.
The idea is to hook content process WindowRoot's event handling related
methods to a new JS context. That context should have access to content
DOM and to an API to send messages to chrome process, but no chrome
privileges.
Fennec doesn't need access to the remote event.target right now, so for the
time being we can either make it null or make it the chrome-side
<xul:{iframe,browser}> hosting the remote content.
In terms of programming idiom I was thinking of something like this for
contentWindow.addAsyncChromeEventHandler("event-type",
"resource://app/modules/browser-handlers.js#functionName", false,
function(result) {
// do something with `result`. I'm not sure whether result is plain-JSON,
// or whether it also allows JPW references.
});
This would install an event listener in the content process which would have
the full use of XPCOM (at least in theory). When events were fired it would
run the function named `functionName` in browser-handlers.js. That function
can optionally send a data structure back to chrome which ends up calling
the fourth element of .addAsyncChromeEventHandler.
I don't know in this proposal whether the result function should be called
with RPC or async dispatch... we'll probably have to wait for some
real-world experience to see what the UI code actually needs.
So this is basically what I had in my mind, except that you want to
send some data structure back, not call any API. I think I agree with
you, having JSON result or similar is enough.
For async chrome event handlers we need some JS context where they can
run. That would be the "content driver".

I'm not sure what you mean with "which would have the full use of XPCOM"
Post by Benjamin Smedberg
Post by Smaug
Also extensions could send new event listeners to the content driver.
Event listeners could then communicate with chrome using "remote
chrome" API, which would probably look a bit like
nsIWebBrowserChrome/nsIEmbeddingSiteWindow/nsIWebBrowserChromeFocus
/nsIContextMenuListener/nsITooltipListener/nsIWebProgressListener.
The API should also have some generic way to send and receive JSON
data.
I think that we'd be better off without this form of communication, and only
allow the resultFunction
Post by Smaug
I *think* without some kind of content driver layer we'll end up having
something pretty close to
http://mxr.mozilla.org/seamonkey/source/ipc/ipcd/, especially dconnect.
Yes, we definitely do not want an arbitrary remoting layer a-la dconnect.
The only arbitrary-remoting layer we're going to allow is JPW, and that's
mainly one-way chrome calling content, not content calling chrome.
Post by Smaug
But, content driver makes it harder to develop extensions and FF
UI. Developer needs to split code to be executed in chrome and in
content driver.
I think that for extensions, something like
xulbrowser.contentWindow.addEventListener (or maybe event
xulbrowser.addEventListener) should continue to "just work"... the
event.target would be a reference to a JPW, and it would be dispatched with
RPC semantics. This would *only* be allowed on the one object, and not on
arbitrary DOM nodes within the tree (meaning we can avoid most issues with
reference cycles).
But long-term we'd like to move most extension over to be jetpacks, which
https://developer.mozilla.org/en/Multi-Process_Architecture/Jetpack (this
could be in a separate thread or a separate process: I've just specified a
separate process because of the added crash and memory protection it provides).
--BDS
Benjamin Smedberg
2009-10-26 14:40:24 UTC
Permalink
Post by Smaug
For async chrome event handlers we need some JS context where they can
run. That would be the "content driver".
I'm not sure what you mean with "which would have the full use of XPCOM"
I don't think you need a special JS context: it would basically be
Cu.import('resource://app/firefox-events.js') and use that JS context. This
also means we get fastload handling "for free".

--BDS
Blake Kaplan
2009-10-27 14:32:22 UTC
Permalink
Post by Benjamin Smedberg
I don't think you need a special JS context: it would basically be
Cu.import('resource://app/firefox-events.js') and use that JS context. This
also means we get fastload handling "for free".
I think that you and smaug are using a different definition of JS context.
smaug is talking about a JSContext, you seem to be talking about a JS global
object. Once you're in JS, it's mostly invisible (except if you inspect new
Error().stack) but the question is: on what context do we run that Cu.import
line?
--
Blake Kaplan
Loading...