I have reimplemented the BeemOtrService in a more "centralized" way.
authorNikita Kozlov <nikita@mbdsys.com>
Tue, 07 Dec 2010 22:57:56 +0100
changeset 815 ca323cff3ac9
parent 814 2ef1c6096069
child 816 bf953743f5a1
I have reimplemented the BeemOtrService in a more "centralized" way.
default.properties
src/com/beem/project/beem/otr/BeemOtrEngineHostImpl.java
src/com/beem/project/beem/otr/BeemOtrManager.java
src/com/beem/project/beem/service/ChatAdapter.java
src/com/zadov/beem/BeemOtrManager.java
src/net/java/otr4j/OtrEngine.java
src/net/java/otr4j/OtrEngineHost.java
src/net/java/otr4j/OtrEngineHostImpl.java
src/net/java/otr4j/OtrEngineImpl.java
src/net/java/otr4j/OtrEngineListener.java
src/net/java/otr4j/OtrException.java
src/net/java/otr4j/OtrKeyManager.java
src/net/java/otr4j/OtrKeyManagerImpl.java
src/net/java/otr4j/OtrKeyManagerListener.java
src/net/java/otr4j/OtrKeyManagerStore.java
src/net/java/otr4j/OtrPolicy.java
src/net/java/otr4j/OtrPolicyImpl.java
src/net/java/otr4j/crypto/KeyAndSession.java
src/net/java/otr4j/crypto/OtrCryptoEngine.java
src/net/java/otr4j/crypto/OtrCryptoEngineImpl.java
src/net/java/otr4j/crypto/OtrCryptoException.java
src/net/java/otr4j/io/OtrInputStream.java
src/net/java/otr4j/io/OtrOutputStream.java
src/net/java/otr4j/io/SerializationConstants.java
src/net/java/otr4j/io/SerializationUtils.java
src/net/java/otr4j/io/messages/AbstractEncodedMessage.java
src/net/java/otr4j/io/messages/AbstractMessage.java
src/net/java/otr4j/io/messages/DHCommitMessage.java
src/net/java/otr4j/io/messages/DHKeyMessage.java
src/net/java/otr4j/io/messages/DataMessage.java
src/net/java/otr4j/io/messages/ErrorMessage.java
src/net/java/otr4j/io/messages/MysteriousT.java
src/net/java/otr4j/io/messages/PlainTextMessage.java
src/net/java/otr4j/io/messages/QueryMessage.java
src/net/java/otr4j/io/messages/RevealSignatureMessage.java
src/net/java/otr4j/io/messages/SignatureM.java
src/net/java/otr4j/io/messages/SignatureMessage.java
src/net/java/otr4j/io/messages/SignatureX.java
src/net/java/otr4j/session/AuthContext.java
src/net/java/otr4j/session/AuthContextImpl.java
src/net/java/otr4j/session/Session.java
src/net/java/otr4j/session/SessionID.java
src/net/java/otr4j/session/SessionImpl.java
src/net/java/otr4j/session/SessionKeys.java
src/net/java/otr4j/session/SessionKeysImpl.java
src/net/java/otr4j/session/SessionStatus.java
--- a/default.properties	Mon Dec 06 01:06:44 2010 +0100
+++ b/default.properties	Tue Dec 07 22:57:56 2010 +0100
@@ -10,4 +10,4 @@
 # Indicates whether an apk should be generated for each density.
 split.density=false
 # Project target.
-target=android-8
+target=android-4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/com/beem/project/beem/otr/BeemOtrEngineHostImpl.java	Tue Dec 07 22:57:56 2010 +0100
@@ -0,0 +1,80 @@
+package com.beem.project.beem.otr;
+
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.util.HashMap;
+import java.util.Map;
+
+import net.java.otr4j.OtrEngineHost;
+import net.java.otr4j.OtrPolicy;
+import net.java.otr4j.OtrPolicyImpl;
+import net.java.otr4j.session.SessionID;
+
+import com.beem.project.beem.service.ChatAdapter;
+
+public class BeemOtrEngineHostImpl implements OtrEngineHost {
+
+	//Map of chat, needed because of the message injection
+	private final Map<SessionID, ChatAdapter> mChats = new HashMap<SessionID, ChatAdapter>();
+
+	//We will have a global policy for Beem as long as we won't need to modify the policy per chat.
+	private final OtrPolicy mGlobalPolicy = new OtrPolicyImpl(OtrPolicy.ALLOW_V2 | OtrPolicy.ERROR_START_AKE);
+	
+	private Map<SessionID, KeyPair> mKeys = new HashMap<SessionID, KeyPair>();
+
+	/*
+	 * We must call addChat before stating a new otr session because we will need the chat instance for message injection
+	 */
+	public void addChat(final SessionID sessionID, final ChatAdapter chat) {
+		mChats.put(sessionID, chat);
+	}
+
+	/*
+	 * We must remove the chat from the map after we ended the corresponding otr session.
+	 */
+	public void removeChat(final SessionID sessionID) {
+		mChats.remove(sessionID);
+	}
+
+	@Override
+	public void injectMessage(SessionID sessionID, String msg) {
+		ChatAdapter chat = mChats.get(sessionID);
+		chat.sendMessage(msg);		
+	}
+
+	@Override
+	public void showWarning(SessionID sessionID, String warning) {
+		// TODO Auto-generated method stub
+	}
+
+	@Override
+	public void showError(SessionID sessionID, String error) {
+		// TODO Auto-generated method stub
+	}
+
+	@Override
+	public OtrPolicy getSessionPolicy(SessionID sessionID) {
+		return mGlobalPolicy;
+	}
+
+	@Override
+	public KeyPair getKeyPair(SessionID sessionID) {	
+		KeyPair key = mKeys.get(sessionID);
+
+		if (key == null) {
+			KeyPairGenerator kg;
+			try {
+				kg = KeyPairGenerator.getInstance("DSA");
+				key = kg.genKeyPair();
+				mKeys.put(sessionID, key);
+			} catch (NoSuchAlgorithmException e) {
+				e.printStackTrace();
+				return null;
+			}
+		}
+
+		return key;
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/com/beem/project/beem/otr/BeemOtrManager.java	Tue Dec 07 22:57:56 2010 +0100
@@ -0,0 +1,31 @@
+package com.beem.project.beem.otr;
+
+import com.beem.project.beem.service.ChatAdapter;
+
+import net.java.otr4j.OtrEngine;
+import net.java.otr4j.OtrEngineImpl;
+import net.java.otr4j.session.SessionID;
+
+public class BeemOtrManager {
+
+	private static final BeemOtrEngineHostImpl mOtrHost= new BeemOtrEngineHostImpl();
+	private static OtrEngine mOtrEngine = new OtrEngineImpl(mOtrHost);
+	
+	public static OtrEngine getOtrManager() {
+		return mOtrEngine;
+	}
+	
+	/*
+	 * We must call addChat before stating a new otr session because we will need the chat instance for message injection
+	 */
+	public static void addChat(final SessionID sessionID, final ChatAdapter chat) {
+		mOtrHost.addChat(sessionID, chat);
+	}
+	
+	/*
+	 * We must remove the chat from the map after we ended the corresponding otr session.
+	 */
+	public static void removeChat(final SessionID sessionID) {
+		mOtrHost.removeChat(sessionID);
+	}
+}
--- a/src/com/beem/project/beem/service/ChatAdapter.java	Mon Dec 06 01:06:44 2010 +0100
+++ b/src/com/beem/project/beem/service/ChatAdapter.java	Tue Dec 07 22:57:56 2010 +0100
@@ -47,7 +47,7 @@
 import java.util.LinkedList;
 import java.util.List;
 
-import net.java.otr4j.OtrEngineListener;
+import net.java.otr4j.OtrException;
 import net.java.otr4j.session.SessionID;
 
 import org.jivesoftware.smack.Chat;
@@ -59,9 +59,9 @@
 import android.os.RemoteException;
 import android.util.Log;
 
+import com.beem.project.beem.otr.BeemOtrManager;
 import com.beem.project.beem.service.aidl.IChat;
 import com.beem.project.beem.service.aidl.IMessageListener;
-import com.zadov.beem.BeemOtrManager;
 
 /**
  * An adapter for smack's Chat class.
@@ -70,6 +70,7 @@
 public class ChatAdapter extends IChat.Stub {
     private static final int HISTORY_MAX_SIZE = 50;
     private static final String TAG = "ChatAdapter";
+    private static final String PROTOCOL = "XMPP";
 
     private final Chat mAdaptee;
     private final Contact mParticipant;
@@ -78,7 +79,7 @@
     private final List<Message> mMessages;
     private final RemoteCallbackList<IMessageListener> mRemoteListeners = new RemoteCallbackList<IMessageListener>();
     private final MsgListener mMsgListener = new MsgListener();
-    private BeemOtrManager mOtrManager;
+    private SessionID mOtrSessionId;
 
     /**
      * Constructor.
@@ -89,16 +90,6 @@
 	mParticipant = new Contact(chat.getParticipant());
 	mMessages = new LinkedList<Message>();
 	mAdaptee.addMessageListener(mMsgListener);
-	mOtrManager = new BeemOtrManager(this, mParticipant.getJIDWithRes(), mParticipant.getJID());
-	mOtrManager.setOtrEngineListener(new OtrEngineListener() {
-		
-		@Override
-		public void sessionStatusChanged(SessionID sessionID) {
-			mMsgListener.otrStateChanged(mOtrManager.status());
-			Log.d(TAG,  "OTR status changed " + mOtrManager.status());
-		}
-	});
-	Log.d(TAG, "new chat, with otr " + mOtrManager.status());
     }
 
     /**
@@ -118,9 +109,15 @@
 	String msgBody = message.getBody();
 	send.setTo(message.getTo());
 	Log.w(TAG, "message to " + message.getTo());
-	if (mOtrManager != null) {
-		Log.d(TAG, "msg out, with otr " + mOtrManager.status());
-		msgBody = mOtrManager.sendMessage(msgBody);
+	
+	if (mOtrSessionId != null) {
+		String body;
+		try {
+			body = BeemOtrManager.getOtrManager().transformSending(mOtrSessionId, msgBody);
+			msgBody = body;
+		} catch (OtrException e) {
+			e.printStackTrace();
+		}
 	}
 		
 	send.setBody(msgBody);
@@ -238,9 +235,15 @@
 	public void processMessage(Chat chat, org.jivesoftware.smack.packet.Message message) {
 	    Message  msg = new Message(message);
 	    Log.d(TAG, "new msg " + msg.getBody());
-	    if (mOtrManager != null) {
-			Log.d(TAG, "msg in, with otr " + mOtrManager.status());
-			msg.setBody(mOtrManager.recieveMessage(msg.getBody()));
+	    
+	    if (mOtrSessionId != null) {
+	    	String body;
+			try {
+				body = BeemOtrManager.getOtrManager().transformReceiving(mOtrSessionId, msg.getBody());
+				msg.setBody(body);
+			} catch (OtrException e) {
+				e.printStackTrace();
+			}			
 		}
 	    	
 	    //TODO add que les message pas de type errors
@@ -298,13 +301,32 @@
 
 	@Override
 	public void startOtrSession() throws RemoteException {
-		mOtrManager.startSession();
-		Log.d(TAG, "start otr " + mOtrManager.status());
+		if (mOtrSessionId != null)
+			return ;
+
+		mOtrSessionId = new SessionID(mParticipant.getJIDWithRes(), mParticipant.getJID(), PROTOCOL);
+		try {
+			BeemOtrManager.addChat(mOtrSessionId, this);
+			BeemOtrManager.getOtrManager().startSession(mOtrSessionId);
+		} catch (OtrException e) {
+			e.printStackTrace();
+			throw new RemoteException();
+		}
 	}
 
 	@Override
 	public void endOtrSession() throws RemoteException {
-		mOtrManager.endSession();
+		if (mOtrSessionId == null)
+			return ;
+		
+		try {
+			BeemOtrManager.getOtrManager().endSession(mOtrSessionId);			
+		} catch (OtrException e) {
+			e.printStackTrace();
+			throw new RemoteException();
+		}
+		BeemOtrManager.removeChat(mOtrSessionId);
+		mOtrSessionId = null;
 	}
 }
 
--- a/src/com/zadov/beem/BeemOtrManager.java	Mon Dec 06 01:06:44 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-package com.zadov.beem;
-
-import net.java.otr4j.OtrEngineHostImpl;
-import net.java.otr4j.OtrEngineImpl;
-import net.java.otr4j.OtrEngineListener;
-import net.java.otr4j.OtrPolicy;
-import net.java.otr4j.OtrPolicyImpl;
-import net.java.otr4j.session.SessionID;
-import android.util.Log;
-
-import com.beem.project.beem.service.ChatAdapter;
-
-public class BeemOtrManager {
-
-	private static final String TAG = "BeemOtrManager";
-	protected ChatAdapter mChat;
-	protected OtrEngineHostImpl myHost;
-	private OtrEngineImpl usAlice;
-	private SessionID aliceSessionID;
-
-	public BeemOtrManager(ChatAdapter chat, String jidres, String jid){
-		mChat = chat;
-		myHost = new OtrEngineHostImpl(chat, 
-				new OtrPolicyImpl(OtrPolicy.ALLOW_V2
-						| OtrPolicy.ERROR_START_AKE));
-		aliceSessionID = new SessionID(jidres,jid, "XMMP");
-		usAlice = new OtrEngineImpl(myHost);
-	}
-	
-	public void setOtrEngineListener(OtrEngineListener listener) {
-		usAlice.addOtrEngineListener(listener);
-	}
-
-	public void startSession() {
-		usAlice.startSession(aliceSessionID);
-	}
-	
-	public void endSession() {
-		usAlice.endSession(aliceSessionID);
-	}
-
-	public String status() {
-		return usAlice.getSessionStatus(aliceSessionID).toString();
-	}
-	
-	public String recieveMessage(String msg) {
-		Log.d(TAG, "in: "+msg);
-		String plain = null;
-		//mChat.otrStatusDisplay.setText("otr status: "+usAlice.getSessionStatus(aliceSessionID).toString());
-		if(usAlice != null){
-			plain = usAlice.transformReceiving(aliceSessionID, msg);
-		}
-		Log.d(TAG,"in: "+plain);
-		return plain;
-	}
-	
-	public String sendMessage(String msg) {
-		Log.d(TAG, "out: "+msg);
-		//mChat.otrStatusDisplay.setText("otr status: "+usAlice.getSessionStatus(aliceSessionID).toString());
-		if(usAlice != null){
-			msg = usAlice.transformSending(aliceSessionID, msg);
-		}
-		Log.d(TAG, "out: "+msg);
-		return msg;
-	}
-
-}
--- a/src/net/java/otr4j/OtrEngine.java	Mon Dec 06 01:06:44 2010 +0100
+++ b/src/net/java/otr4j/OtrEngine.java	Tue Dec 07 22:57:56 2010 +0100
@@ -19,9 +19,10 @@
 	 * @param content
 	 *            The message content to be transformed.
 	 * @return The transformed message content.
+	 * @throws OtrException 
 	 */
 	public abstract String transformReceiving(SessionID sessionID,
-			String content);
+			String content) throws OtrException;
 
 	/**
 	 * 
@@ -30,32 +31,36 @@
 	 * @param content
 	 *            The message content to be transformed.
 	 * @return The transformed message content.
+	 * @throws OtrException 
 	 */
-	public abstract String transformSending(SessionID sessionID, String content);
+	public abstract String transformSending(SessionID sessionID, String content) throws OtrException;
 
 	/**
 	 * Starts an Off-the-Record session, if there is no active one.
 	 * 
 	 * @param sessionID
 	 *            The session identifier.
+	 * @throws OtrException 
 	 */
-	public abstract void startSession(SessionID sessionID);
+	public abstract void startSession(SessionID sessionID) throws OtrException;
 
 	/**
 	 * Ends the Off-the-Record session, if exists.
 	 * 
 	 * @param sessionID
 	 *            The session identifier.
+	 * @throws OtrException 
 	 */
-	public abstract void endSession(SessionID sessionID);
+	public abstract void endSession(SessionID sessionID) throws OtrException;
 
 	/**
 	 * Stops/Starts the Off-the-Record session.
 	 * 
 	 * @param sessionID
 	 *            The session identifier.
+	 * @throws OtrException 
 	 */
-	public abstract void refreshSession(SessionID sessionID);
+	public abstract void refreshSession(SessionID sessionID) throws OtrException;
 
 	/**
 	 * 
--- a/src/net/java/otr4j/OtrEngineHost.java	Mon Dec 06 01:06:44 2010 +0100
+++ b/src/net/java/otr4j/OtrEngineHost.java	Tue Dec 07 22:57:56 2010 +0100
@@ -26,6 +26,6 @@
 	public abstract void showError(SessionID sessionID, String error);
 
 	public abstract OtrPolicy getSessionPolicy(SessionID sessionID);
-	
+
 	public abstract KeyPair getKeyPair(SessionID sessionID);
 }
--- a/src/net/java/otr4j/OtrEngineHostImpl.java	Mon Dec 06 01:06:44 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-package net.java.otr4j;
-
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
-
-import net.java.otr4j.crypto.KeyAndSession;
-import net.java.otr4j.session.SessionID;
-
-import com.beem.project.beem.service.ChatAdapter;
-
-
-public class OtrEngineHostImpl implements OtrEngineHost{
-	
-	private ChatAdapter mChat;
-	private OtrPolicy policy;
-    public String lastInjectedMessage;
-    private ArrayList<KeyAndSession> keyring = new ArrayList<KeyAndSession>();
-    
-	public OtrEngineHostImpl(ChatAdapter chat, OtrPolicy policy){
-		mChat = chat;
-		this.policy = policy;
-	}
-	
-	@Override
-	public KeyPair getKeyPair(SessionID sessionID) {
-		 
-		for(int i = 0; i<keyring.size(); i++){
-			if(sessionID.equals(keyring.get(i).getSessionID())){
-				return keyring.get(i).getKeyPair();
-			}
-		}
-		
-		 KeyPairGenerator kg;
-         try {
-                 kg = KeyPairGenerator.getInstance("DSA");
-
-         } catch (NoSuchAlgorithmException e) {
-                 e.printStackTrace();
-                 return null;
-         }
-         KeyAndSession kp = new KeyAndSession(kg.genKeyPair(), sessionID);
-         keyring.add(kp);
-         return kp.getKeyPair();
-	}
-
-	@Override
-	public OtrPolicy getSessionPolicy(SessionID sessionID) {
-		return this.policy;
-	}
-
-	@Override
-	public void injectMessage(SessionID sessionID, String msg) {
-		mChat.sendMessage(msg);
-	}
-
-	@Override
-	public void showError(SessionID sessionID, String error) {
-	//	mChat.otrStatusDisplay.setText(""+error);		
-	}
-
-	@Override
-	public void showWarning(SessionID sessionID, String warning) {
-		//mChat.otrStatusDisplay.setText(""+warning);
-	}
-
-}
--- a/src/net/java/otr4j/OtrEngineImpl.java	Mon Dec 06 01:06:44 2010 +0100
+++ b/src/net/java/otr4j/OtrEngineImpl.java	Tue Dec 07 22:57:56 2010 +0100
@@ -25,14 +25,14 @@
  */
 public class OtrEngineImpl implements OtrEngine {
 
-	public OtrEngineImpl(OtrEngineHost listener) {
-		if (listener == null)
+	public OtrEngineImpl(OtrEngineHost host) {
+		if (host == null)
 			throw new IllegalArgumentException("OtrEgineHost is required.");
 
-		this.setListener(listener);
+		this.setHost(host);
 	}
 
-	private OtrEngineHost listener;
+	private OtrEngineHost host;
 	private Map<SessionID, Session> sessions;
 
 	private Session getSession(SessionID sessionID) {
@@ -44,7 +44,7 @@
 			sessions = new Hashtable<SessionID, Session>();
 
 		if (!sessions.containsKey(sessionID)) {
-			Session session = new SessionImpl(sessionID, getListener());
+			Session session = new SessionImpl(sessionID, getHost());
 			sessions.put(sessionID, session);
 
 			session.addOtrEngineListener(new OtrEngineListener() {
@@ -54,64 +54,43 @@
 						l.sessionStatusChanged(sessionID);
 				}
 			});
-
-		}
-
-		return sessions.get(sessionID);
+			return session;
+		} else
+			return sessions.get(sessionID);
 	}
 
 	public SessionStatus getSessionStatus(SessionID sessionID) {
 		return this.getSession(sessionID).getSessionStatus();
 	}
 
-	public String transformReceiving(SessionID sessionID, String msgText) {
-		try {
-			return this.getSession(sessionID).transformReceiving(msgText);
-		} catch (OtrException e) {
-			listener.showError(sessionID, e.getMessage());
-			return null;
-		}
+	public String transformReceiving(SessionID sessionID, String msgText)
+			throws OtrException {
+		return this.getSession(sessionID).transformReceiving(msgText);
 	}
 
-	public String transformSending(SessionID sessionID, String msgText) {
-		try {
-			return this.getSession(sessionID).transformSending(msgText, null);
-		} catch (OtrException e) {
-			listener.showError(sessionID, e.getMessage());
-			return null;
-		}
+	public String transformSending(SessionID sessionID, String msgText)
+			throws OtrException {
+		return this.getSession(sessionID).transformSending(msgText, null);
+	}
+
+	public void endSession(SessionID sessionID) throws OtrException {
+		this.getSession(sessionID).endSession();
 	}
 
-	public void endSession(SessionID sessionID) {
-		try {
-			this.getSession(sessionID).endSession();
-		} catch (OtrException e) {
-			listener.showError(sessionID, e.getMessage());
-		}
+	public void startSession(SessionID sessionID) throws OtrException {
+		this.getSession(sessionID).startSession();
 	}
 
-	public void startSession(SessionID sessionID) {
-		try {
-			this.getSession(sessionID).startSession();
-		} catch (OtrException e) {
-			listener.showError(sessionID, e.getMessage());
-		}
+	private void setHost(OtrEngineHost host) {
+		this.host = host;
 	}
 
-	private void setListener(OtrEngineHost listener) {
-		this.listener = listener;
+	private OtrEngineHost getHost() {
+		return host;
 	}
 
-	private OtrEngineHost getListener() {
-		return listener;
-	}
-
-	public void refreshSession(SessionID sessionID) {
-		try {
-			this.getSession(sessionID).refreshSession();
-		} catch (OtrException e) {
-			listener.showError(sessionID, e.getMessage());
-		}
+	public void refreshSession(SessionID sessionID) throws OtrException {
+		this.getSession(sessionID).refreshSession();
 	}
 
 	public PublicKey getRemotePublicKey(SessionID sessionID) {
@@ -125,7 +104,6 @@
 			if (!listeners.contains(l))
 				listeners.add(l);
 		}
-
 	}
 
 	public void removeOtrEngineListener(OtrEngineListener l) {
--- a/src/net/java/otr4j/crypto/KeyAndSession.java	Mon Dec 06 01:06:44 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-package net.java.otr4j.crypto;
-
-import java.security.KeyPair;
-
-import net.java.otr4j.session.SessionID;
-
-public class KeyAndSession {
-
-	private KeyPair myKeyPair;
-	private SessionID mySessionID;
-	
-	public KeyAndSession(KeyPair kp, SessionID si){
-		myKeyPair = kp;
-		mySessionID = si;
-	}
-	
-	public KeyPair getKeyPair(){
-		return myKeyPair;
-	}
-	public SessionID getSessionID(){
-		return mySessionID;
-	}
-}
--- a/src/net/java/otr4j/session/SessionImpl.java	Mon Dec 06 01:06:44 2010 +0100
+++ b/src/net/java/otr4j/session/SessionImpl.java	Tue Dec 07 22:57:56 2010 +0100
@@ -44,11 +44,6 @@
  */
 public class SessionImpl implements Session {
 
-	/**
-	 * 
-	 * @author George Politis
-	 * 
-	 */
 	class TLV {
 		public TLV(int type, byte[] value) {
 			this.setType(type);
@@ -76,7 +71,7 @@
 	}
 
 	private SessionID sessionID;
-	private OtrEngineHost listener;
+	private OtrEngineHost host;
 	private SessionStatus sessionStatus;
 	private AuthContext authContext;
 	private SessionKeys[][] sessionKeys;
@@ -87,7 +82,7 @@
 	public SessionImpl(SessionID sessionID, OtrEngineHost listener) {
 
 		this.setSessionID(sessionID);
-		this.setListener(listener);
+		this.setHost(listener);
 
 		// client application calls OtrEngine.getSessionStatus()
 		// -> create new session if it does not exist, end up here
@@ -274,12 +269,12 @@
 		return sessionID;
 	}
 
-	private void setListener(OtrEngineHost listener) {
-		this.listener = listener;
+	private void setHost(OtrEngineHost host) {
+		this.host = host;
 	}
 
-	private OtrEngineHost getListener() {
-		return listener;
+	private OtrEngineHost getHost() {
+		return host;
 	}
 
 	private SessionKeys[][] getSessionKeys() {
@@ -320,6 +315,9 @@
 		} catch (IOException e) {
 			throw new OtrException(e);
 		}
+		
+		if (m == null)
+			return msgText; // Propably null or empty.
 
 		switch (m.messageType) {
 		case AbstractEncodedMessage.MESSAGE_DATA:
@@ -375,7 +373,7 @@
 				+ getSessionID().getUserID() + " throught "
 				+ getSessionID().getUserID() + ".");
 
-		getListener().showError(this.getSessionID(), errorMessage.error);
+		getHost().showError(this.getSessionID(), errorMessage.error);
 
 		OtrPolicy policy = getSessionPolicy();
 		if (policy.getErrorStartAKE()) {
@@ -506,7 +504,7 @@
 
 		case FINISHED:
 		case PLAINTEXT:
-			getListener().showWarning(this.getSessionID(),
+			getHost().showWarning(this.getSessionID(),
 					"Unreadable encrypted message was received.");
 
 			injectMessage(new ErrorMessage(AbstractMessage.MESSAGE_ERROR,
@@ -524,7 +522,7 @@
 		} catch (IOException e) {
 			throw new OtrException(e);
 		}
-		getListener().injectMessage(getSessionID(), msg);
+		getHost().injectMessage(getSessionID(), msg);
 	}
 
 	private String handlePlainTextMessage(PlainTextMessage plainTextMessage)
@@ -544,7 +542,7 @@
 			case FINISHED:
 				// Display the message to the user, but warn him that the
 				// message was received unencrypted.
-				getListener().showWarning(this.getSessionID(),
+				getHost().showWarning(this.getSessionID(),
 						"The message was received unencrypted.");
 				return plainTextMessage.cleanText;
 			case PLAINTEXT:
@@ -553,7 +551,7 @@
 				// is set, warn him that the message was received
 				// unencrypted.
 				if (policy.getRequireEncryption()) {
-					getListener().showWarning(this.getSessionID(),
+					getHost().showWarning(this.getSessionID(),
 							"The message was received unencrypted.");
 				}
 				return plainTextMessage.cleanText;
@@ -567,7 +565,7 @@
 				// Remove the whitespace tag and display the message to the
 				// user, but warn him that the message was received
 				// unencrypted.
-				getListener().showWarning(this.getSessionID(),
+				getHost().showWarning(this.getSessionID(),
 						"The message was received unencrypted.");
 			case PLAINTEXT:
 				// Remove the whitespace tag and display the message to the
@@ -575,7 +573,7 @@
 				// message
 				// was received unencrypted.
 				if (policy.getRequireEncryption())
-					getListener().showWarning(this.getSessionID(),
+					getHost().showWarning(this.getSessionID(),
 							"The message was received unencrypted.");
 			}
 
@@ -696,7 +694,7 @@
 			}
 		case FINISHED:
 			this.lastSentMessage = msgText;
-			getListener()
+			getHost()
 					.showError(
 							sessionID,
 							"Your message to "
@@ -737,7 +735,7 @@
 			tlvs.add(new TLV(1, null));
 
 			String msg = this.transformSending(null, tlvs);
-			getListener().injectMessage(getSessionID(), msg);
+			getHost().injectMessage(getSessionID(), msg);
 			this.setSessionStatus(SessionStatus.PLAINTEXT);
 			break;
 		case FINISHED:
@@ -776,7 +774,6 @@
 			if (!listeners.contains(l))
 				listeners.add(l);
 		}
-
 	}
 
 	public void removeOtrEngineListener(OtrEngineListener l) {
@@ -786,10 +783,10 @@
 	}
 
 	public OtrPolicy getSessionPolicy() {
-		return getListener().getSessionPolicy(getSessionID());
+		return getHost().getSessionPolicy(getSessionID());
 	}
 
 	public KeyPair getLocalKeyPair() {
-		return getListener().getKeyPair(this.getSessionID());
+		return getHost().getKeyPair(this.getSessionID());
 	}
 }
--- a/src/net/java/otr4j/session/SessionStatus.java	Mon Dec 06 01:06:44 2010 +0100
+++ b/src/net/java/otr4j/session/SessionStatus.java	Tue Dec 07 22:57:56 2010 +0100
@@ -14,4 +14,4 @@
 	PLAINTEXT,
 	ENCRYPTED,
 	FINISHED
-}
\ No newline at end of file
+}