Introducing MozillaView - GeckoView Proof of Concept

Over the past couple of months, I've been working on making the Pluggable Webviews a feature with more than one webview, which led me down the path of adding GeckoView to Cordova. The thing with GeckoView is that it is not a Chromium-based webview like the default Android WebView, the WebView in Android 5.0, the WebView used in Amazon FireOS, or the Crosswalk WebView that I demoed at OSCON and PhoneGap Day US. Instead, this is based on Gecko, which is the core technology behind Firefox, Firefox OS and Firefox for Android.

There were a lot of technical challenges involved, but this blog is going to talk mostly about the general architecture of the Multiple WebView featue as it exists today, and how we managed to shoehorn in GeckoView.

The Architecture

Right now we have an interface called CordovaWebView, which will most likely be renamed CordovaWebInterface. This provides the basic surface that is required for the view to operate as a view. It would be great if mulitple inheritance was a thing, then it would be possible to guarantee that every CordovaWebInterface implemented the View class and could be used as a stand-alone component, but we are not at that point today. I recommend that this be the case, as it is with MozillaView and the default Android WebView but this is not the case with Crosswalk.

At any rate, any class that implemnts the WebInterface will be able to be loaded by the CordovaActivity based on a setting in config.xml which specifies the class that will be loaded. If no class is loaded, then the default Android WebView is loaded, and Cordova works now like it has in the past.

However, if you do load the class, then the class is loaded instead, and the basic methods are run so that the class can intialize itself and display on the screen. In this case, this means that MozillaView, which extends the GeckoView, has to create a browser to associate itself with, and create a Chrome object and a content object. These objects are what are required to run the bridge.

We requested a bridge from the Chrome team to allow us to get our Cordova plugins to work with GeckoView, and we have something that's prety cool. Instead of blindly bolting on Java objects, GeckoView allows messages to be passed through the Chrome object via a registered JS file which unlike most of the code that Cordova currently runs has modern Javascript features such as promises. I know that I wasn't a big beliver in promises when I encountered this, but as an alternative to the synchronous nature of the addJavascriptInterface method, this is a much better way to handle this. Because, even if you're polling the object to get a result, you can handle the result asynchronously and there's less cahnce of blocking if the plugin implementer does something stupid like not use a thread from the thread pool to do non-trivial work.

Overall, I really think this approach works better and has less code overall than the hacky approaches that we've had to do in the past with Chrome, such as use timeouts because of the brittleness of addJavscriptInterface. This has definitely been a learing experience and I hope other people look at this code as well, since there's some interesting things to be found here.

What's this work on?

MozillaView works on Android 2.3 all the way up to Android 5.0. We obviously can't guarantee that things will work at that point. This code does require a special version of cordova-js that can be found on my Github repo. Of course this relies on Nightlies so it can break at any time.

Of course, the actual plugin can be found in my repository here

What's next

I'm interested in adding other PoC webviews in the new year, such as the new library that's used in the Krypton Browser (BTW: Please stop calling everything Krypton! Every second tool that I look at using is called Krypton! It's confusing me.), or play with Servo and try to shoehorn it in. That said, I might take a break from the WebView stuff and do work I can't blog about. In that case, I'll probably just fill this with my open hardware and radio hobbies.