package com.kedzie.vbox.event;
import java.io.IOException;
import android.app.IntentService;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.os.Parcelable;
import android.support.v4.app.NotificationCompat;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import com.kedzie.vbox.R;
import com.kedzie.vbox.api.IEvent;
import com.kedzie.vbox.api.IEventListener;
import com.kedzie.vbox.api.IEventSource;
import com.kedzie.vbox.api.IMachine;
import com.kedzie.vbox.api.IMachineEvent;
import com.kedzie.vbox.api.jaxb.VBoxEventType;
import com.kedzie.vbox.app.BundleBuilder;
import com.kedzie.vbox.machine.MachineListActivity;
import com.kedzie.vbox.soap.VBoxSvc;
/**
* Polls VirtualBox for events and publishes them in local broadcasts.
*/
public class EventIntentService extends IntentService {
private static final String TAG = EventIntentService.class.getSimpleName();
private static final int NOTIFICATION_ID = 749;
private static final int DEFAULT_INTERVAL = 500;
public static final String BUNDLE_EVENT = "evt";
public static final String INTENT_INTERVAL="interval";
private VBoxSvc _vmgr;
private int _interval;
private boolean _running=true;
private LocalBroadcastManager _lbm;
private IEventSource evSource;
private IEventListener listener;
public EventIntentService() {
super("VirtualBox Event Handler");
}
@Override
protected void onHandleIntent(Intent intent) {
_lbm = LocalBroadcastManager.getInstance(this);
_vmgr = intent.getParcelableExtra(VBoxSvc.BUNDLE);
_interval = intent.getIntExtra(INTENT_INTERVAL, DEFAULT_INTERVAL);
// sendNotification();
IEvent event = null;
evSource = _vmgr.getVBox().getEventSource();
listener = evSource.createListener();
evSource.registerListener(listener, new VBoxEventType [] { VBoxEventType.ANY }, false);
while(_running) {
try {
if((event=evSource.getEvent(listener, 0))!=null) {
BundleBuilder bundle = new BundleBuilder().putProxy(BUNDLE_EVENT, event);
if(event instanceof IMachineEvent)
bundle.putProxy(IMachine.BUNDLE, _vmgr.getVBox().findMachine(((IMachineEvent)event).getMachineId()));
_lbm.sendBroadcast(new Intent(event.getType().name()).putExtras(bundle.create()));
evSource.eventProcessed(listener, event);
} else if(_running)
Thread.sleep(_interval);
} catch (Throwable e) {
Log.e(TAG, "Error", e);
}
}
}
/**
* Create notification notifying user that events are being handled in real-time.
*/
private void sendNotification() {
String title = getString(R.string.event_handler_notification_title);
Notification notification = new NotificationCompat.Builder(EventIntentService.this)
.setContentTitle(title)
.setContentText(getString(R.string.event_handler_notification_content, _vmgr.getServer().toString()))
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.drawable.ic_notif_vbox)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher))
.setContentIntent(PendingIntent.getActivity(EventIntentService.this, 0, new Intent(this, MachineListActivity.class).putExtra(VBoxSvc.BUNDLE, (Parcelable)_vmgr), 0))
.setTicker(title)
.setAutoCancel(false)
.build();
((NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE)).notify(NOTIFICATION_ID, notification);
}
@Override
public void onDestroy() {
// ((NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE)).cancel(NOTIFICATION_ID);
if(_running) {
_running=false;
Log.w(TAG, "Service is still in running state onDestroy!");
}
new Thread() {
@Override
public void run() {
try {
if(evSource!=null)
evSource.unregisterListener(listener);
} catch(IOException e) {}
}
}.start();
super.onDestroy();
}
}