Sunday, December 05, 2010

Loopers, MessageQueues, and Handlers (Part1)

Loopers, MessageQueues, and Handlers provide one of the facilities for processes and threads to communicate with each other. They are also one of the basis to implement the Services of Android framework. The relationship between these classes and how they interact with each other are not so easy to be seen through at the first glance. And that's why there are so many articles talking about them. This post does not intend to show they are used, but focus on the relationship between them.

Sunday, June 20, 2010

Log of instructions for JNI


Reference:
Edit HelloWorld.java
HelloWorld.java

class HelloWorld { private native void print(); public static void main(String[] args) { new HelloWorld().print(); } static { System.loadLibrary("HelloWorld"); } }
Compile the JAVA class -- HelloWorld.class
  $ javac HelloWorld.java
Generate the NATIVE header file -- HelloWorld.h
  $ javah -jni HelloWorld
HelloWorld.h

/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class HelloWorld */ #ifndef _Included_HelloWorld #define _Included_HelloWorld #ifdef __cplusplus extern "C" { #endif /* * Class: HelloWorld * Method: print * Signature: ()V */ JNIEXPORT void JNICALL Java_HelloWorld_print (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif
Implement the NATIVE method -- HelloWorld.c
HelloWorld.c

#include <stdio.h> #include <jni.h> #include "HelloWorld.h" JNIEXPORT void JNICALL Java_HelloWorld_print (JNIEnv *env, jobject obj) { printf("Hello World\n"); return; }
Compile the NATIVE source code and build the NATIVE library
  $ gcc -c -fPIC HelloWorld.c -I$JAVA_HOME/include -I$JAVA_HOME/include/linux
  $ gcc -shared HelloWorld.o -o libHelloWorld.so
Add "current" directory to the search path of share libraries
  $ export LD_LIBRARY_PATH=.
Run the HelloWorld JAVA program
  $ java HelloWorld

Hello World

Saturday, June 12, 2010

Taking a snapshot of Android device

We can dump the framebuffer of a android device and save it as a file on our host in one single step:
  $ adb pull /dev/graphics/fb0 fb.dump
The dumped raw data is in RGB565 pixel format. So we'd like to convert it into a more common image format that could be recognized by common image viewers.
And FFMPEG could be handy for doing the conversion like this:
  $ ffmpeg -f rawvideo -pix_fmt rgb565 -s 320x480 -i fb.dump output%d.png
In this case, more than one images might be generated and named output1.png, output2.png, etc. This happens because the framebuffer on android is required to support page flipping, and the backed buffer can be dumped from the /dev/graphics/fb0 as well.

Alternatively, we can use the fbgrab utility to do the conversion:
  $ fbgrab -f fb.dump -w 320 -h 960 -b 16 output.png
Here we explicitly specify the width, height(x2 for the backed buffer), and color depth. In this case, we get a single image which is composed by two cascaded snapshots.

Of course we can also cross-compile the fbgrab utility and have it take the snapshot directly on the target device, and then pull it back with adb.
  $ fbgrab -d /dev/graphics/fb0 output.png
However, the only benefit with this, I think, is saving some time to type the dimension of the framebuffer, since the fbgrab would figure it out with IOCTL on the device node.

Estimating memory usage on Android and Linux

Earlier kernels export Rss and Vss of each single process to show how many page frames it occupies and how the address space it spans on a particular time. But this information is process-wide, and it doesn't help when you estimate system-wide memory usage. The problem is the lacking of information about how the processes share pages with each other. Simply summing up the Rss of all processes would over calculate the number of pages shared by multiple processes.