Sunday, September 26, 2010

Tokaplot

My latest app, Tokaplot, is now on the Android Market. This is a 2x1 widget which plots phone information over time. The information which can be plotted is (currently):

1. Battery level (in percent).
2. CPU % from /proc/stat
3. Free memory % (from /proc/meminfo)
4. Temperature (in Celsius, from the phone battery temperature sensor).
5. GSM signal (the phone cell signal strength in -dBm).
6. WiFi signal (also in in -dBm)
7. Network data received (in kB, from the difference between readings of /proc/net/dev)
8. Network data sent (in kB)
9. Gravity (in units of acceleration, this is the dot product of gravity and the vector orthogonal to the phone screen).
10. Magnetic field (in microTeslas, this is the magnitude of the total magnetic field).
11. Light (in Lux, from the phone light sensor).

The sampling rate, and hence plot length, as well as many graphics options can be changed allowing for a fully customisable plotting tool. Useful for showing your battery level usage or how much work your phone's doing!

Android really needs to make installing a widget clearer to stop people getting annoyed they can't 'run' a widget. The widget needs to be installed by long-pressing on an empty space on the home screen. It can then be chosen from the widget menu.

The widget works by asynchronously collecting samples. When the graph is updated, all samples are sorted into time bins, the bins being the size of the sample rate. These bins are then averaged, and the points are joined together. This can result in the graph looking too linear while the phone is asleep, so I plan to put in some smoothing in the future.

Hopefully the reading of the /proc/ information for the CPU and network stuff will work on all devices. This is done every minute at the moment. The load average is quite simple to read, but the network stuff needs a good deal of parsing. The network data counters work by splitting /proc/dev/net into lines, and summing the receive/sent byte columns of lines starting with 'rmnet' (which I think is GSM data) or 'eth' (which I think is WiFi data) .

For more widget sizes I've released Tokaplot +, which has 2x2, 4x1 and 4x2 sizes as well as extra customisation.

Update 1.0: First release version.

Update 1.1: Bugfixes and tidying.

Update 1.2: Added CPU load and tweaked UI.

Update 1.3: Added WiFi strength, also tweaked rendering and menu. Changed the sampling and added time smoothing. Re-wrote a lot of internals to make adding new plots much easier.

Update 1.4: Added network data counters, hope these work on all devices. Added a very fancy colour picker, which I've been meaning to write for ages. Also added longer ranges - now up to 3hrs (17 days total!). Also minor UI tweaking.

Update 2.0: Major, major update. Just about threw out all the old internals and re-wrote them. The data collection now works asynchronously, with new data points being added to a wrappable buffer. Each data value collected is given a timestamp, which is used to sort the data into bins. The bins are averaged and then the renderer does a join-the-dots to show the graph.

I'd also been using threads to run each widget. It turns out this is a bad idea. People complained of freezing, which I think was caused by this. Everything now is carried out on a task queue using Runnables. Simpler code, less overhead and no synchronization issues to worry about as it's all the same thread! Multiple widgets are also now properly supported.

Other things are the widget now properly supports Android 1.5-2.0, the renderer was re-written to take a list of points rather than just plotting whatever was in the buffer. The widget now updates when the phone wakes up and user preferences are saved. Finally some UI elements were added.

2.01: Minor tidies/fixes. Changed the graphline so it now goes off the left hand side of the plot. Caught a rare error where Android would hand a null pointer to widget update (why? Who knows?). Tried to improve the re-appearance of the widget after device restart, but really have no idea how Android handles this.

2.1: Added free memory % and big button to link to Tokaplot +. Sorry, I know I said no spam!

2.2: Important update. I'd assumed that services were naturally long-running, especially if their thread is being used frequently. Turns out this is not the case, and you have to tell Android your service is a long running service and shouldn't be killed. This requires you (in 2.0+) to put an annoying icon in the status bar. A fudgy way round this is to set the icon to blank and set the notification time really, really high. VoilĂ , no icon. This should fix all the freezing problems with the widget. I really should have read the Android Service notes more carefully..

2.21: Reduced thread priority to 1 to stop clashes with other long-running services such as music players.

2.22: Fixed a minor bug where the data plots would occasionally show large negative values.

2.30: Added battery current. Note: This will not work on most devices as they don't have this information! Tested on the HTC desire.

2.32: Added ability to lock widget. Also fixed a minor bug with free memory % calculation.

2.6 Finally found a way to remove the stupid notification!