Android Issues

Android tweaks and workarounds

  • Normally you do not get to see the output on stdout and sterr of native applications (such as the phoneME VM) on your Android as those I/O streams are hidden from the user. I implemented a workaround by means of a simple wrapper with an Android Activity that acts as a console terminal that displays all input/output redirected from the phoneME VM.

  • I used the CodeSourcery toolchain to compile the phoneME VM. The advantage is that you do not need to build the Android sources to get a native toolchain for Android. But since the libc library of the CodeSourcery toolchain is different from that of Android, I had to statically link the phoneME VM. This causes some issues with network resolving. Methods like gethostbyname(), gethostbyaddr() and related methods do not work if you run the phoneME VM on a different libc environment. You get a warning about that at compile time when you statically link the cvm binary. I reimplemented those methods in the phoneME VM with proxies that delegate the work to the Android wrapper. A proper fix would link the phoneME VM against Androids' bionic libc library.

    [Network resolving issues are resolved by compiling with the Android cross-compiler toolchain and linking against the Android libc library. Note that you first need to check out and compile the Android source code.]

  • The framebuffer graphics backend in MIDP for running midlets cannot use /dev/fb0. There is an equivalent native framebuffer backend on Android called /dev/graphics/fb0, but it cannot be accessed directly as it needs root access. Furthermore, it would compete with the Android user interface that is also directly accessing the framebuffer and there is no way of locking the native framebuffer. Therefore, I added another Activity that acts as a virtual framebuffer and implemented a virtual framebuffer backend in the phoneME VM that talks to this virtual framebuffer Activity.
    The phoneME VM uses fifos to send framebuffer updates to the virtual framebuffer Activity. The Activity takes care of the 16-bit to 32-bit RGB color conversion when drawing the frames. As expected, the refresh rate for framebuffer updates is subpar compared to a memory mapped framebuffer backend. Another minor issue is that the size of the framebuffer is currently hardcoded and that flipping the orientation of your Android device does not have the desired effect.

    [The slow framebuffer updates were first fixed by using the SurfaceFlinger accelerated graphics backend. Unfortunately, recent Android editions require applications to be signed with the phone's manufacturer's key to get this kind of hardware access. The Android wrapper
    application now paints a bitmap to a SurfaceView with direct access to the bitmap's pixels]

  • Installing the Android wrapper and the phoneME VM is not straightforward. When packaging the Android wrapper into an apk package, I first included the cvm binary as an Android Asset. Before executing a J2ME application, I save the phoneME VM to a writeable area on the Android filesystem and run the application. Unfortunately, the maximum size of an Android Asset defined by UNCOMPRESS_DATA_MAX can range from 1MB to 4MB depending on the device. The cvm binary is larger than 1 MB, so on some systems the Android wrapper will fail to unpack the asset. Currently, I use the adb utility of the Android SDK to push the phoneME VM to the Android device. Another approach is to download the phoneME VM from the web the first time you run a J2ME application. Having a shared linked phoneME VM might also reduce its footprint.

    [This has fixed by splitting up the binary in smaller chunks and have the Android wrapper assemble them again while
    saving the binary on the filesystem.]