[webkit-gtk] WebKit2 API and Injected Bundle support

Carlos Garcia Campos cgarcia at igalia.com
Tue May 8 03:40:13 PDT 2012


WebKit2 provides a way to inject code in the web process to do some
things that are impossible to do other ways. It works like a plugin,
loaded by the web process with dlopen at startup. Only one injected
bundle client is supported by the web process. There's an InjectedBundle
API in WebKit2/WebProcess/InjectedBundle/ very similar to the UIProcess
C API. In some cases the clients of both APIs contain the same
callbacks, but there's a userData parameter that allows to communicate
both APIs somehow, for example:

In WKBundlePageUIClient we have mouseDidMoveOverElement callback with
the following signature:

void (*WKBundlePageMouseDidMoveOverElementCallback)(WKBundlePageRef page, WKBundleHitTestResultRef hitTestResult, 
                                                                                               WKEventModifiers modifiers, WKTypeRef* userData, 
                                                                                               const void* clientInfo);

And in WKPageUIClient we have mouseDidMoveOverElement with the
signature:

void (*WKPageMouseDidMoveOverElementCallback)(WKPageRef page, WKHitTestResultRef hitTestResult, 
                                                                                    WKEventModifiers modifiers, WKTypeRef userData, const void *clientInfo);

So, the web process first notifies the injected bundle client, and then
the ui client, so that we can pass additional information from the web
process to the ui process wihtout using additional messages.

In other cases the injected bundle clients contain callbacks that are
not available in the UI clients, for example willSendRequestForFrame in
WKBundlePageResourceLoadClient. This is the callback that allows to
modify a URLRequest for any resource before it's sent to the server. We
need this to implement WebKitWebResource::send-request signal that
exposes this functionality in our WebKit2 GTK+ API. For these cases, the
Injected Bundle API provides a way to send/receive user messages to
communicate the Web and UI processes.

These are just examples, but it might be used for any other cases where
you need something from the web process like accessing the DOM,
javascript context, etc.

So, we need to support Injected Bundle, the main question is whether we
want to expose it somehow in our public API and how. I think we can
provide everything needed in our API without exposing the injected
bundle API, using custom IPC messages in some cases like we did for
printing, cookies or uri schemes, and using the injected bundle API
internally to implement the required features like in
WebKitWebResource::send-request signal. Following this idea I
implemented send-request here:

[GTK] Add WebKitWebResource::send-request signal to WebKit2 GTK+ API
https://bugs.webkit.org/show_bug.cgi?id=83681

However some people are concerned because that approach doesn't allow
the user of the WebKit2 GTK+ API to use injected bundle. The main
problem is that the web process only allows one injected bundle client,
so if the users install their own injected bundle lib, we can't
implement things like WebKitWebResource::send-request signal in our API.
Of course users could implement their own send-request signal using
their injected bundle, but we would end up with a different
implementation in every application and that's not the point of the GTK+
API.

In case we decide to expose the injected bundle API, we need to figure
out how to do it, because we would need to wrap also the injected bundle
objects with WebKitBundleFoo objects. The high level injected bundle API
would be bigger than our current WebKit2 GTK+ API, becase we also need
to wrap or convert basic C types that can be serialized in user messages
(WKArray, WKDictionary, etc.).

So, I think we have at least these options:

1.- Expose the injected bundle api: Users would install their own
injected bundle lib and would implement everything that requires the use
of injected bundle. We would need to wrap the whole injected bundle API.
This would require a lot of work and time. An alternative would be to
not wrap the API and users would implement the bundle lib using the C
API directly. We would only need to provide a method in our
WebKitWebContext to pass the bundle lib to the web process.

2.- Don't expose the injected bundle API: We install our own bundle lib,
and use it to implement everything that requires the use of injected
bundle, exposing it in our API in a transparent way. That's what I did
for WebKitWebResource::send-request signal in bug #83681.

3.- Don't expose the injected bundle API, but allow to add
extensions/plugins. The idea is to provide a module system similar to
GTK modules or GIO extension points. We install our own injected bundle
lib that allows to load extensions/modules. We would also provide our
own module to implement the features that require to use injected bundle
like WebKitWebResource::send-request signal. In this case we have the
same problem than 1, wrapping the whole injected bundle API would be too
much work, so the modules/extensions might be written using the C API
directly.

Feel free to add any other suggestions here. 

The good thing about 3 is that is compatible with 2, so we can implement
2 (which is already implemented) and then move to 3 without affecting
the API (we would move the current impl to a module and rework the
injected bundle lib to load modules and route messages). 

My main concern is that we might end up implementing an extension system
or wrapping an entire API that nobody is going to use eventually. So, I
prefer to start with a simpler option that would allow us to implement
the complex one in the future if it's really needed. We won't know until
we start porting more applications that use more extensively the current
WebKit1 API. So, for now I think the best option is the second one,
leaving it open to implement 3 in the future if required by apps.

Opinions?
-- 
Carlos Garcia Campos
http://pgp.rediris.es:11371/pks/lookup?op=get&search=0xF3D322D0EC4582C3
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: This is a digitally signed message part
URL: <http://lists.webkit.org/pipermail/webkit-gtk/attachments/20120508/a0317d21/attachment.bin>


More information about the webkit-gtk mailing list