I’m terrible at writing blog posts, and I’ve been meaning to write this since UDS at least. Sorry!
If you saw the wrap-up notes for the August UDS, you might have noticed the following statement:
oxide: we sorted out the details of the work that needs to happen for oxide to be [sic] replace qtwebkit, for the touch browser, webapps and SDK, before 14.04
If you’re wondering what on earth is going on, then this post attempts to explain.
A few months ago, I started to look at how we provide post-release support for the various Webkit ports in Ubuntu – in particular, QtWebkit (which is used by the Ubuntu Touch browser and in the Ubuntu SDK). For an acceptable level of post-release support we need to be able to deliver the following, as a minimum:
- Security fixes for the duration of the LTS (5 years).
- Updates to add support for new web technologies and to provide web compatibility fixes throughout the support life-cycle.
In addition to this, we also need something that:
- Is supportable on the phone, converged device and desktop.
- Has good integration with the native toolkit, SDK and accessibility mechanisms.
- Allows us to ship a browser that delivers a competitive level of performance.
At the moment, we only really achieve the last 3 – and we do this by relying on other projects to do the work for us. This is great, but we need a proper post-release story too. The main difficulty with this is that the upstream projects generally don’t support their releases with updates for the duration that we require in Ubuntu – this means that it becomes the distribution’s responsibility to provide security maintenance for 5 years. As an example, Ubuntu 13.04 currently includes QtWebkit based on the 5.0 release of Qt – from which, the last maintenance release was 5.0.2 in April 2013. Since then there have been 4 major releases of Chrome, and in 1 month of commits to the main Webkit SVN repository, I counted no fewer than 7 security fixes.
We’ve been thinking of ways to resolve this for some time now. I’ve made a list of things that have been discussed:
- Backporting individual security fixes from the main Webkit SVN repository for the support life-cycle.
- Backporting complete new versions of the supported Webkit ports.
- Taking the existing Webkit ports and regularly rebasing them on the latest WebCore and JSC ourselves.
- Creating our own Webkit port.
Backporting individual security fixes from the main Webkit SVN repository
This is basically our current strategy, and it is one that we’ve already abandoned for the major browsers that are shipped in the Ubuntu archive (Firefox and Chromium). There are several problems with this strategy:
- We don’t have access to Webkit security bugs, so don’t really know what to backport or how to verify what we’re backporting.
- Backporting patches is actually pretty difficult and error prone, particularly when it’s being done by people who aren’t working on the code.
- Backporting patches becomes much harder, riskier and more time consuming as the newest Webkit code gradually diverges more from the code that we ship in Ubuntu.
In addition to this, backporting individual security fixes doesn’t help us with our second requirement, which is to ensure that we ship something that is compatible with the latest web technologies.
Backporting complete new versions of Webkit ports
This has been tried recently with WebkitGTK, with limited success. The problem with this is that new releases tend to depend on newer versions of various other parts of the platform, making it difficult to ship the latest versions on older Ubuntu releases. As an example, WebkitGTK 2.2.0 depends on Gtk 3.6 (Ubuntu 12.04 includes 3.4), Glib 2.36 (Ubuntu 12.10 includes 2.34) and libsoup 2.42 (Ubuntu 13.04 – the latest stable version, only includes 2.40). The latest version of WebkitGTK is only buildable on Ubuntu 13.10, which isn’t even released yet.
The current development release of QtWebkit also doesn’t build on Ubuntu 13.10 (which still includes the Qt 5.0 stack).
Regularly rebasing supported Webkit ports on the latest WebCore
This is a non-starter really. There’s not really much difference between this and forking each of the Webkit ports, and I don’t think that the various upstream developers would be that pleased with us shipping FrankenWebkit versions.
Creating our own Webkit port
This has the advantage that we would be able to control the release model, and regularly rebase our port on the most appropriate revision of WebCore in order to pick up security fixes and web compatibility updates. We would be able to do this whilst providing guaranteed API stability for the Ubuntu SDK. Of course, there is the small issue of this requiring a huge amount of work…..
Shortly after Google announced that they were going to fork Webkit, we started to explore the possibility of providing a library for our SDK that was based on the Chromium Content API (and hence, V8 + Blink). I had already started to look at one such effort (Chromium Embedded Framework), although this didn’t really fit our requirements.
Chromium has some advantages over Webkit – it provides more functionality out of the box, so it should be easier to build a library on this rather than create our own port of Webkit. Webkit no longer powers a major browser on the Linux desktop, so it’s more of a risk for us in the long-term. Also, Chrome’s popularity and market share makes shipping a browser based on it a good strategic decision.
At our Oakland sprint in April, I took away some initial actions to scope out the amount of work required to provide our own library based on Chromium. I did that, and have since been working on an interesting little project….
Oxide is a library that allows you to embed a Chromium-powered webview in QML applications. It currently provides a fairly trivial API that is quite similar to the current QML QtWebkit webview API for simple use cases, although it is nowhere near feature complete yet.
You can grab the code from https://launchpad.net/oxide.
What works currently (not all of these features have full test coverage yet, but I am getting there):
- Basic navigation (load url / back / forward reload).
- Incognito mode.
- Multiple browser contexts so you can have multiple webviews with different permanent storage locations.
- User scripts, with support for a limited subset of Greasemonkey metadata (exclude, include, match, run-at), an option to inject in to matching subframes, and support for running scripts in different contexts.
- Message passing API to allow communication between the embedder and user scripts (this is used for the automated tests it has so far).
The plan is to have the Ubuntu Touch browser and SDK using this by Ubuntu 14.04. There is a lot of work to do between now and then – some of the things we need are:
- Accelerated compositing.
- A proper navigation API with back / forward list.
- Dialog support (alert / confirm / prompt / file / colour / HTTP auth).
- Media device access permissions API.
Also see the open bugs in Launchpad.
If you want to help out with this, feel free to grab me on IRC – I’ve got plenty of work I can hand out! At some point, I plan on writing a guide to help people get started with this.