Wednesday, September 22, 2010

PAW Performance

To test the performance of PAW on Android I created a small web app for PAW Runtime which basically takes a small picture (80x120px) and transforms it into a grayscale and sepia image.

Web App


The transformation was done with native code (compiled into the PAW runtime) and also with pure BeanShell code to get a feel how BeanShell performs.
Main reasons for doing the test were the reports about bad BeanShell performance.

The algorithms used for BeanShell and native code  were identical.
Here is the BeabShell code:

import android.graphics.*;
import android.graphics.Bitmap.CompressFormat;

file = parameters.get("file");
filter = parameters.get("filter");
sepia = (filter != null && filter.equals("sepia")) ? true : false;

depth = 20;

if(file != null) {
 bitmap = BitmapFactory.decodeFile(file);

 if(bitmap != null) {
  bitmap2 = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
  w = bitmap.getWidth();
  h = bitmap.getHeight();
  for(x=0; x < w; x++) {
   for(y=0; y < h; y++) {
    c = bitmap.getPixel(x, y);

    r = Color.red(c);
    g = Color.green(c);
    b = Color.blue(c);
     
    gry = (r + g + b) / 3;
    r = g = b = gry;
    
    if(sepia) {
     r = r + (depth * 2);
     g = g + depth;
    }

    if(r > 255) {
      r = 255;
    }
    if(g > 255) {
      g = 255;
    }

    bitmap2.setPixel(x, y, Color.rgb(r, g, b));
   }
  }

  bos = new ByteArrayOutputStream();
  bitmap2.compress(CompressFormat.PNG, 0 /*ignored for PNG*/, bos);
  byte[] bitmapdata = bos.toByteArray();

  request.sendResponse(bitmapdata, "image/png");
  request.out.flush();
  request.out.close();
 }
}


Here is the result after running the test:

Result


Actually BeanShell is much slower than I expected. But if you take into consideration what is happening behind the scenes it's not as surprising as it seems. There is a log of Java reflection, parsing, instantiations etc. going on.
Another result was, that the PAW server itself is performing nicely, which is a good sign.
So from a developer's point of view BeanShell code should be reduced to a minimum and native Android API should be used as much as possible.

What it also means is that, because the PAW Web App uses much BeanShell code, there is room for improvement...

To test it for yourself, download the latest PAW Runtime version and unpack the Image Manipulation ZIP file to your /sdcard/paw-runtime directory.

After that the following menu entry should be available in your PAW Runtime menu:

Menu Entry

Thursday, September 16, 2010

PAW Runtime

PAW Runtime is basically a stripped down PAW Server that only listens to the loopback interface on a random port and with a WebView serving as browser frontend.
With this set-up it is possible to run PAW applications directly on the device.

Everything that's possible with PAW Server is also possible with the runtime version.

Overview


It enables users and programmers to directly develop applications on the device without the need to install a SDK on the PC.
Because the GUI is defined via HTML development of the interface is easy for people that know HTML/CSS and JavaScript.

There are of course limitations to this approach concerning speed and using all features of the platform, but for developing small applications or prototypes this should be sufficient.
What is not possible is to develop individual apps, all PAW Runtime apps reside in the /sdcard/paw-runtime directory and are accessible (when defined in the webconf/apps directory) from the main menu screen.

The runtime itself comes with no applications, but demo applications are available for download.
Below is the main menu with installed demo applications.

Menu

Let's have a look at the compass app shown in the first image.

All applications are stored in the /sdcard/paw-runtime/html folder. The application consists of a XHTML file and the corresponding jQuery scripts and images. Together with the demos comes a html/common folder that contains components (like JavaScript files) that can be reused.

Let's have a look at the XHTML file:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>Compass</title>
<link rel="stylesheet" href="../common/css/default.css">
<script type="text/javascript" src="../common/js/jquery.js"></script>
<script type="text/javascript" src="../common/js/executeScript.js"></script>
<script type="text/javascript" src="js/jquery.rotate.js"></script>
<script type="text/javascript">
$(document).ready(function() {
updateCompass();
});

function updateCompass() {
executeScript('compassScript', null, 'compassRes');
$("#compassImg").rotate($("#compassRes").val() * -1, 'abs');
}
</script>
</head>
<body>
<center>
<h1>Compass</h1>
<img src="images/compass_rose.png" id="compassImg">
<p>
<div style="font-size: 30px; font-style: bold;" id="compass"></div>
</p>
</center>

<input type="hidden" id="compassRes" onChange="$('#compass').html($(this).val() + '°'); setTimeout('updateCompass();', 500);">

<!-- Script -->
<textarea id="compassScript" style="visibility:hidden; display: none;">
import de.fun2code.android.pawserver.AndroidInterface;

sensorListener = AndroidInterface.getSensorListener();
bearing = sensorListener.getOrientBearing();
$$.print(bearing);
</textarea>

</body>
</html>


The part that reads the bearing information of the device is surrounded by BeanShell <bsh>...</bsh> tags.
All the rest is standard HTML/JavaScript. A documentation of the functions provided by PAW comes bundled with the demo applications.

One last thing to do is to define the application's .conf file in the webconf/apps directory, so that the application is available from the main menu.

name=Compass
description=Displays Compass and Bearing
icon=compass/images/compass_rose.png
href=compass/compass.xhtml

APK Download: PawRuntime.apk
Demos Download: PawRuntime_Demos.zip
Eclipse Project: AndroidPawRuntime_Eclipse_Project.zip

Note: Files are based on PAW Server for Android 0.60 beta


The demos can be simply unpacked onto the /sdcard of the device.

PAW Runtime is currently in alpha state.
Comments are welcome...