Android Chromium

Build Chromium Content Shell, Test Shell or Android WebView for Android.

Table Of Contents

Introduction

This project was inspired by pwnall's chromeview, but it shares no common code. The goal of this project is similar to that project -- which is to allow you to embed a replacement for the stock Android WebView, using the latest Chromium.

Why

NOTE: Google recently announced that they will be using Chromium for Android WebView in release 4.4 KitKat. While that is great news for web developers who want to build apps on the Android platform, there may still be valid reasons why you'd prefer to go down a path like this:

What Is The Difference Between This & ChromeView

The chromeview project was an awesome start to solving this problem, and I started there, but henceforth, the author has stated that he lacks the time to dedicate to it. So, I originally forked it, and updated Chromium to a newer build. Then I looked into the scrolling issues and after some digging, decided that there was a separate build artifact (Content Shell) out of Chromium that would provide a better base than the one chromeview was currently using. The code was different enough that I felt it just warranted a separate repo -- so that's what you have here. Scrolling does work great here. There are some quirks, so check the issues to figure out what isn't quite working (yet).

Later, I realized that the Chromium TestShell was another build artifact that includes everying in Content Shell, and also includes various Google Chrome features like sync, autofill, infobar, tabs, cache invalidation, etc. So, I decided to add a target for Chromium Test Shell and allow you to choose to build one or both, at your convenience.

Finally, after Google announced support from Chromium in Android WebView, it seems like the AndroidWebView apk target out of the Chromium source tree was ready to use, so I added that as well.

I also re-factored the whole thing to use Gradle with the Android Gradle plugin. It works happily with Android Studio.

Targets

You can choose to build and install one or all of the following apk targets and use any of the as the base of your project:

Details on how to build below.

Asset and Resource URLs

Note: android_webview supports Android asset/res urls like file:///android_asset and file:///android_res but content-shell and testshell do not. android-webview includs a simple file in assets/asset_file.html that you can load when you launch the app. Just put in the url: file:///android_asset/asset_file.html and it will display as expected. For content-shell/testshell, you can easily unzip or copy web resources from the assets folder to the app's data folder, and then load the url from an absolute file path, e.g. file:///data/data/{package-name}/files/index.html. Or you can see how it is implemented in android-webview and port it over to the other projects.

JavaScript Bridge

All three projects provide APIs that allow you to add JavaScript objects that can bridge over to Java and vice-versa. You can easily build your home-grown Cordova fairly painlessly. One limitation I have found is that you cannot pass a JavaScript callback Function into Java. For asynchronous execution into Java from JavaScript, a simple workaround is to have Java return a unique identifier immediately. The JavaScript side can store a reference to any callbacks with that identifier. When Java asynchronously calls back with the result, pass the identifier, and JavaScript can use it to invoke the reference to the callback(s).

What Do I Do With This

Pre-requisites

Install Android Studio. This is the easiest way to get the Android Build Tools and SDK needed for the build. Launch the SDK Manager from inside Android Studio (Tools -> Android -> SDK Manager) and configure it so it matches at least the following:

sdk-manager 1

sdk-manager 2

These versions may be outdated. You need to cross-reference the versions found in dependencies.gradle to ascertain what version of the SDK the build expects, as well as what version of the build tools. You'll also need the extra repositories denoted in the Extras section of the SDK Manager.

Build / Install

Make a copy of local.properties.sample and edit it to point to the folder where your SDK lives

$ cp local.properties.sample local.properties
$ vi local.properties

Use the gradle wrapper. Run gradlew build (Mac / Linux) or gradlew.bat build (Windows) -- either command will build everything in the whole project space. Alternatively, you can install gradle yourself, if you'd prefer to not use the wrapper (it is painless).

Artifacts are found under ${projectDir}/build/apk. Note that only content-shell, testshell and android-webview will build an apk. The rest are defined as library projects.

You can also use Gradle to build and install the app with adb. Connect a device or emulator and run:

For Content Shell:

$ cd chromium/content-shell && gradle installDebug

For Test Shell:

$ cd chromium/testshell && gradle installDebug

For Android WebView:

$ cd chromium/android-webview && gradle installDebug

Each apk provides a very basic stock browser shell with only an address bar and maybe a back/forward button, but take solace in the fact that the underpinnings are full Chromium. You can use this as a baseline to build a new browser, or an app that uses the browser, or something more interesting.

I have checked in the Intellij .iml files, so you can just import the project directly into Android Studio.

Artifacts: Assets & Libraries

The main Chromium artifact is a native shared library .so. It also depends on a number of .pak files in the /assets folder (you'll find these in the content-shell, testshell and android-webview apps). As built, these need to be included in your /libs and /assets folder of your project, and they will add a good 30-40MB of binary goodness to the size of your app. However, if you're savvy, you could figure out a way to load those from a central location on the platform, so they don't have to be included in .apk file. This will require code modifications.

This project contains a snapshot in time binary build of Chromium for Android -- the specific version that was built is captured in the VERSION file. Instructions below if you want to update Chromium.

The rest of the projects include java source and Android assets that were authored by Google to get Chromium to show up in a standard Android view and interact with it.

Updating Chromium

Build the latest Chromium for Android (see instructions below). A shell script is included under chromium/update-chromium that can be used to copy over new Chromium source and build artifacts. Very minor modifications were made to the source in order to re-structure it into the new build or get around minor issues. Modifications are kept in each project's modified directory (if it doesn't have one, nothing was modified). If you run the shell scripts, beware it will delete and replace your source. If you don't want this, don't run it blindly -- edit it to suit your needs. My workflow (which isn't ideal) is to run the script, and then hand-merge the couple of files in the modified directory.

Google updates this code constantly, so if you git pull and gclient sync on the Chromium repo and rebuild, then copy the stuff over here, there's no guarantee that all of this won't break. Note that the Java source is pretty tightly coupled to the native code -- so if you build a new shared object, chances are you'll need all the latest .java too, or it will blow up at runtime.

License

Nearly all of the source in here is copied from the Chromium project and thus subject to Chromium license(s) -- LICENSE files are found w/in each project. Anything else is licensed under BSD, found in the root project dir LICENSE file.

What Version of Chromium Is It?

Inspect the VERSION file for details on last commit logs

Pre-requisites for Building Chromium

@pwnall has some nice instructions for how to setup a Chromium build machine on a VM. I have made a couple of tweaks to it on my own fork -- namely stick with Ubuntu 12.04 for the least amount of headache.

I build on a MBP using an Ubuntu 12.04 image I created in VMWare Fusion. You will need some decent hardware to build Chromium. On 4 cores with 4GB RAM it can take several hours to complete the build. If you have a single core, forget it.

If you have a spare machine to setup a build machine, I suppose that would be even nicer.

Debugging

Java

You can debug content-shell, testshell or android-webview Java straight from Android Studio by running one of the gradle tasks in debug mode.

Remote Chrome DevTools

Yes, you can :) You need a fairly recent copy of Google Chrome running on your dev machine along with the ADT bundle.

TODO: these instructions work for content-shell, but testshell and android-webview is going to be slightly different; need to add section on how to debug testshell and android-webview.

First, remote shell into the device and add the command line switch to enable remote debug over USB:

$ adb shell
[email protected]:/ $

Content shell will read the file /data/local/tmp/content-shell-command-line at startup and apply whatever valid switches it finds. You can quickly create this file with the remote usb debug switch as follows:

[email protected]:/ $ echo chrome --remote-debugging-raw-usb > /data/local/tmp/content-shell-command-line

Connect your device with USB, and use ADT (or Gradle or command line tools, etc.) to start the content-shell Android application. Now, you need to setup adb port forwarding for the debug protocol. Execute this on your dev machine (not on the device itself):

$ adb forward tcp:9222 localabstract:content_shell_devtools_remote

Now, you can navigate to http://localhost:9222 using Chrome on your dev machine, and you should see the instance of content_shell -- you can inspect it and it will open up DevTools and allow you to remote debug.

GDB

You need root on your device. Specifically, if the command adb root works for you, you're in good shape. If not, you won't be able to debug native code. You'll also need to have built Chromium yourself (easiest way), as Google provides a suite of adb + gdb scripts that do all the heavy lifting for you to attach gdb over adb.

Consult those scripts for making this work. It would be nice to modify a version of those scripts to work with the build in this repo, but that is a task for another day (happy to take a pull request for this).

Pull Requests

Pull requests welcome to help improve the environment / shell scripts / build scripts. In Android, the project's namespace is important, and if you have multiple package namespaces with resources, then it becomes a PITA to resolve the R.java files. This is why I broke it out (one project per namespace) -- to avoid this problem. Some of the projects don't contain any resources, however, and they could really be merged into a single library, but I left them separate, as you never know if Google decides to add resources to a project, then this structure already works and requires no re-factoring.

Don't send pull requests for Google authored code b/c it will just be re-written on the next update -- unless you think it warrants saving -- in that case commit a copy of it to the modified sub directory of said project. Don't send pull requests for updates to Chromium, I'd prefer you just fork the repo and update those yourself.

Invaluable Resources