Start refactoring the service to make it connect on intent.
authorDa Risk <da_risk@beem-project.com>
Tue, 17 May 2011 00:53:28 +0200
changeset 888 4b1073eebe7d
parent 887 25d96cc298d0
child 889 fb4d6a08bffa
Start refactoring the service to make it connect on intent.
AndroidManifest.xml
src/com/beem/project/beem/BeemService.java
src/com/beem/project/beem/Intent.java
src/com/beem/project/beem/ui/LoginAnim.java
--- a/AndroidManifest.xml	Thu May 05 01:06:49 2011 +0200
+++ b/AndroidManifest.xml	Tue May 17 00:53:28 2011 +0200
@@ -47,6 +47,8 @@
 			android:label="Beem Service" android:permission="com.beem.project.beem.BEEM_SERVICE">
 			<intent-filter>
 				<action android:name="com.beem.project.beem.BeemService"></action>
+				<action android:name="com.beem.project.beem.intent.action.CONNECT" />
+				<action android:name="com.beem.project.beem.intent.action.DISCONNECT" />
 			</intent-filter>
 		</service>
 	</application>
--- a/src/com/beem/project/beem/BeemService.java	Thu May 05 01:06:49 2011 +0200
+++ b/src/com/beem/project/beem/BeemService.java	Tue May 17 00:53:28 2011 +0200
@@ -72,12 +72,20 @@
 import android.content.SharedPreferences.Editor;
 import android.net.ConnectivityManager;
 import android.net.Uri;
+import android.os.Bundle;
 import android.os.IBinder;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
 import android.os.RemoteException;
 import android.preference.PreferenceManager;
 import android.provider.Settings;
 import android.util.Log;
 
+import java.util.Map;
+import java.util.HashMap;
+
 import com.beem.project.beem.service.XmppConnectionAdapter;
 import com.beem.project.beem.service.XmppFacade;
 import com.beem.project.beem.service.aidl.IXmppFacade;
@@ -104,18 +112,17 @@
     private static final int DEFAULT_XMPP_PORT = 5222;
     //private static final String COMMAND_NAMESPACE = "http://jabber.org/protocol/commands";
 
+    private static final int MESSAGE_CONNECT = 0x1;
     private NotificationManager mNotificationManager;
     private XmppConnectionAdapter mConnection;
     private SharedPreferences mSettings;
     private String mLogin;
     private String mPassword;
-    private String mHost;
     private String mService;
-    private int mPort;
-    private ConnectionConfiguration mConnectionConfiguration;
-    private ProxyInfo mProxyInfo;
-    private boolean mUseProxy;
     private IXmppFacade.Stub mBind;
+    private Looper mServiceLooper;
+    private Handler mHandler;
+    private Map<String, XmppConnectionAdapter> mConnections = new HashMap<String, XmppConnectionAdapter>();
 
     private BeemBroadcastReceiver mReceiver = new BeemBroadcastReceiver();
     private BeemServiceBroadcastReceiver mOnOffReceiver = new BeemServiceBroadcastReceiver();
@@ -129,39 +136,65 @@
     public BeemService() {
     }
 
+    @Override
+    public int onStartCommand(Intent intent, int flags, int startId) {
+	if (intent != null) {
+	    handleIntent(intent);
+	}
+	return Service.START_STICKY;
+    }
+
     /**
      * Initialize the connection.
      */
-    private void initConnectionConfig() {
+    private ConnectionConfiguration initConnectionConfig(String account) {
 	// TODO add an option for this ?
 //         SmackConfiguration.setPacketReplyTimeout(30000);
-	mUseProxy = mSettings.getBoolean(BeemApplication.PROXY_USE_KEY, false);
-	if (mUseProxy) {
+	ProxyInfo proxy = null;
+	if (mSettings.getBoolean(BeemApplication.PROXY_USE_KEY, false)) {
 	    String stype = mSettings.getString(BeemApplication.PROXY_TYPE_KEY, "HTTP");
-	    String phost = mSettings.getString(BeemApplication.PROXY_SERVER_KEY, "");
+	    String phost = mSettings.getString(BeemApplication.PROXY_SERVER_KEY, "").trim();
 	    String puser = mSettings.getString(BeemApplication.PROXY_USERNAME_KEY, "");
 	    String ppass = mSettings.getString(BeemApplication.PROXY_PASSWORD_KEY, "");
-	    int pport = Integer.parseInt(mSettings.getString(BeemApplication.PROXY_PORT_KEY, "1080"));
+	    String tmpPort = mSettings.getString(BeemApplication.PROXY_PORT_KEY, "1080");
+	    int pport = 1080;
+	    try {
+		if (tmpPort != null)
+		    pport = Integer.parseInt(tmpPort);
+	    } catch (NumberFormatException e) { }
 	    ProxyInfo.ProxyType type = ProxyType.valueOf(stype);
-	    mProxyInfo = new ProxyInfo(type, phost, pport, puser, ppass);
+	    proxy = new ProxyInfo(type, phost, pport, puser, ppass);
 	} else {
-	    mProxyInfo = ProxyInfo.forNoProxy();
+	    proxy = ProxyInfo.forNoProxy();
 	}
-	if (mSettings.getBoolean("settings_key_specific_server", false))
-	    mConnectionConfiguration = new ConnectionConfiguration(mHost, mPort, mService, mProxyInfo);
-	else
-	    mConnectionConfiguration = new ConnectionConfiguration(mService, mProxyInfo);
+
+	String service = StringUtils.parseServer(account);
+	ConnectionConfiguration config = null;
+	if (mSettings.getBoolean("settings_key_specific_server", false)) {
+	    int port = DEFAULT_XMPP_PORT;
+	    String tmpPort = mSettings.getString("settings_key_xmpp_port", "5222");
+	    try {
+		if (tmpPort != null)
+		    port = Integer.parseInt(tmpPort);
+	    } catch (NumberFormatException e) { }
+	    String host = mSettings.getString("settings_key_xmpp_server", "").trim();
+	    if ("".equals(host))
+		host = service;
+	    config = new ConnectionConfiguration(host, port, service, proxy);
+	} else
+	    config = new ConnectionConfiguration(service, proxy);
 
 	if (mSettings.getBoolean("settings_key_xmpp_tls_use", false)
 	    || mSettings.getBoolean("settings_key_gmail", false)) {
-	    mConnectionConfiguration.setSecurityMode(SecurityMode.required);
+	    config.setSecurityMode(SecurityMode.required);
 	}
 	if (mSettings.getBoolean(BeemApplication.SMACK_DEBUG_KEY, false))
-	    mConnectionConfiguration.setDebuggerEnabled(true);
-	mConnectionConfiguration.setSendPresence(true);
+	    config.setDebuggerEnabled(true);
+	config.setSendPresence(true);
 	// maybe not the universal path, but it works on most devices (Samsung Galaxy, Google Nexus One)
-	mConnectionConfiguration.setTruststoreType("BKS");
-	mConnectionConfiguration.setTruststorePath("/system/etc/security/cacerts.bks");
+	config.setTruststoreType("BKS");
+	config.setTruststorePath("/system/etc/security/cacerts.bks");
+	return config;
     }
 
     /**
@@ -189,6 +222,11 @@
     @Override
     public void onCreate() {
 	super.onCreate();
+	HandlerThread thread = new HandlerThread("BeemServiceThread");
+	thread.start();
+	mServiceLooper = thread.getLooper();
+	mHandler = new BeemServiceHandler(mServiceLooper);
+
 	registerReceiver(mReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
 	mSettings = PreferenceManager.getDefaultSharedPreferences(this);
 	mSettings.registerOnSharedPreferenceChangeListener(mPreferenceListener);
@@ -197,34 +235,11 @@
 	    registerReceiver(mOnOffReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));
 	    registerReceiver(mOnOffReceiver, new IntentFilter(Intent.ACTION_SCREEN_ON));
 	}
-	String tmpJid = mSettings.getString(BeemApplication.ACCOUNT_USERNAME_KEY, "").trim();
-	mLogin = StringUtils.parseName(tmpJid);
-	mPassword = mSettings.getString(BeemApplication.ACCOUNT_PASSWORD_KEY, "");
-	mPort = DEFAULT_XMPP_PORT;
-	mService = StringUtils.parseServer(tmpJid);
-	mHost = mService;
-
-	if (mSettings.getBoolean("settings_key_specific_server", false)) {
-	    mHost = mSettings.getString("settings_key_xmpp_server", "").trim();
-	    if ("".equals(mHost))
-		mHost = mService;
-	    String tmpPort = mSettings.getString("settings_key_xmpp_port", "5222");
-	    if (!"".equals(tmpPort))
-		mPort = Integer.parseInt(tmpPort);
-	}
-	if (mSettings.getBoolean(BeemApplication.FULL_JID_LOGIN_KEY, false) ||
-	    "gmail.com".equals(mService) || "googlemail.com".equals(mService))  {
-	    mLogin = tmpJid;
-	}
-
-	initConnectionConfig();
 	configure(ProviderManager.getInstance());
 
 	mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
-	mConnection = new XmppConnectionAdapter(mConnectionConfiguration, mLogin, mPassword, this);
 
 	Roster.setDefaultSubscriptionMode(SubscriptionMode.manual);
-	mBind = new XmppFacade(mConnection);
 	Log.d(TAG, "Create BeemService");
     }
 
@@ -244,19 +259,6 @@
 	Log.i(TAG, "Stopping the service");
     }
 
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void onStart(Intent intent, int startId) {
-	super.onStart(intent, startId);
-	Log.d(TAG, "onStart");
-	try {
-	    mConnection.connectAsync();
-	} catch (RemoteException e) {
-	    e.printStackTrace();
-	}
-    }
 
     /**
      * Show a notification using the preference of the user.
@@ -442,6 +444,17 @@
 	 */
     }
 
+    private void handleIntent(Intent intent) {
+	Message msg = null;
+	if (com.beem.project.beem.Intent.ACTION_CONNECT.equals(intent.getAction())) {
+	    msg = mHandler.obtainMessage(MESSAGE_CONNECT, intent.getExtras());
+	} else {
+	    Log.w(TAG, "Unknown intent " + intent);
+	}
+	if (msg != null)
+	    mHandler.sendMessage(msg);
+    }
+
     /**
      * Listen on preference changes.
      */
@@ -497,5 +510,67 @@
 	    }
 	}
     }
+
+    private class BeemServiceHandler extends Handler {
+	
+	public BeemServiceHandler(Looper looper) {
+	    super(looper);
+	}
+
+	@Override
+	public void handleMessage(Message msg) {
+	    Bundle b = (Bundle) msg.obj;
+	    switch (msg.what) {
+		case MESSAGE_CONNECT:
+		    handleConnect(b);
+		    break;
+		default:
+		    Log.w(TAG, "Unknown message " + msg);
+	    }
+	}
+    }
+
+    private void handleConnect(Bundle b) {
+	Intent res = new Intent(com.beem.project.beem.Intent.ACTION_DISCONNECTED);
+	String account = null;
+	if (b != null)
+	    account = b.getString(com.beem.project.beem.Intent.EXTRA_ACCOUNT);
+	if (account == null) //TODO temporary
+	    account = "dummy";
+	if (account == null) {
+	    //connect all
+	} else {
+	    res.putExtra(com.beem.project.beem.Intent.EXTRA_ACCOUNT, account);
+	    XmppConnectionAdapter con = mConnections.get(account);
+	    if (con != null && con.isAuthentificated())
+		return;
+	    if (con == null ) {
+		ConnectionConfiguration config = initConnectionConfig(account);
+		String login = StringUtils.parseName(account);
+		String password = mSettings.getString(BeemApplication.ACCOUNT_PASSWORD_KEY, "");
+
+		if (mSettings.getBoolean(BeemApplication.FULL_JID_LOGIN_KEY, false) ||
+			"gmail.com".equals(mService) || "googlemail.com".equals(mService))  {
+		    login = account;
+			}
+		con = new XmppConnectionAdapter(config, login, password, this);
+		try {
+		    Log.i(TAG, "Starting connection of " + account);
+		    if(con.connectSync()){
+			mConnections.put(account, con);
+			mConnection = con;
+			res.setAction(com.beem.project.beem.Intent.ACTION_CONNECTED);
+			//TODO 
+			mBind = new XmppFacade(con);
+		    } else {
+			Log.w(TAG, "Unable to connect " + account);
+		    }
+		} catch (RemoteException e) {
+		    Log.e(TAG, "Unable to connect " + account, e);
+		}
+	    }
+	}
+	sendBroadcast(res);
+    }
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/com/beem/project/beem/Intent.java	Tue May 17 00:53:28 2011 +0200
@@ -0,0 +1,61 @@
+
+/*
+    BEEM is a videoconference application on the Android Platform.
+
+    Copyright (C) 2009 by Frederic-Charles Barthelery,
+                          Jean-Manuel Da Silva,
+                          Nikita Kozlov,
+                          Philippe Lago,
+                          Jean Baptiste Vergely,
+                          Vincent Veronis.
+
+    This file is part of BEEM.
+
+    BEEM is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    BEEM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with BEEM.  If not, see <http://www.gnu.org/licenses/>.
+
+    Please send bug reports with examples or suggestions to
+    contact@beem-project.com or http://dev.beem-project.com/
+
+    Epitech, hereby disclaims all copyright interest in the program "Beem"
+    written by Frederic-Charles Barthelery,
+               Jean-Manuel Da Silva,
+               Nikita Kozlov,
+               Philippe Lago,
+               Jean Baptiste Vergely,
+               Vincent Veronis.
+
+    Nicolas Sadirac, November 26, 2009
+    President of Epitech.
+
+    Flavien Astraud, November 26, 2009
+    Head of the EIP Laboratory.
+
+*/
+package com.beem.project.beem;
+
+public class Intent {
+
+    public static final String ACTION_CONNECT = "com.beem.project.beem.intent.action.CONNECT";
+
+    public static final String ACTION_DISCONNECT = "com.beem.project.beem.intent.action.DISCONNECT";
+
+    public static final String ACTION_SEND_MSG = "com.beem.project.beem.intent.action.SEND_MSG";
+
+    public static final String ACTION_CONNECTED = "com.beem.project.beem.intent.action.CONNECTED";
+
+    public static final String ACTION_DISCONNECTED = "com.beem.project.beem.intent.action.DISCONNECTED";
+
+    public static final String EXTRA_ACCOUNT = "com.beem.project.beem.intent.extra.ACCOUNT";
+}
+
--- a/src/com/beem/project/beem/ui/LoginAnim.java	Thu May 05 01:06:49 2011 +0200
+++ b/src/com/beem/project/beem/ui/LoginAnim.java	Tue May 17 00:53:28 2011 +0200
@@ -44,9 +44,13 @@
 package com.beem.project.beem.ui;
 
 import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
 import android.content.ComponentName;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.ServiceConnection;
+import android.content.SharedPreferences;
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.IBinder;
@@ -59,8 +63,10 @@
 import android.widget.Button;
 import android.widget.ImageView;
 import android.widget.TextView;
+import android.preference.PreferenceManager;
 
 import com.beem.project.beem.R;
+import com.beem.project.beem.BeemApplication;
 import com.beem.project.beem.service.LoginAsyncTask;
 import com.beem.project.beem.service.aidl.IXmppFacade;
 
@@ -83,6 +89,8 @@
     private Button mCancelBt;
     private TextView mLoginState;
     private boolean mBinded;
+    private BroadcastReceiver mReceiver;
+    private SharedPreferences mSettings;
 
     /**
      * Constructor.
@@ -96,12 +104,26 @@
     @Override
     protected void onCreate(Bundle savedInstanceState) {
 	super.onCreate(savedInstanceState);
+	mSettings = PreferenceManager.getDefaultSharedPreferences(this);
 	setContentView(R.layout.login_anim);
 	mLoginState = (TextView) findViewById(R.id.loginanim_status_text);
 	mLogo = (ImageView) findViewById(R.id.loginanim_logo_anim);
 	mRotateAnim = AnimationUtils.loadAnimation(this, R.anim.rotate_and_scale);
 	mCancelBt = (Button) findViewById(R.id.loginanim_cancel_button);
 	mCancelBt.setOnClickListener(new ClickListener());
+	mReceiver = new BroadcastReceiver() {
+	    public void onReceive(Context ctx, Intent intent) {
+		String action = intent.getAction();
+	        if (com.beem.project.beem.Intent.ACTION_CONNECTED.equals(action)) {
+		    LoginAnim.this.setResult(Activity.RESULT_OK);
+		    finish();
+		} else if (com.beem.project.beem.Intent.ACTION_DISCONNECTED.equals(action)) {
+		    LoginAnim.this.setResult(Activity.RESULT_CANCELED);
+		    finish();
+		}
+	    }
+	    
+	};
     }
 
     /* (non-Javadoc)
@@ -111,10 +133,17 @@
     protected void onStart() {
 	super.onStart();
 	mLogo.startAnimation(mRotateAnim);
-	if (mTask == null)
-	    mTask = new LoginTask();
-	if (!mBinded)
-	    mBinded = bindService(LoginAnim.SERVICE_INTENT, mServConn, BIND_AUTO_CREATE);
+	String account = mSettings.getString(BeemApplication.ACCOUNT_USERNAME_KEY, "").trim();
+	Intent intent = new Intent(com.beem.project.beem.Intent.ACTION_CONNECT);
+	intent.putExtra(com.beem.project.beem.Intent.EXTRA_ACCOUNT, account);
+	IntentFilter filter = new IntentFilter(com.beem.project.beem.Intent.ACTION_CONNECTED);
+	filter.addAction(com.beem.project.beem.Intent.ACTION_DISCONNECTED);
+	registerReceiver(mReceiver, filter);
+	startService(intent);
+//         if (mTask == null)
+//             mTask = new LoginTask();
+//         if (!mBinded)
+//             mBinded = bindService(LoginAnim.SERVICE_INTENT, mServConn, BIND_AUTO_CREATE);
     }
 
     /* (non-Javadoc)
@@ -123,10 +152,11 @@
     @Override
     protected void onStop() {
 	super.onStop();
-	if (mBinded && mTask.getStatus() != AsyncTask.Status.RUNNING) {
-	    unbindService(mServConn);
-	    mXmppFacade = null;
-	}
+	unregisterReceiver(mReceiver);
+//         if (mBinded && mTask.getStatus() != AsyncTask.Status.RUNNING) {
+//             unbindService(mServConn);
+//             mXmppFacade = null;
+//         }
     }
 
     /* (non-Javadoc)
@@ -158,9 +188,9 @@
 	@Override
 	public void onClick(View v) {
 	    if (v == mCancelBt) {
-		if (!mTask.cancel(true)) {
-		    Log.d(TAG, "Can't interrupt the connection");
-		}
+//                 if (!mTask.cancel(true)) {
+//                     Log.d(TAG, "Can't interrupt the connection");
+//                 }
 		setResult(Activity.RESULT_CANCELED);
 		finish();
 	    }