[webkit-dev] [Chromium] Changing how WebKit interfaces with Chromium

Adam Barth abarth at webkit.org
Sat Mar 31 14:05:39 PDT 2012


tl;dr: We're changing how WebKit interfaces with Chromium.  This email
describes what we're changing and why.  If you've not interested in
the Chromium port, you should feel free to skip this message.

== Overview ==

Chromium is removing the PlatformSupport abstraction.  Platform
support exists just to bounce calls from WebCore/platform to the
WebKit layer.

For example, currently Chromium's CookieJar implementation indirects
through PlatformSupport:

    CookieJar::cookies() =>
        return PlatformSupport::cookies()

    PlatformSupport::cookies() =>
        return webKitPlatformSupport()->cookieJar()->cookies();

In the new design, Chromium's CookieJar has one fewer layer to plumb through:

    CookieJar::cookies() =>
        return webKitPlatformSupport()->cookieJar()->cookies()

To accomplish this simplification, we're moving a subset of the
Chromium--WebKit interface to WebCore/platform, where it can be called
directly by Chromium-specific code in WebCore/platform.

The change in Chromium's layering diagram is depicted below:

https://docs.google.com/drawings/d/1GJXd6XSLEehvuqA7Xbvbz0OH6Znnr2iTijihjrEY0ts/edit

== Previous Design ==

Previously, there was a single interface that WebKit used to interact
with the embedder called the Embedder Interface.  This interface
really served two distinct purposes:

1) Provide an object constellation centered around WebView that let
the embedder control WebKit and let WebKit ask questions/notify the
embedder about topics related (in some way) to the WebView.

2) Provide an interface that WebKit can use to access services
independent of the WebView (e.g., ask for the current time or fetch a
URL from the network).

Some other ports use OS-provided facilities (e.g., CFNetwork) for (2),
but for the Chromium port, we prefer that the embedder abstracts these
OS interactions from WebKit so that we can substitute different
implementations (e.g., in-process versus out-of-process or Windows
versus Linux).

== New Design ==

In the new design, there are two interfaces that WebKit uses to
interact with the embedder.  The objects that serve purpose (1) remain
in <http://trac.webkit.org/browser/trunk/Source/WebKit/chromium/public>.
 The objects that serve purpose (2) are now located (or at least
migrating towards)
<http://trac.webkit.org/browser/trunk/Source/Platform/chromium/public>.
 Over time, we plan to migrate the headers in
<http://trac.webkit.org/browser/trunk/Source/WebKit/chromium/public/platform/>
to their new home.

Note: We've moved these headers to Platform/chromium/public rather
than WebCore/platform/chromium/public to make it easier to move the
rest of WebCore/platform to Platform in the future, but Platform
remains just the new name for WebCore/platform.

Similar to how the Client Interface can be accessed from the
Chromium-specific part of the WebKit layer, the Platform Interface can
be accessed from the Chromium-specific part of the Platform layer (aka
WebCore/platform).  Some basic concepts (e.g., WebString) are shared
by both interfaces.  These concepts are located in the Platform
Interface, but we might end up moving them to a "neutral location" if
that's valuable.

== Advantages ==

The primary advantage of the new design over the old design is that in
the old design we had a bunch of code in the Chromium WebKit layer in
the WebCore namespace.  For example, the Chromium implementation of
WebCore::ResourceHandle was located in
WebKit/chromium/src/ResourceHandle.cpp whereas other ports implemented
their version of ResourceHandle in WebCore/platform/network (which is
much more sensible and where Chromium's ResourceHandle lives in the
new design).

Over time, as we added support for things like PeerConnection, we were
growing more WebCore-namespaced code in the WebKit layer.  We even
created a directory called "bridge" to try to contain the layering
inversion.  This code was often "boilerplate" that just served to
plumb calls through the WebKit layer to gain access to the embedder.
In the new design, this code can live in WebCore/platform and access
the Platform Interface directly.

Similarly, we've be able to remove PlatformSupport, which exists only
to redirect calls from WebCore to the WebKit layer.

Another, smaller, advantage of the new design is that it's more
difficult to introduce layering violation whereby interfaces for
purpose (2) actually end up depending on concepts related to WebView.
Previously, there was nothing stopping interfaces defined on
WebKitPlatformSupport from depending on WebView-related headers.  The
new design makes that a compile-time error.

== Frequently Asked Questions ==

Q) I'm confused why some things are in Platform and some things are in
WebCore/platform.  What's the difference between these two
directories?

A) Platform is just the new name for WebCore/platform.  They're
conceptually the same thing.  We hope to move all the code that's
currently in WebCore/platform into Platform, as discussed previously
on webkit-dev.  We've moved some API headers directly to their final
home in Platform to reduce the amount of API churn on the embedder.

Q) I noticed that the Platform Interface is in the WebKit namespace.
Doesn't just swap WebCore-namespaced code in the WebKit layer for
WebKit-namespaced code in the WebCore layer?

A) For the time being, we've left the Platform Interface in the WebKit
namespace to avoid too much API churn for the embedder.  (You'll
notice that we also have some forwarding headers in
WebKit/chromium/public/platform/ that point to the new directory).
Once the split is complete, we'll likely delete the forwarding headers
and change the namespace.  One subtly is the "common" concepts (e.g.,
WebString).  We're not sure how best to handle these objects yet
because we don't want folks using the Client Interface to worry too
much about whether something is also used by the Platform Interface.

Q) Why are you defining the Platform Interface in svn.webkit.org.  The
more normal thing is for lower-level libraries to define their own
interface and for WebKit to consume those libraries using their own
headers.

A) Often when there is a many-to-one relation between the two sides of
an interface, we define the interface on the "one" side.  For example,
for Skia, there is one implementation of Skia and many folks using
Skia.  In that case, it makes sense for Skia to define its interface
and for WebKit to consume that interface.  In the case of the Platform
Interface, there is (for most intents and purposes) a one-to-one
relation between the two sides of the interface, which gives us the
freedom to define the interface on either side.

We've chosen to define it on the WebKit side, largely for the benefit
of the WebKit project.  This approach insulates WebKit from churn in
Chromium.  For example, when Chromium changed from representing
strings using std::wstring to string16, there was no impact on WebKit
because the interface between WebKit and Chromium is defined in terms
of WebKit types, not Chromium types.  Similarly, when Chromium
switched from WinHTTP to a custom HTTP stack, there was no impact on
WebKit.  By contrast, if Safari were to switch from CFNetwork to
another network stack, WebKit would need to be changed.

Q) Why are you inventing the new-fangled design instead of using
PlatformStrategies?

A) Like PlatformSupport, PlatformStrategies is a mechanism for
bouncing calls from WebCore up to the WebKit layer.
PlatformStrategies has the virtue of not requiring WebCore-namespaced
code in the WebKit layer, but has the disadvantage of still requiring
a bunch of boilerplate code to route the calls out to the embedder.
In some sense, you can view the Platform Interface as letting the
embedder provide PlatformStrategies directly instead of requiring an
indirection through the WebKit layer.  In the future, it might make
senes to share some interfaces between PlatformStrategies and the
Platform Interface, but that would have the consequence of making
these interfaces public, which is something we'd want to discuss more
with the community first.

Q) I want to define a new API between Chromium and WebKit, should I
put it in the Client Interface or the Platform Interface?

A) Feel free to ask your friendly neighborhood API reviewer!
Generally, if the API is used by WebKit to manipulate lower-level
concepts, then the interface belongs in the Platform Interface,
especially if the API doesn't make reference to WebViews or any
WebView-related concepts.  If the API allows the embedder to control
WebKit or asks the embedder for advice, then it belongs in the Client
Interface.

Please let me know if you have any questions or comments.

Thanks!
Adam


More information about the webkit-dev mailing list