package org.societies.android.platform.comms.integration;
import org.societies.android.api.comms.XMPPAgent;
import org.societies.android.api.utilities.ServiceMethodTranslator;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.Parcelable;
import android.os.RemoteException;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.util.Log;
public class MainActivity extends Activity {
private static final String LOG_TAG = MainActivity.class.getName();
private static final String SERVICE_ACTION = "org.societies.android.platform.comms.app.ServicePlatformCommsRemote";
//This is passed to the remote service as a parameter and used to limit the sent broadcast
private static final String CLIENT_NAME = "org.societies.android.platform.comms.integration";
//Modify these constants to suit local XMPP server
private static final String XMPP_DOMAIN = "societies.bespoke";
private static final String XMPP_IDENTIFIER = "alan";
private static final String XMPP_PASSWORD = "midge";
private static final String XMPP_BAD_IDENTIFIER = "godzilla";
private static final String XMPP_BAD_PASSWORD = "smog";
private static final String XMPP_NEW_IDENTIFIER = "gollum";
private static final String XMPP_NEW_PASSWORD = "precious";
private static final String XMPP_RESOURCE = "GalaxyNexus";
private static final String XMPP_SUCCESSFUL_JID = XMPP_IDENTIFIER + "@" + XMPP_DOMAIN + "/" + XMPP_RESOURCE;
private static final String XMPP_NEW_JID = XMPP_NEW_IDENTIFIER + "@" + XMPP_DOMAIN + "/" + XMPP_RESOURCE;
private static final int XMPP_PORT = 5222;
private static final String XMPP_DOMAIN_AUTHORITY = "danode." + XMPP_DOMAIN;
private static final String SIMPLE_XML_MESSAGE = "<iq from='romeo@montague.net/orchard to='juliet@capulet.com/balcony'> " +
"<query xmlns='http://jabber.org/protocol/disco#info'/></iq>";
private final String elementNames [] = {"cssManagerMessageBean", "cssManagerResultBean"};
private final String nameSpaces [] = {"http://societies.org/api/schema/cssmanagement"};
private boolean boundToService;
private Messenger targetService = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setupBroadcastReceiver();
bindToService();
}
protected void onStop() {
super.onStop();
if (boundToService) {
unbindService(serviceConnection);
}
}
/**
* Call a real out-of-process service. Process involves:
* 1. Select valid method signature
* 2. Create message with corresponding index number
* 3. Create a bundle (cf. http://developer.android.com/reference/android/os/Bundle.html) for restrictions on data types
* 4. Add parameter values. The values are held in key-value pairs with the parameter name being the key
* 5. Send message
*
*/
private void userLogin() {
if (boundToService) {
InvokeRemoteMethod invoke = new InvokeRemoteMethod(CLIENT_NAME);
invoke.execute();
}
}
private void configureService() {
if (boundToService) {
ConfigureRemoteService configure = new ConfigureRemoteService(CLIENT_NAME);
configure.execute();
}
}
private void sendMessage() {
if (boundToService) {
SendMessageAsync sendmessage = new SendMessageAsync(CLIENT_NAME);
sendmessage.execute();
}
}
private void registerElements() {
if (boundToService) {
RegisterElementsAsync register = new RegisterElementsAsync(CLIENT_NAME);
register.execute();
}
}
private void bindToService() {
Intent serviceIntent = new Intent(SERVICE_ACTION);
Log.d(LOG_TAG, "Bind to Societies Android Comms Service: ");
bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE);
}
private ServiceConnection serviceConnection = new ServiceConnection() {
public void onServiceDisconnected(ComponentName name) {
boundToService = false;
}
public void onServiceConnected(ComponentName name, IBinder service) {
boundToService = true;
targetService = new Messenger(service);
Log.d(this.getClass().getName(), "Societies Android Comms Service connected: ");
configureService();
}
};
/**
* Create a suitable intent filter
* @return IntentFilter
*/
private IntentFilter createTestIntentFilter() {
//register broadcast receiver to receive SocietiesEvents return values
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(XMPPAgent.UN_REGISTER_COMM_MANAGER);
intentFilter.addAction(XMPPAgent.DESTROY_MAIN_IDENTITY);
intentFilter.addAction(XMPPAgent.GET_DOMAIN_AUTHORITY_NODE);
intentFilter.addAction(XMPPAgent.GET_IDENTITY);
intentFilter.addAction(XMPPAgent.GET_ITEMS_RESULT);
intentFilter.addAction(XMPPAgent.GET_ITEMS_ERROR);
intentFilter.addAction(XMPPAgent.GET_ITEMS_EXCEPTION);
intentFilter.addAction(XMPPAgent.SEND_IQ_RESULT);
intentFilter.addAction(XMPPAgent.SEND_IQ_ERROR);
intentFilter.addAction(XMPPAgent.SEND_IQ_EXCEPTION);
intentFilter.addAction(XMPPAgent.IS_CONNECTED);
intentFilter.addAction(XMPPAgent.LOGIN);
intentFilter.addAction(XMPPAgent.LOGOUT);
intentFilter.addAction(XMPPAgent.UN_REGISTER_COMM_MANAGER);
intentFilter.addAction(XMPPAgent.CONFIGURE_AGENT);
intentFilter.addAction(XMPPAgent.REGISTER_RESULT);
intentFilter.addAction(XMPPAgent.REGISTER_EXCEPTION);
return intentFilter;
}
/**
* Broadcast receiver to receive intent return values from service method calls
*/
private class MainReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.d(LOG_TAG, "Received action: " + intent.getAction());
if (intent.getAction().equals(XMPPAgent.IS_CONNECTED)) {
Log.d(LOG_TAG, Boolean.toString(intent.getBooleanExtra(XMPPAgent.INTENT_RETURN_VALUE_KEY, false)));
} else if (intent.getAction().equals(XMPPAgent.GET_IDENTITY)) {
Log.d(LOG_TAG, intent.getStringExtra(XMPPAgent.INTENT_RETURN_VALUE_KEY));
} else if (intent.getAction().equals(XMPPAgent.GET_DOMAIN_AUTHORITY_NODE)) {
Log.d(LOG_TAG, intent.getStringExtra(XMPPAgent.INTENT_RETURN_VALUE_KEY));
} else if (intent.getAction().equals(XMPPAgent.LOGIN)) {
Log.d(LOG_TAG, "Logged in JID: " + intent.getStringExtra(XMPPAgent.INTENT_RETURN_VALUE_KEY));
registerElements();
} else if (intent.getAction().equals(XMPPAgent.LOGOUT)) {
Log.d(LOG_TAG, Boolean.toString(intent.getBooleanExtra(XMPPAgent.INTENT_RETURN_VALUE_KEY, false)));
} else if (intent.getAction().equals(XMPPAgent.UN_REGISTER_COMM_MANAGER)) {
Log.d(LOG_TAG, Boolean.toString(intent.getBooleanExtra(XMPPAgent.INTENT_RETURN_VALUE_KEY, false)));
} else if (intent.getAction().equals(XMPPAgent.CONFIGURE_AGENT)) {
Log.d(LOG_TAG, Boolean.toString(intent.getBooleanExtra(XMPPAgent.INTENT_RETURN_VALUE_KEY, false)));
userLogin();
}
}
}
/**
* Create a broadcast receiver
*
* @return the created broadcast receiver
*/
private BroadcastReceiver setupBroadcastReceiver() {
BroadcastReceiver receiver = null;
Log.d(LOG_TAG, "Set up broadcast receiver");
receiver = new MainReceiver();
this.registerReceiver(receiver, createTestIntentFilter());
Log.d(LOG_TAG, "Register broadcast receiver");
return receiver;
}
/**
*
* Async task to invoke remote service method
*
*/
private class InvokeRemoteMethod extends AsyncTask<Void, Void, Void> {
private final String LOCAL_LOG_TAG = InvokeRemoteMethod.class.getName();
private String packageName;
private String client;
/**
* Default Constructor
*
* @param packageName
* @param client
*/
public InvokeRemoteMethod(String client) {
this.client = client;
}
protected Void doInBackground(Void... args) {
String targetMethod = XMPPAgent.methodsArray[10];
Message outMessage = Message.obtain(null, ServiceMethodTranslator.getMethodIndex(XMPPAgent.methodsArray, targetMethod), 0, 0);
Bundle outBundle = new Bundle();
/*
* By passing the client package name to the service, the service can modify its broadcast intent so that
* only the client can receive it.
*/
outBundle.putString(ServiceMethodTranslator.getMethodParameterName(targetMethod, 0), this.client);
Log.d(LOCAL_LOG_TAG, "Client Package Name: " + this.client);
outBundle.putString(ServiceMethodTranslator.getMethodParameterName(targetMethod, 1), XMPP_IDENTIFIER);
Log.d(LOCAL_LOG_TAG, "Identifier: " + XMPP_IDENTIFIER);
outBundle.putString(ServiceMethodTranslator.getMethodParameterName(targetMethod, 2), XMPP_DOMAIN);
Log.d(LOCAL_LOG_TAG, "Domain: " + XMPP_DOMAIN);
outBundle.putString(ServiceMethodTranslator.getMethodParameterName(targetMethod, 3), XMPP_PASSWORD);
Log.d(LOCAL_LOG_TAG, "Password: " + XMPP_PASSWORD);
outMessage.setData(outBundle);
Log.d(LOCAL_LOG_TAG, "Call Societies Android Comms Service: " + targetMethod);
try {
targetService.send(outMessage);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
/**
* Test if callback class from one app can be used in another app
*
*/
/**
*
* Async task to invoke remote service method
*
*/
private class ConfigureRemoteService extends AsyncTask<Void, Void, Void> {
private final String LOCAL_LOG_TAG = ConfigureRemoteService.class.getName();
private String packageName;
private String client;
/**
* Default Constructor
*
* @param packageName
* @param client
*/
public ConfigureRemoteService(String client) {
this.client = client;
}
protected Void doInBackground(Void... args) {
String targetMethod = XMPPAgent.methodsArray[17];
Message outMessage = Message.obtain(null, ServiceMethodTranslator.getMethodIndex(XMPPAgent.methodsArray, targetMethod), 0, 0);
Bundle outBundle = new Bundle();
/*
* By passing the client package name to the service, the service can modify its broadcast intent so that
* only the client can receive it.
*/
outBundle.putString(ServiceMethodTranslator.getMethodParameterName(targetMethod, 0), this.client);
Log.d(LOCAL_LOG_TAG, "Client Package Name: " + this.client);
outBundle.putString(ServiceMethodTranslator.getMethodParameterName(targetMethod, 1), XMPP_DOMAIN_AUTHORITY);
Log.d(LOCAL_LOG_TAG, "Domain Authority: " + XMPP_DOMAIN_AUTHORITY);
outBundle.putInt(ServiceMethodTranslator.getMethodParameterName(targetMethod, 2), XMPP_PORT);
Log.d(LOCAL_LOG_TAG, "XMPP port" + XMPP_PORT);
outBundle.putString(ServiceMethodTranslator.getMethodParameterName(targetMethod, 3), XMPP_RESOURCE);
Log.d(LOCAL_LOG_TAG, "JID resource: " + XMPP_RESOURCE);
outBundle.putBoolean(ServiceMethodTranslator.getMethodParameterName(targetMethod, 4), false);
Log.d(LOCAL_LOG_TAG, "Debug : " + false);
outMessage.setData(outBundle);
Log.d(LOCAL_LOG_TAG, "Call Societies Android Comms Service: " + targetMethod);
try {
targetService.send(outMessage);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
/**
*
* Async task to invoke remote service method
*
*/
private class SendMessageAsync extends AsyncTask<Void, Void, Void> {
private final String LOCAL_LOG_TAG = SendMessageAsync.class.getName();
private String packageName;
private String client;
/**
* Default Constructor
*
* @param packageName
* @param client
*/
public SendMessageAsync(String client) {
this.client = client;
}
protected Void doInBackground(Void... args) {
String targetMethod = XMPPAgent.methodsArray[3];
Message outMessage = Message.obtain(null, ServiceMethodTranslator.getMethodIndex(XMPPAgent.methodsArray, targetMethod), 0, 0);
Bundle outBundle = new Bundle();
/*
* By passing the client package name to the service, the service can modify its broadcast intent so that
* only the client can receive it.
*/
outBundle.putString(ServiceMethodTranslator.getMethodParameterName(targetMethod, 0), this.client);
Log.d(LOCAL_LOG_TAG, "Client Package Name: " + this.client);
outBundle.putString(ServiceMethodTranslator.getMethodParameterName(targetMethod, 1), SIMPLE_XML_MESSAGE);
Log.d(LOCAL_LOG_TAG, "Simple XML message: " + XMPP_DOMAIN_AUTHORITY);
outMessage.setData(outBundle);
Log.d(LOCAL_LOG_TAG, "Call Societies Android Comms Service: " + targetMethod);
try {
targetService.send(outMessage);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
/**
*
* Async task to invoke remote service method
*
*/
private class RegisterElementsAsync extends AsyncTask<Void, Void, Void> {
private final String LOCAL_LOG_TAG = RegisterElementsAsync.class.getName();
private String packageName;
private String client;
/**
* Default Constructor
*
* @param packageName
* @param client
*/
public RegisterElementsAsync(String client) {
this.client = client;
}
protected Void doInBackground(Void... args) {
String targetMethod = XMPPAgent.methodsArray[0];
Message outMessage = Message.obtain(null, ServiceMethodTranslator.getMethodIndex(XMPPAgent.methodsArray, targetMethod), 0, 0);
Bundle outBundle = new Bundle();
/*
* By passing the client package name to the service, the service can modify its broadcast intent so that
* only the client can receive it.
*/
outBundle.putString(ServiceMethodTranslator.getMethodParameterName(targetMethod, 0), this.client);
Log.d(LOCAL_LOG_TAG, "Client Package Name: " + this.client);
outBundle.putStringArray(ServiceMethodTranslator.getMethodParameterName(targetMethod, 1), elementNames);
Log.d(LOCAL_LOG_TAG, "Element Names array: " + elementNames.length);
outBundle.putStringArray(ServiceMethodTranslator.getMethodParameterName(targetMethod, 1), nameSpaces);
Log.d(LOCAL_LOG_TAG, "Namespaces array: " + nameSpaces.length);
outBundle.putParcelable(ServiceMethodTranslator.getMethodParameterName(targetMethod, 1), (Parcelable) (new TestCallback()));
Log.d(LOCAL_LOG_TAG, "Callback");
outMessage.setData(outBundle);
Log.d(LOCAL_LOG_TAG, "Call Societies Android Comms Service: " + targetMethod);
try {
targetService.send(outMessage);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
}