Bend it like Bluemix, MongoDB using Auto-scaling – Part 2!

This post takes off from my previous post Bend it like Bluemix, MongoDB using Auto-scale –  Part 1! In this post I generate traffic using Multi-Mechanize a performance test framework and check out the auto-scaling on Bluemix, besides also doing some rudimentary check on the latency and throughput for this test application. In this particular post I generate concurrent threads which insert documents into MongoDB.

Note: As mentioned in my earlier post this is more of a prototype and the typical situation when architecting cloud applications. Clearly I have not optimized my cloud app (bluemixMongo) for maximum efficiency. Also this a simple 2 tier application with a rudimentary Web interface and a NoSQL DB at This is more of a Proof of Concept (PoC) for the auto-scaling service on Bluemix.

As earlier mentioned the bluemixMongo app is a modification of my earlier post Spicing up a IBM Bluemix cloud app with MongoDB and NodeExpress. The bluemixMongo cloud app that was used for this auto-scaling test can be forked from Devops at bluemixMongo or from GitHib at bluemix-mongo-autoscale. The Multi-mechanize config file, scripts and results can be found at GitHub in multi-mechanize

The document to be inserted into MongoDB consists of 3 fields – Firstname, Lastname and Mobile. To simulate the insertion of records into MongoDB I created a Multi-Mechanize script that will generate random combination of letters and numbers for the First and Last names and a random 9 digit number for the mobile. The code for this script is shown below

1. The snippet below measure the latency for loading the ‘New User’ page
def run(self):
# create a Browser instance
br = mechanize.Browser()
# don"t bother with robots.txt
print("Rendering new user")
br.addheaders = [("User-agent", "Mozilla/5.0Compatible")]
# start the timer
start_timer = time.time()
# submit the request
resp ="")
#resp ="http://localhost:3000/newuser")
# stop the timer
latency = time.time() - start_timer
# store the custom timer
self.custom_timers["Load Add User Page"] = latency
# think-time

The script also measures the time taken to submit the form containing the Firstname, Lastname and Mobile

# select first (zero-based) form on page
# Create random Firstname
a = (''.join(random.choice(string.ascii_uppercase) for i in range(5)))
b = (''.join(random.choice(string.digits) for i in range(5)))
firstname = a + b
# Create random Lastname
a = (''.join(random.choice(string.ascii_uppercase) for i in range(5)))
b = (''.join(random.choice(string.digits) for i in range(5)))
lastname = a + b
# Create a random mobile number
mobile = (''.join(random.choice(string.digits) for i in range(9)))
# set form field
br.form["firstname"] = firstname
br.form["lastname"] = lastname
br.form["mobile"] = mobile
# start the timer
start_timer = time.time()
# submit the form
resp = br.submit()
# stop the timer
latency = time.time() - start_timer
# store the custom timer
self.custom_timers["Add User"] = latency

2. The config.cfg file is setup to generate 2 asynchronous thread pools of 10 threads for about 400 seconds

run_time = 400
rampup = 0
results_ts_interval = 10
progress_bar = on
console_logging = off
xml_report = off
threads = 10
script =
threads = 10
script =

3. The code to add a new user in the app (adduser.js) uses the ‘async’ Node module to enforce sequential processing.

collection = db.collection('phonebook', function(error, response) {
if( error ) {
return; // Return immediately
else {
console.log("Connected to phonebook");
callback(null, 'one');
// Insert the record into the DB
"FirstName" : FirstName,
"LastName" : LastName,
"Mobile" : Mobile
}, function (err, doc) {
if (err) {
// If it failed, return error
res.send("There was a problem adding the information to the database.");
else {
// If it worked, redirect to userlist - Display users
// And forward to success page
collection.find().toArray(function(err, items) {
console.log("**************************>>>>>>>Length =" + items.length);
db.close(); // Make sure that the open DB connection is close
callback(null, 'two');

4. To checkout auto-scaling the instance memory was kept at 128 MB. Also the scale-up policy was memory based and based on the memory of the instance exceeding 55% of 128 MB for 120 secs. The scale up based on CPU utilization was to happen when the utilization exceed 80% for 300 secs.


5. Check the auto-scaling policy


6. Initially as seen there is just a single instance


7. At around 48% of the script with around 623 transactions the instance is increased by 1. Note that the available memory is decreased by 640 MB – 128 MB = 512 MB.


8. At around 1324 transactions another instance is added

Note: Bear in mind

a) The memory threshold was artificially brought down to 55% of 128 MB.b) The app itself is not optimized for maximum efficiency


9. The Metric Statistics tab for the Autoscaling service shows this memory breach and the trigger for autoscaling


10. The Scaling history Tab for the Auto-scaling service displays the scale-up and scale-down and the policy rules based on which the scaling happened


11. If you go to the results folder for the Multi-mechanize tool the response and throughput are captured.

The multi-mechanize commands are executed as follows
To create a new project
multimech-newproject.exe adduser
This will create 2 folders a) results b) test_scripts and the file c) config.cfg. The needs to be updated as required

To run the script
multimech-run.exe adduser

12.The results are shown below

a) Load Add User page (Latency)

Load Add User Page_response_times_intervals

b) Load Add User (Throughput)

Load Add User Page_throughput

c)Load Add User (Latency)

Add User_response_times_intervals

d) Load Add User (Throughput)

Add User_throughput

The detailed results can be seen at GitHub at multi-mechanize

13. Check the Monitoring and Analytics Page

a) Availability


b) Performance monitoring


So once the auto-scaling happens the application can be fine-tuned and for performance. Obviously one could do it the other way around too.

As can be seen adding NoSQL Databases like MongoDB, Redis, Cloudant DB etc. Setting up the auto-scaling policy is also painless as seen above.

Of course the real challenge in cloud applications is to make them distributed and scalable while keeping the applications themselves lean and mean!

See also

Also see
1.  Bend it like Bluemix, MongoDB with autoscaling – Part 1
3. Bend it like Bluemix, MongoDB with autoscaling – Part 3

You may like :
a) Latency, throughput implications for the cloud
b) The many faces of latency
c) Brewing a potion with Bluemix, PostgreSQL & Node.js in the cloud
d)  A Bluemix recipe with MongoDB and Node.js
e)Spicing up IBM Bluemix with MongoDB and NodeExpress
f) Rock N’ Roll with Bluemix, Cloudant & NodeExpress

a) Latency, throughput implications for the cloud

b) The many faces of latency

c) Design principles of scalable, distributed systems

Disclaimer: This article represents the author’s viewpoint only and doesn’t necessarily represent IBM’s positions, strategies or opinions

Test driving Push notification in Bluemix

This post is a continuation of my earlier post ‘Getting started with mobile cloud in Bluemix‘. Here I take a test drive of the push service that Bluemix offers based on the article “Extend an Android app using the Push cloud service” from developerWorks.

This post assumes that you have already completed the changes from my earlier post for the mobile cloud. If you haven’t,  you could clone the code from “mobile data” which is the official IBM version of this app and includes all the changes needed for persisting data in the cloud through their Android.

The Mobile Cloud App I created on Bluemix is “mobtvg“. The main steps to have Push notification service using Bluemix are

  1. GCM services : Get Google API Project number  & GCM API Key
  2. Include the Google Play services library project
  3. Add the jar files to enable Push service
  4. Modify the server side Node.js file to send push notifications to all registered devices
  5. Make necessary code changes
  6. Run the application and test for notification

Here are more details on the above steps

a) GCM services : Google Cloud Messaging for Android (GCM) is a service that allows you to send data from your server to your users’ Android-powered device, and also to receive messages from devices on the same connection. The 1st thing to do is get the Google API Project number & GCM API key.

– Click on Google Developer Console

– Click Create Project. Enter Project name & click Create.

– Note the Project Number on top of the page.

– Click API & Auth on left panel. Click API.

– Scroll down and turn-on Google Messaging for Android

–  Click credentials and click “Create new key”. Click server key. Click create

-Copy API key in the Public API access

Now go the Bluemix dashboard and click your application. Click the Push module. In the Configuration tab, scroll down to Google Cloud Messaging and  click ‘Edit’

Enter the Google API Project Number & GCM API key for both the Sandbox & Production configuration and click Save.

b) In Eclipse click Windows->Android SDK manager. Scroll down to the bottom and under Extras select Google Play services. Click install. Once the installation is successful import the project as follows File-Import->Android->Existing Android  code into Workspace. Click Next. In the next screen Browse to the path where your ADT bundle is installed and choose the folder

<ADT-Bundle>\ sdk\extras\google\google_play_services

and Click Ok. Also  check ‘Copy project into workspace’. This will copy.


Now build the Google Play Services Project. To do this the project. Click Project->Properties->Android and make sure that you select ‘Is library project’ and then click build.


Add a reference to the Google Play services in the Androidmanifest.xml



android:value=”@integer/google_play_services_version” />

c) Make all the code changes given in Step 4 of “Extend an Android app using the Push cloud service.

d) In make sure you change the app_name to the name of your app for e.g

public static final String CLASS_NAME = “MainActivity”;

public static final String APP_NAME = “mobtvg“;

Also ensure that under assets folder you have populated the Application ID in the file

applicationID=<Application ID from Bluemix>

d) Add ibmcloudcode.jar, ibmpush.jar, android-support-v4.jar (from <Android_SDK_Location>/extras/android/support/v4)

e) Now the Mobile Push project need to include this library project. To do this select your Mobile App project. Click Project->Properties->Android. Click Add and select google-play-services-lib. Note: Make sure “Is library project” is unchecked otherwise you are in for a lot of grief.


f) Now you need to make changes to the Node.js application to push any changes from the server to all registered devices.  The code for this is in bluelist-push-node. Note; Making changes through the GUI results in an error that “manifest.yml is not in root node”. So I suggest that you take the ‘cf’ route as follows.

– Clone the code using Git

git clone

Go to bluelist-push-node folder

i) Open the app.js with your favorite editor and enter the Application ID of your Bluemix application

//Data Values

var values = {


//change this to the actual application id of your mobile backend starter


host : “;


ii) Open manifest.yml and change host name & name to the name of your application for e.g.

host: mobtvg

disk: 1024M

name: mobtvg

command: node app.js

path: .


mem: 128M

instances: 1

iii) Once the changes are complete, open a command propmpt and  login into Bluemix using ‘cf’ as follows

– cd to the directory in which Node.js & manifest.yml exist, Do

cf login – a

cf push mobtvg -p . -m 512M

(Note the changes are pushed to the mobile cloud app on Bluemix)

This will run through and finally give the status that the app is running successfully.

f) Now that all changes are complete the Mobile Cloud with Push can be tested..

g) Click Window->Android Virtual Device Manager. Click the Device definitions. You choose Google Nexus, Nexus 7. Click Create AVD.

Note: Make sure you choose Google API Level Y and not Android x.x.x API Y.


Let the AVD come up and display the current items in the grocery list.

h) Login to Bluemix. Click Push and select the Notifications tab and enter a test message for e.g. “This is a notification from Bluemix” and click send.


This will result in a Push Notification to be sent to the AVD. You should see this popup on you AVD as shown below


i) Add another AVD through Windows-Android Virtual Device manager. While one AVD is running go to Run->Run Configurations->Target Device and choose the newly created AVD.

j) This will start a second AVD which will refresh with the contents of the grocery list. Now adda new item in one of AVD devices. This will result in a Push notification to the other device that the Bluelist has been updated.


There you have it.

1) A mobile cloud applications in which changes persist in the cloud and are refreshed each time the Android device is restarted.

2) A Push notification that is sent to all registered devices whenever there is a change to the list.

Disclaimer: This article represents the author’s viewpoint only and doesn’t necessarily represent IBM’s positions, strategies or opinions

Find me on Google+

A method to crowd source pothole marking on (Indian) roads

In, India, roads and potholes are 2 sides of the same coin! You cannot think of one in exclusion of another. This post of mine looks at a novel technique of rapidly identifying & marking potholes in (Indian) roads. This approach can be used for any city in the world but is very pertinent to Indian roads.

This idea of mine provides a technique of quickly marking pothole in roads through the method of crowd sourcing


Introduction: It is a well known fact that Indian roads are riddled with potholes. Some may even say that there are potholes with patches of road in between them. This disclosure looks at a novel technique of rapidly identifying & marking potholes in (Indian) roads. The approach can be used for any city in the world. However this disclosure will focus on Indian roads. This disclosure proposes a novel technique of crowd-sourcing the marking of potholes on roads rather than having any single government body (NHAI etc) travel on roads to make the markings.

Description: This post proposes a novel crowd-sourced method for pothole marking that will be easy to conduct and extremely rapid The crowd-sourced pothole marking application will be made of the following components namely Pot-hole marking app, Backend server, Map Matching utility, Pothole ranking utility.

Pothole marking App: A location based smartphone app will need to be created preferably both on Android and iOS. The app will display the map with buttons to mark the following

a)   Points in map of potholes

b)   Bad segments of roads with potholes

Backend Server: The backend server will collect all the data (marked potholes) and bad segments of roads and will update a database.  A map-matching utility will map the latitude, longitude of the marked point on to a map. When the geographical location of a pothole is received (latitude, longitude) the backend server will also store the time stamp.

Pothole ranker: This module will run on a periodical basis, say once every 3 minutes. This module will determine all the potholes that have been entered in the last 3 minutes and add to the accumulated count of marked potholes. Each marked pothole will hold the count of the marks and also the time stamp of the mark. It will also rank the criticality of the pothole based on the accumulated count of potholes over the period.

The pothole ranker will maintain the following metrics

  1. Pothole criticality = Total accumulated count/ Total time
  2. Pothole impact measure = Max rate of pothole marks (Pothole marks/hr)
  3. Bad stretches of roads with many potholes =

Number of adjacent potholes/ Distance in meters


Description: This how the scheme will work in practice. The app will be uploaded into Google Play and Apple’s App store.  All users who would like to participate in the pothole marking exercise can download and install the app on their smart phones. These users when they are traveling on a road can mark potholes as they encounter them. It is assumed that the users are passengers in vehicles or pillion riders. The fact that users all over the city can simultaneously mark potholes as they encounter them will make the gathering of pothole data rapid and extremely accurate. A map of a city would need to be generated with the circles/points for locations of potholes, color-coded appropriately. We could use the color red for higher ranked potholes and yellow for lower ranked potholes with intermediate colors like purple, pink etc.  This data can then be used by Government bodies in addressing roads in fixing the roads.

There are three advantages of crowd sourcing the pothole marking

1)   The process of gathering data is rapid

2)   Roads where the traffic is heaviest will have potholes with a higher rank and can be addressed first

3)   The process will be very accurate

Crowd sourcing of pothole marking will have the following benefits

  1. The marking of potholes will be extremely rapid
  2. The potholes will be ranked based on accumulated count
  3. Ranking of potholes can be done on

– Total accumulated count/Total time

– Rate of pothole mark

– Critical segments with major potholes

4. It will be easy to segregate

– Critical potholes
– Max impactful potholes
– Bad road segment

  1. The process will be very accurate

Conclusion: The process of crowd sourcing pothole marking of Indian roads will be extremely efficient in marking potholes and bringing it to the attention of the Government.

A map of a city with the circles for locations of potholes, color-coded appropriately, to indicate higher marked potholes versus the lower ranked potholes could be generated. This map can be used to bring to the attention of the government the really bad roads and terrible road segments. Rather than having a couple of vehicles trying to ply roads and mark roads this will be very fast and extremely accurate.

Afterword: The concept of crowd sourcing for traffic is not new. Waze, which Google bought for close to $2bn does just that. It crowd sources traffic conditions and alerts users of the app. Also I did a Google search on using mobile apps for potholes marking and, not surprisingly, there were others who had also thought of a similar idea in Boston & Florida see the links below


However, I personally think that the situation in India is different, where there are ‘roads in between potholes’ ;-). While in the above 2 cases in US, only the location of the potholes is important, my idea ranks potholes based on the accumulated count and the rate of pothole marks. These metrics can be used by the government in addressing those sections of roads where the potholes have a higher rank i.e. where the traffic is highest.

Your thoughts are welcome.

Find me on Google+

Unity(full) android App: With bells and whistles

In this post I discuss a fairly complete Android App – Unity which is a simple unit converter. The android app has all the good stuff from Android including activities, intents, spinners, launch icons and a splash screen to boot as below. Download it from Google Play : Unity – Unit Converter . To know more about the app read on …


I have enhanced my earlier basic Unity app to start with a Splash Screen before moving onto an initial screen with buttons for various unit conversion like mass,length,volume etc

This is shown below


When any of these buttons are clicked it goes to the appropriate conversion screen. This is done by starting the appropriate activity. An activity is invoked by the intent which starts the activity.

Hence the has an intent and activity for each of the buttons mass,length,volume in the addListenerOnButton as follows

publicvoid addListenerOnButton() {

//Mass activity

massButton = (Button) findViewById(;


massButton.setOnClickListener(new OnClickListener() {

publicvoid onClick(View arg0) {

Intent intent = new Intent(context, massActivity.class);




//Length activity

lengthButton = (Button) findViewById(;


lengthButton.setOnClickListener(new OnClickListener() {

publicvoid onClick(View arg0) {

Intent intent = new Intent(context, lengthActivity.class);




When the “Mass button” is clicked it activates a new intent based on the class.

The file performs the following main functions

  1. Changes the layout to the one defined in mass.xml under res/layout.mass.xml
  2. Instantiates a massAdapter as an ArrayAdapter
  3. Passes the massAdapter to both the spinners in the View
  4. A convert method is invoked when the Convert button is clicked. This method does the actual calculation
  5. Finally a ‘Home’ button is used to go back to the MainActivity class

publicclass massActivity extends Activity {

String[] massUnits = {“gram”,“kilogram”,“ounce”,“pound”,“ton”};

//double massConversion[][] = new double[5][5];

doublemassConversion[][] = newdouble [][]{







protectedvoid onCreate(Bundle savedInstanceState) {

ArrayAdapter<String> massAdapter = new ArrayAdapter<String> (this,


sp1 = (Spinner) findViewById(;


sp1.setOnItemSelectedListener(new OnItemSelectedListener() {

publicvoid onItemSelected(AdapterView<?> argo0, View arg1,

int arg2, long arg3) {

intitem = sp1.getSelectedItemPosition();


publicvoid onNothingSelected(AdapterView<?> arg0) {



sp2 = (Spinner) findViewById(;


sp2.setOnItemSelectedListener(new OnItemSelectedListener() {

publicvoid onItemSelected(AdapterView<?> argo0, View arg1,

int arg2, long arg3) {

intitem = sp2.getSelectedItemPosition();





publicvoid convert(View view) {

double inputValue = Double.parseDouble(text1.getText().toString());

int item1 = sp1.getSelectedItemPosition();

int item2 = sp2.getSelectedItemPosition();

double value = massConversion[item1][item2];

double convertedValue = inputValue * value;



The Home button takes back to the Main screen

publicvoid home(View view) {

final Context context = this;

Intent intent = new Intent(context,




The mass.xml screen has 1 Textfield for input, a TextView for output, 2 spinners for handling the fromUnit & toUnit and a Convert & a Home button. The mass.xml is shown below

<TableLayout xmlns:android=;


android:layout_height=“fill_parent” >




android:layout_height=“wrap_content” >








android:textAppearance=“?android:attr/textAppearanceMedium” />








android:inputType=“numberDecimal” />





android:text=“@string/convertedValue” >


















android:text=“@string/Convert” />



android:text=“@string/home” />




Note: Ensure that you add this new activity massActivity to AndroidManifest.xml

As shown




android:label=”@string/app_name” >




Similar code can be replicated for the other buttons and other conversion units.

Once this is done your application is ready. It is now time to create a suitable “icon” for your android app. I found GIMP utility extremely useful in creating icons. GIMP cam be downloaded from This requires some learning ramp-up. So I took the easy route and downloaded ready made icon from which has a huge collection of icons.

The specified dimensions for the icons based on the resolution of the android device is given in

and should be

  • Low density screens (ldpi): 36x36px, 120dpi
  • Medium density screens (mdpi): 48x48px, 160dpi
  • High density screens (hdpi): 72x72px, 240dpi
  • Extra high density screens (xdpi): 96x96px, 320dpi

Copy all the icons to the directory below and rename the png files to ic_launcher.png

  • Low density icon : res/drawable-ldpi
  • Medium density icon : res/drawable-mdpi
  • High density icon : res/drawable-hdpi
  • Extra high density icon : res/drawable-xdpi


It is worth mentioning a problem that I faced initially and had me stumped. I would make some changes and get the error “R cannot be resolved to a variable”.

AftertryingtounsuccessfullycleanandrebuildtheprojectseveraltimesItriedtodiginmore.MysearchwithGoogleprovedfutilewithsomepostscomplainingthatEclipsewasclobberingfiles.TheissueusuallyhappenswhentheR.javafilecannotbegeneratedwhenyoubuildtheproject.Thisusuallyhappenswhenthereissomeissueinyour /resdirectory.Checkifthereareanyredmarksinyourlayout,strings.xmlorAndroidManifest.xmletcfile, fixthem, rebuild and theproblemshouldgoaway.

Finally I added an initial splash screen. For this I took the code from O’Reilly’s cook book “Splash screens in Android”. A splash *.jpg or *.png has to be added to the res/drawable folders

Remember to change the AndroidManifest.xml to have the app open up with the splash screen and then switch the

A snippet is shown below




android:label=“@string/app_name” >


<action android:name=“android.intent.action.MAIN” />

<category android:name=“android.intent.category.LAUNCHER” />





android:label=“@string/app_name” >




android:label=“@string/app_name” >



With this app is also set to rock ‘n roll. I also managed to submit the app to Google Play. To publish in Google Play you need to do the following

  1. Create a signed app package. For this right click the package, select Android Tools->Export Signed Application Package and follow the prompts. Upload the *.apk file in Google Play
  2. You will also need 2 screenshots of the app & a 512×512 icon.

And you should be through.

The Unity project can be cloned from Git Hub at Unity project or

The entire Unity – Unit converter app can be downloaded at Unity-Unit Converter

Find me on Google+

Toying with Android apps

As the title suggests this is my first encounter with Android. This post is not meant for those who are intending to develop serious android apps. This article shows how to get started with Android App development. Recently I acquired my first Samsung smartphone and I can’t seem to get enough of it. I am now fully hooked on to Android and hope to play around with it in the days to come. Fortunately the initial encounter has been fairly pleasant.

To get started download the SDK from assuming you already have Eclipse like I did. Unpack and install the SDK at a suitable location for e.g. /android. You will also have to install the Eclipse plugin for Android from Alternatively you can directly download the comple ADT bundle which includes the SDK,Eclipse along with plugin etc.

Once you have Android installed on in the plugin start Eclipse. Select File->New->Project-> Android Application Project and click next. In the Application Name enter My Test and let eclipse fill the names for Project name and Package name. Click next. Allow default values in New Android Application and Configure Launcher icon screens. In the Create Activity choose Blank Activity and choose default values for New Blank Activity and finally choose Finish.

This will create the Android Project. The files and folders that are created
/src – Source folder. This contains the java source files
/res – Resource folder. This is the resource which specifies the Layout, UI and also has the Android Manifest File indicating permissions.

For the 1st Android app under res/layout open activity_main.xml. There are 2 tabs in the eclipse Window namely Graphical Layout and activity_main.xml. The Palette can be used to drag and drop widgets like textfield, buttons, radio buttons etc. For my example I placed a text field with a text “My first Android Hello World App”. You can modify the text after dragging from the palette by right clicking and entering the text string. Similarly I also dragged and dropped a button and named it “Submit”. Right click the button choose Other properties->Inherited from View and select onClick and enter “print” for New OnClickValue. Now the function print will be invoked when the Submit button is clicked.

The activity_main.xml will contain the following contents
<RelativeLayout xmlns:android=;
tools:context=“.MainActivity” >
android:text=“Submit” />
android:text=“My First Android Hello World App”
android:textAppearance=“?android:attr/textAppearanceMedium” />

Now under src open and add the following code
public void print(View view) {
Toast.makeText(this, “Hello World, Hello Android!”,

Before you build your application click Windows->Android SDK Manager. Select Tools, Android 4.2 and the necessary Extras. This will update your SDK with the latest version of teh SDK and associated libraries. Now click Windows-> Android Virtual Device Manager. This is Android’s emulator and needs to be setup. The simplest way is to select the Device Definitions tab and choose one of the devices mentioned there as your AVD. Alternatively you can select New and create a custom AVD.

Now build the project by selecting Project->Build All. Once the build is successful run the project. This will bring the AVD you selected above.

This will take a few minutes. Finally the screen will appear with a lock. Drag the lock to unlock it. To see a list of apps click the rectange wih six squares inside it. You show now see this in the AVD.

Finally double click your My Test app. When you click the Submit button it show print “Hello world, Hello Android as show below.

The SDK also comes with several sample Android projects to play around with. To build a sample project click New->Project-Android Sample Project and choose any one among them. Play around with other AVDs.

I hope to do some more serious stuff with Android in the days to come. Watch this space

Find me on Google+