Vladimir Vukićević — Words
 



I’ve been looking to understand the Android OS better, so that I can answer some questions and create plans for getting Gecko/Firefox running on Android-based devices.  One of the first questions I asked was, “How do Android apps start?”  They’re clearly separate processes while they’re running, but it wasn’t clear how they were launched.  It turns out, there are a couple of pieces here.  I’m going to describe what I’ve discovered here, in case it’s useful for someone else; I haven’t been able to find much of this information, largely because I don’t think many people need to know any of this.

At boot time, a special instance of the Java VM is launched, called the Zygote.  This process loads a bunch of the core Java classes and performs initial processing of them, making it possible to avoid this step for each app launch.  Once the initial work is done, the process listens to a socket and waits for requests.

To launch an app using the Zygote process, a command-line tool called “dvz” can be used.  It sends its arguments to the Zygote, which will fork and then start executing the main method in a given class.

So, we have these steps, dealing with the Zygote process:

But, that’s not fully how a new Android Activity is started.  It’s a bit of a roundabout process.  To launch a new Activity, the ActivityManagerService is notified with an activity start request, including things like the name/class/etc. of the activity.  It puts that information in a list of activities to run.  Then, a new process is started with the main from ActivityThread.  This new process then contacts the ActivityManagerService and asks, essentially, “what app am I?”.  The service then gives it the name of its activity class and other info, which is then loaded, and a message is enqeued on the main thread to instantiate the new activity and send it an onCreate() message.

This is interesting because it means that apps are not launched directly, but instead somewhat indirectly through specializing a generic “Activity” process for a specific activity.  A side effect of this is that I couldn’t find a way to actually register an app with the ActivityManagerService if it wasn’t launched by it.  So, to be a full Android app, you have to go through this normal startup process.

JNI Bridging

One of the difficulties in porting Gecko to Android is that the Android platform is built around Java, whereas Gecko is very much all native C/C++.  However, there is a fairly good native bridge layer, JNI, which is fairly heavily optimized by Dalvik.  So, the simplest way to connect these two is to write a shell app in Java, which bridges events, messages, paint requests, etc. to the native code for handling.

As a proof of concept of this, I wrote a simple test app.  It’s fairly straightforward, with a few wrinkles.  Most of this stuff can be done with the stock Android SDK and NDK — except painting.  The only API that the NDK exposes for graphics is OpenGL ES.  This is fine, but in some cases you may want to access Skia directly from native code.  This is possible, but requires version-specific code to accomplish.  You can ship multiple versions of your JNI glue layer, optimized for each Android version (or even platform), and load the right one during your app startup on the Java side.

This is, of course, not very portable, robust, or guaranteed to continue to work by Google, but it’s possible.  There are some very rough hacks in the test app, but for the most part it demonstrates that this approach can work fine.

Next up, I’ll probably blog about porting issues for large native apps, including library compatibility, Bionic, and integrating into a non-ant-based build system.


4 Comments to “Android Hacking (Part 1 of probably many)”  

  1. 1 Ibrahim

    Awesome, I intend to get a Droid when my Verizon contract is up, would be awesome to have Fennec and Firefox on it. Plus I’m looking into Android dev as well and while this is probably lower level than the average Android program would need to be, it’s a very interesting look at Android internals. I’ll look forward to more of these in the future.

  2. 2 eli yukelzon

    very interesting and in depth stuff. please keep posting your findings.
    good articles on android internals are far-in-between.

    cheers

  3. 3 jmdesp

    Vladimir, you are simply amazing ! I’m impatiently waiting for what will come next.

  4. 4 Sean

    Hello!

    I am going to be purchasing the Moto Droid in the new year and I’d LOVE to see a Firefox browser available on Android. Keep fighting the good fight! I’ll be following closely.

    Sean