Many Linux developers look for a cron like service when starting to develop on Android, well luckily it exists in the form of AlarmManager. AlarmManager allows you to schedule your application to run at a time in the future, however it is cleared on boot–should/can be re registered with the system through OnBoot BroadcastReceiver.

AndroidManifest.xml; you need to register the two BroadcastReceivers, and the service. Also get permission to use the WakeLock, and to get Boot_Completed signal.

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
<application>
     <receiver android:name=".service.OnBootReceiver" >
         <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
         </intent-filter>
     </receiver>

     <receiver android:name=".service.OnAlarmReceiver" >
     </receiver>

     <service android:name=".service.TaskButlerService" >
     </service>
</application>

This is a BroadcastReceiver for the OnBoot complete, used to reschedule alarms with the AlarmManager since after boot the alarms are flashed out. There is only 2 lines of code in the onReceive() method, that is due to your own onReceive() needing to be short. The first line acquires a partial WakeLock to keep the CPU running, while our IntentService is executing.

package edu.worcester.cs499summer2012.service;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

/**
 * BroadCastReceiver for android.intent.action.BOOT_COMPLETED
 * passes all responsibility to TaskButlerService.
 * @author Dhimitraq Jorgji
 *
 */
public class OnBootReceiver extends BroadcastReceiver{
	@Override
	public void onReceive(Context context, Intent intent) {

		WakefulIntentService.acquireStaticLock(context); //acquire a partial WakeLock
		context.startService(new Intent(context, TaskButlerService.class)); //start TaskButlerService
	}
}

IntentService is my favorite way of getting things done in the background, separate from the main thread of my application. Usually I don’t inherit IntentService directly, and I suggest you do the same; define a synchronized method to acquire a WakeLock before you continue on with whatever you need to accomplish.

package edu.worcester.cs499summer2012.service;

import android.app.IntentService;
import android.content.Context;
import android.content.Intent;
import android.os.PowerManager;

/**
 * Acquires a partial WakeLock, allows TaskButtlerService to keep the CPU alive
 * until the work is done.
 * @author Dhimitraq Jorgji
 *
 */
public class WakefulIntentService extends IntentService {
	public static final String
	LOCK_NAME_STATIC="edu.worcester.cs499summer2012.TaskButlerService.Static";;
	public static final String
	LOCK_NAME_LOCAL="edu.worcester.cs499summer2012.TaskButlerService.Local";
	private static PowerManager.WakeLock lockStatic=null;
	private PowerManager.WakeLock lockLocal=null;

	public WakefulIntentService(String name) {
		super(name);
	}
	/**
	 * Acquire a partial static WakeLock, you need too call this within the class
	 * that calls startService()
	 * @param context
	 */
	public static void acquireStaticLock(Context context) {
		getLock(context).acquire();
	}

	synchronized private static PowerManager.WakeLock getLock(Context context) {
		if (lockStatic==null) {
			PowerManager
			mgr=(PowerManager)context.getSystemService(Context.POWER_SERVICE);
			lockStatic=mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
					LOCK_NAME_STATIC);
			lockStatic.setReferenceCounted(true);
		}
		return(lockStatic);
	}

	@Override
	public void onCreate() {
		super.onCreate();
		PowerManager mgr=(PowerManager)getSystemService(Context.POWER_SERVICE);
		lockLocal=mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
				LOCK_NAME_LOCAL);
		lockLocal.setReferenceCounted(true);
	}

	@Override
	public void onStart(Intent intent, final int startId) {
		lockLocal.acquire();
		super.onStart(intent, startId);
		getLock(this).release();
	}

	@Override
	protected void onHandleIntent(Intent intent) {
		lockLocal.release();
	}
}

Now we can simply inheriting the WakeFulIntentService, and do all our work with in one simple method onHandleIntent(Intent). The method can be called from within anywhere in your program and it will handle everything on a background thread like any Service, also safely since it holds a WakeLock until the method completes at which point it returns the lock and exits nicely.

package edu.worcester.cs499summer2012.service;

import java.util.List;

import android.content.Intent;

import edu.worcester.cs499summer2012.database.TasksDataSource;
import edu.worcester.cs499summer2012.task.Task;

/**
 * An IntentService that takes care of setting up alarms for Task Butler
 * to remind the user of upcoming events
 * @author Dhimitraq Jorgji
 *
 */
public class TaskButlerService extends WakefulIntentService{

	public TaskButlerService() {
		super("TaskButlerService");
	}

	@Override
	protected void onHandleIntent(Intent intent) {
		TasksDataSource db = TasksDataSource.getInstance(this); //get access to the instance of TasksDataSource
		TaskAlarm alarm = new TaskAlarm();

		List<Task> tasks = db.getAllTasks(); //Get a list of all the tasks there
		for (Task task : tasks) {
			// Cancel existing alarm
			alarm.cancelAlarm(this, task.getID());

			//Procrastinator and Reminder alarm
			if(task.isPastDue()){
				alarm.setReminder(this, task.getID());
			}

			//handle repeat alarms
			if(task.isRepeating() && task.isCompleted()){
				task = alarm.setRepeatingAlarm(this, task.getID());
			}

			//regular alarms
			if(!task.isCompleted() && (task.getDateDue() >= System.currentTimeMillis())){
				alarm.setAlarm(this, task);
			}
		}
		super.onHandleIntent(intent);
	}
}

At this point you just need a BroadcastReceiver to receive your alarms.

package edu.worcester.cs499summer2012.service;

import edu.worcester.cs499summer2012.database.TasksDataSource;
import edu.worcester.cs499summer2012.task.Task;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;

/**
 * BroadCastReceiver for Alarms, displays notifications as it receives alarm
 * and then starts TaskButlerService to update alarm schedule with AlarmManager
 * @author Dhimitraq Jorgji
 *
 */
public class OnAlarmReceiver extends BroadcastReceiver {
	@Override
	public void onReceive(Context context, Intent intent) {
		WakefulIntentService.acquireStaticLock(context); //acquire a partial WakeLock

		//send notification, bundle intent with taskID
		NotificationHelper notification = new NotificationHelper();
		Bundle bundle = intent.getExtras();
		int id = bundle.getInt(Task.EXTRA_TASK_ID);
		TasksDataSource db = TasksDataSource.getInstance(context);
		Task task = db.getTask(id);

		if(task.hasFinalDateDue() || task.getPriority() == Task.URGENT){
			notification.sendPersistentNotification(context, task); // send basic notification
		} else {
			notification.sendBasicNotification(context, task); // send basic notification
		}

		context.startService(new Intent(context, TaskButlerService.class)); //start TaskButlerService
	}
}

The setAlarm method:
NOTE:I use a method to create PendingIntent so my pending intents mach if the id passed in is the same, and because of of the FLAG_UPDATE_CURRENT the pending intent updates a possibly existing PendingIntent rather than duplicating.

	/**
	 * Set a One Time Alarm using the taskID
	 * @param context
	 * @param id id of task to retrieve task from SQLite database
	 */
	public void setAlarm(Context context, int id){
		TasksDataSource db = TasksDataSource.getInstance(context);
		Task task = db.getTask(id);
		AlarmManager am=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
		am.set(AlarmManager.RTC_WAKEUP, task.getDateDue(), getPendingIntent(context, id));
	}

	//get a PendingIntent
	PendingIntent getPendingIntent(Context context, int id) {
		Intent intent =  new Intent(context, OnAlarmReceiver.class)
		.putExtra(Task.EXTRA_TASK_ID, id);
		return PendingIntent.getBroadcast(context, id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
	}

All of the source code for Task Butler can be found on GitHub, including the above code.

Any questions shoot away in the comments bellow.

Advertisements

Library’s TV is Very Useful

Posted: November 26, 2012 in WSU CS
Tags:

Who would have thought our Library’s TV could be so useful for group projects involving programming. James had an idea to bring a HDMI cable in to allow us to show code each other easier; we don’t have to crowd behind one person’s laptop, this was a lot more comfortable. The meeting went longer than expected, however it helped us set the direction we wanted to go with the app, as well as debug, and write some code.

Using NotificationCompa from android.support.v4.app allows for backwards compatibility when creating notifications for your Android app. Bellow is a class that defines two basic methods for the notifications, however at this point it should be easy to go trough the documentation, and call the extra methods to set more things–even using the new android Jelly Bean notification goodies– for example the second method creates a persistent notification by setting onGoing flag true.

Speaking of flags:

//you can NOT set flags directly like
notification.flags |= Notification.FLAG_AUTO_CANCEL;
//you have to use the methods in NotificationCompat.Builder
builder.setAutoCancel(true); 

Things of note in the code is that in Notification notification = builder.getNotification(); notification is still a Notification object and not a NotificationCompat object, however the builder was defined as a NotificationCompat.Builder, this is helpful because the NotificationManager.notify() only accepts Notification objects.

package edu.worcester.cs499summer2012.service;

import edu.worcester.cs499summer2012.R;
import edu.worcester.cs499summer2012.activity.ViewTaskActivity;
import edu.worcester.cs499summer2012.task.Task;

import android.app.Notification;
import android.os.Build;
import android.support.v4.app.NotificationCompat;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;

/**
 * Creates Notifications using NotificationCompat to allow for
 * comparability though different API levels
 * 
 * @author Dhimitraq Jorgji
 *
 */
public class NotificationHelper{
	/**
	 * Basic Text Notification for Task Butler, using NotificationCompat
	 * @param context 
	 * @param id id of task, call task.getID() and pass it to this parameter
	 */
	public void sendBasicNotification(Context context, Task task) {
		NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
			.setContentText(task.getName())
			.setContentTitle(context.getText(R.string.app_name))
			.setSmallIcon(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ? 
					R.drawable.ic_notification : R.drawable.ic_notification_deprecated)
			.setAutoCancel(true)
			.setContentIntent(getPendingIntent(context, task.getID()))
			.setWhen(System.currentTimeMillis())
			.setDefaults(Notification.DEFAULT_ALL);
		Notification notification = builder.getNotification();
		NotificationManager notificationManager = getNotificationManager(context);
		notificationManager.notify(task.getID(), notification);
	}
	/**
	 * Basic Text Notification with Ongoing flag enabled for Task Butler, using NotificationCompat
	 * @param context 
	 * @param id id of task, call task.getID() and pass it to this parameter
	 */
	public void sendPersistentNotification(Context context, Task task) {
		NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
			.setContentText(task.getName())
			.setContentTitle(context.getText(R.string.app_name))
			.setSmallIcon(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ? 
					R.drawable.ic_notification : R.drawable.ic_notification_deprecated)
			.setAutoCancel(true)
			.setContentIntent(getPendingIntent(context,task.getID()))
			.setWhen(System.currentTimeMillis())
			.setOngoing(true)
			.setDefaults(Notification.DEFAULT_ALL);
		Notification notification = builder.getNotification();
		NotificationManager notificationManager = getNotificationManager(context);
		notificationManager.notify(task.getID(), notification);
	}
	//get a PendingIntent
	PendingIntent getPendingIntent(Context context, int id) {
		Intent intent =  new Intent(context, ViewTaskActivity.class)
			.putExtra(Task.EXTRA_TASK_ID, id);
		return PendingIntent.getActivity(context, id, intent, 0);
	}
	//get a NotificationManager
	NotificationManager getNotificationManager(Context context) {
		return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
	}
}

All of the source code for Task Butler can be found on GitHub, including the above code.

Any questions shoot away in the comments bellow.

So since euca2ools did not have enough work for me to continue at it for the rest of the semester, I decided I ll simply jump on our main project the Eutester project. It has been a good day so far, most things went well I heard some people had problems with version mismatches so I downloaded and installed everything from source code their most up-to-date versions of “all the things” (boto/m2crypto/paramiko/eutester). Reading through the wiki that the eutester group of guys has set up on cs.worcester.edu, and following  some links to blogg posts from the developers, I managed to run some tests on our newly installed Eucalyptus 3 cloud which is still not able to keep a VM instance running.

>>> eucaops.get_emi()
Image:emi-238B37D9
>>> emi = eucaops.get_emi()
>>> reservations = eucaops.run_instance(emi)
Attempting to run instance-store image Image:emi-238B37D9 in group default
Beginning poll loop for the 1 found in Reservation:r-860340D3
Beginning poll loop for instance Instance:i-0696428B to go to running
Instance(i-0696428B) State(pending), sleeping 10s
Instance(i-0696428B) State(pending), sleeping 10s
Instance(i-0696428B) State(pending), sleeping 10s
Instance(i-0696428B) State(pending), sleeping 10s
Instance(i-0696428B) State(pending), sleeping 10s
Instance(i-0696428B) State(terminated) Poll(5) time elapsed (51)
[CRITICAL]: [TEST_REPORT] FAILED: Instance:i-0696428B did not enter the proper state and was left in terminated

 

After some looking around found out about the existence of nc.log file, and here is the portion of the fail runs:

[EUCAFATAL] Failed to connect to qemu:///system
[i-16F93EC9] could not contact the hypervisor, abandoning the instance
[i-16F93EC9] state change for instance: Staging -> Shutoff (Pending)
doDescribeResource: cores=1/2 mem=1604/1732 disk=11/13 iqn=iqn.1994-05.com.redhat:262aa1ddbe2
[i-16F93EC9] Pending pub=0.0.0.0 priv=0.0.0.0 mac=d0:0d:16:F9:3E:C9 vlan=-24 net=-1 plat=linux vols=
[EUCAFATAL ] Failed to connect to qemu:///system
[i-16F93EC9] cleaning up state for instance
[i-16F93EC9] stopping the network (vlan=-24)
[EUCAWARN  ] vnetStopNetworkManaged(): supplied vlan '-24' is out of range (0 - 4096), nothing to do
[i-16F93EC9] state change for instance: Shutoff -> Teardown (Teardown)
[EUCAFATAL ] Failed to connect to qemu:///system

After trying to work my way through an old bug report and fix on the above problem, I decided I should check if Hardware Virtualization, which turned out it was the right idea, because in this case it is turned off in the BIOS.

So some time during week 4 of the project I had some down time, and I decided to learn how euca2ools worked. Simple command-line tools yet still very powerful as well. However recently we run to some problems with the version mismatches; so here it goes: “how to install everything from source with the latest versions”:

Very easy to install from source:
NOTE: make sure to remove older versions of the software.

Download newest boto: https://github.com/downloads/boto/boto/boto-2.3.0.tar.gz

cd /download/location
tar zxvf boto-2.3.0n.tar.gz
cd boto-2.3.0
sudo python setup.py install

Download newest M2Crypto: http://pypi.python.org/packages/source/M/M2Crypto/M2Crypto-0.21.1.tar.gz

cd /download/location 
tar zxvf M2Crypto-0.21.1.tar.gz 
cd M2Crypto-0.21.1 
sudo python setup.py install

Download euca2ools from: https://github.com/eucalyptus/euca2ools

cd /download/location
cd euca2ools
sudo make

And that should be it.

It is finally getting there but still with struggles, right now for example while I am writing this I wish I could instead be connecting to our own cluster and uploading images but port 8773 still seams to be closed when trying to look in from the outside, so I can’t connect to try and work on an instance. While earlier today Long was able to upload kernel images to the server it looks like there is a problem when trying to actually start up an instance on the server which most likely proves right our fears of hardware support for hypervisor being turned off on the BIOS. One might think “big deal” just turn it on; however these are stoke dell machines we are using the BIOS options are basic at best, so we will most-likely have to install things from scratch trying to install an other BIOS on the mother board and finally unlock the hardware support.

And finally we have our definite proof that kvm support is disabled on the BIOS, and here goes an other week without having a working cloud.

Week three was dedicated to our search for an open source project we would like to work on. Since were doing the assignment “FOSS Field Trip 2” we would each bring 2 projects to discuss. It sounded simple enough, but the class was divided between two projects. Eucalyptus for which we had the support of mentors already in the program, and they had asked us to join; including a proposal with their ambitions of what they hoped to accomplish with our help. Irrlicht which was a project one of our class mates has worked on before, and has contact with many of the developers still, we were told that we would be building a test suite for their 3D engine. It came down to a vote where eucalyptus won due to the support that the two mentors showed, and their proposal which gave us a real plan for the future of the class.