I like to break things

Introducing Oxide

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…..

Enter Chromium

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….

Introducing Oxide

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.

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).

What next?

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:

12 thoughts on “Introducing Oxide”

I’m aware of Qt WebEngine, although this was announced after I’d already started work on this. However, whilst it’s great that somebody else is doing something similar, this would not solve our original problem – which is that we want something we can properly support for 5 years.

Also, Oxide isn’t particularly tied to Qt. It’s been designed to support new ports fairly easily (eg, I might add a Gtk port in the future)

couldn’t the browser app simply be a click package, that brings with it all its own dependancies (theoretically making it possible to run a different version of *packagename* for that app). I suppose the down side would be storage space, which can be quite limited on mobile devices…

I hope that some efforts will be taken to make Oxide’s QML APIs and WebEngine’s as similar as possible, at least when it comes to common features.
So that developers interested in only the basic sets of feature could just change the import line.

I’m curious, what uses liboxideqtcore0 on my Ubuntu 15.04 desktop? It seems like it’s used by unity-webapps, but as I understand it those just make web pages running in Firefox first-class applications in Unity. What’s actually firing up a separate “Web browser engine”? Thanks!

It seems less than ideal that I have a 90MB liboxideqtcore0, and a 40MB libqt5webkit5 installed on my desktop (plus the 210 MB chromium-browser which I voluntarily installed) when they’re all implementing WebKit. At least they’re sharing glib and stdc++ AFAICT unity-webapps-qml pulls in *both* liboxideqtcore0 and libqt5webkit5, which seems strange.

I have a framebuffer device. Can I compile Oxide for a framebuffer embedded arm device? When I compile, it gives –cflags x11, no package x11 found. Because I don’t need X11, I use framebuffer. How to compile it so?