Enabling the camera button in Android's emulator

I was trying to test the behaviour of phones with a camera button with my photography application, Instantanea. Since I don't have any phone with a physical camera button, I figured out I could use the emulator. It has a camera button, right?

Only it can't be clicked.

But it's Android... I have the source code! Would I be able to do something with it?

I first took a look at the skin I was using with my virtual device. I noticed there was a layout file in its folder. This file contains a mapping between a PNG image of the virtual controls and the corresponding keys. And as I was expecting, there was no mention of 'camera' at all.

I looked into all the other skins, using the mighty power of grep:

grep -lir "camera" *

but it didn't find anything. So I simply decided to add the mapping to the skin I am currently using, and see what happened. It's as simple as adding this:

camera {
        image button.png
        x 0
        y 0

to the <strong>buttons</strong> section of the layout file.

I then restarted the emulator, and when it finished loading, I saw with enormous joy that the button was finally <em>active</em>. I could hover it and it would show the familiar blue shade that the other buttons showed when the mouse was over them. I could even click it!

Yay! ... or nay?

It was actually <em>nay</em>. This error message in Logcat ruined it all:

Warning: skin file button uses unknown key name 'camera'```

So I did my favourite thing to do in these cases: googled for the error message. With a bit of luck it would show me the file where that was defined, and with a bit more of luck I'd be able to fix it, right? The file in question was external/qemu/android/skin/file.c (in android's git). I inspected it and saw that it defined a list of mappings (_keyinfo_table) which were used when loading the skin file, but again, there was no trace of 'camera' in the file.

I searched again for the camera string with grep, this time in the entire external/qemu/android directory, and this time I found several occurrences of it. Of all of them, the most interesting is external/qemu/keycode.h, since this one defines the key codes that are then used in file.c for parsing the mappings defined in the skins. And the good news is that the key code was already there:

kKeyCodeCamera                  = KEY_CAMERA,

... so that meant that the emulator might already know what to do when told that a camera button had been pressed. Therefore, I used that variable for adding a new line into file.c. Something as ridiculously simple as this:

{ "camera",       kKeyCodeCamera },

And then recompiled the emulator. To run it, I used the same trick I did the last time I applied a patch to it--I just took the newly compiled emulator in out/host/bin/ and copied it to the SDK tools folder (I had made a backup of the old executable before, don't worry ;-))

I restarted the emulator and verified that the camera key was still clickable --it was! And it didn't spit any error to Logcat. Even more--it worked with my application, that uses that button to (very sensibly) take a picture! Woohoo!

Of course, how silly would it be to fix this and not share it with you? So I learnt how to submit a patch to Android. With a project that big, they have created their own tool/website (gerrit) for managing patches and revising them, verifying them, etc. Which means there's a process--and it's a little bit ambiguous. The official instructions were slightly confusing, but with the help of this blog post by Johan de Koning I was able to submit the two patches required to make the emulator enable and process correctly the presses from the camera button. They still need to go through their approval process, but in the meantime you can apply them to your own copy of the emulator if you need to use the camera button and can't wait for the next release of the SDK :-)

Happy emulating everyone!