Sunday, January 18, 2009

NetMeter

My third android application grew out of the frustration for not knowing what is going on with device behind my back. Many of the early apps - probably written on the emulator or with little field test and experience on real devices are pretty aggressive in resource usage - some of them in the background. From my own experience with Android programming, it can be pretty hard sometimes not to mess up and do something which is very power-consuming merely by accident. Mobile programming requires a particular style and attention to resource efficiency, which many programmers from a desktop/server background are not used to.

NetMeter makes use of data from the /proc filesystem of the linux kernel which is deep underneath the Android platform. As opposed to using supported and documented APIs this is quite a bit more hacky and uncertain to work on any device or even future releases. On the other hand, the /proc filesystem is a pretty standard mechanism for making kernel state accessible to userspace applications.

When running, NetMeter collects cellular and wifi send & receive traffic stats as well as total CPU utilization at a fairly aggressive rate and collects the data in memory. The application's main activity display the most recent measurements as numbers in a table on top of the screen and plots the history of sampled network rates and CPU utilization as graphs on the bottom.

The last part of the application is an activity screen which shows the CPU utilization broken down by process. This is basically a re-implementation of the very useful unix command top, which can also be run on Android through the adb shell application. Getting this to work was a bit tricky, but looking at the actual source for top command for the android environment helped quite a bit.

I wanted the application to be able to run in the background as the user is doing something else in the foreground, which might cause some traffic or CPU impact that should be analyzed. On the other hand, I didn't want the app to install itself as a service and run all the time, like many others do since it would have an unacceptably high system load given its heavy polling. The model should be the same as for the media player application which can be started and which "iconizes" itself to the status bar while running in the background and which can be brought back by selecting that icon in the status bar to eventually stop it explicitly from the menu of the main activity. I think that would be a nice model for user driven application which need to run in the background - giving the user a maximum of control. From the feedback on the Android Market, some users seem to disagree, asking for automatic startup and continuous running in the background, since the feel that a traffic monitor is something which should be running all the time. NetMeter was intended as a diagnostic and trouble-shooting tool and not for continuous usage tracking and accounting. Maybe there is need for another application (NetCounter seems to be a pretty good match for that).

To get this kind of life-cycle behavior, the main activity starts up a local in-process service if it is not already running and binds to it. All data collection happens within this service and all the activity does whenever it is started is to pass a reference to its display views to the service to be updated whenever the service does a new measurement. The service also posts the icon notification into the status bar whenever it is running, which in turn triggers the main activity to be run. This basically makes the application appear to be "iconized" in the status bar, like in many classical desktop environments. The core of this code is based on the local-service example from the API samples section of the Android documentation.

The application is open-source and can be found at http://code.google.com/p/android-labs/source/browse/trunk/NetMeter