src/com/beem/project/beem/service/ChatAdapter.java
changeset 916 b2e1b45382a4
parent 862 1a0caf61fc7c
parent 915 3e4fb7a4c39f
child 918 98d8df89c3d2
equal deleted inserted replaced
884:5315a5713dd5 916:b2e1b45382a4
    38     President of Epitech.
    38     President of Epitech.
    39 
    39 
    40     Flavien Astraud, November 26, 2009
    40     Flavien Astraud, November 26, 2009
    41     Head of the EIP Laboratory.
    41     Head of the EIP Laboratory.
    42 
    42 
    43 */
    43  */
    44 package com.beem.project.beem.service;
    44 package com.beem.project.beem.service;
    45 
    45 
    46 import java.io.File;
    46 import java.io.File;
    47 import java.io.FileWriter;
    47 import java.io.FileWriter;
    48 import java.io.IOException;
    48 import java.io.IOException;
    49 import java.util.Collections;
    49 import java.util.Collections;
    50 import java.util.LinkedList;
    50 import java.util.LinkedList;
    51 import java.util.List;
    51 import java.util.List;
    52 
    52 
       
    53 import net.java.otr4j.OtrException;
       
    54 import net.java.otr4j.session.SessionID;
       
    55 
    53 import org.jivesoftware.smack.Chat;
    56 import org.jivesoftware.smack.Chat;
    54 import org.jivesoftware.smack.XMPPException;
    57 import org.jivesoftware.smack.XMPPException;
    55 import org.jivesoftware.smack.util.StringUtils;
    58 import org.jivesoftware.smack.util.StringUtils;
    56 import org.jivesoftware.smackx.ChatState;
    59 import org.jivesoftware.smackx.ChatState;
    57 import org.jivesoftware.smackx.ChatStateListener;
    60 import org.jivesoftware.smackx.ChatStateListener;
       
    61 import org.jivesoftware.smackx.ChatState;
    58 
    62 
    59 import android.os.Environment;
    63 import android.os.Environment;
    60 import android.os.RemoteCallbackList;
    64 import android.os.RemoteCallbackList;
    61 import android.os.RemoteException;
    65 import android.os.RemoteException;
    62 import android.util.Log;
    66 import android.util.Log;
    63 
    67 
       
    68 import com.beem.project.beem.otr.BeemOtrManager;
    64 import com.beem.project.beem.service.aidl.IChat;
    69 import com.beem.project.beem.service.aidl.IChat;
    65 import com.beem.project.beem.service.aidl.IMessageListener;
    70 import com.beem.project.beem.service.aidl.IMessageListener;
    66 
    71 
    67 /**
    72 /**
    68  * An adapter for smack's Chat class.
    73  * An adapter for smack's Chat class.
    69  * @author darisk
    74  * @author darisk
    70  */
    75  */
    71 public class ChatAdapter extends IChat.Stub {
    76 public class ChatAdapter extends IChat.Stub {
    72     private static final int HISTORY_MAX_SIZE = 50;
    77 	private static final int HISTORY_MAX_SIZE = 50;
    73     private static final String TAG = "ChatAdapter";
    78 	private static final String TAG = "ChatAdapter";
    74 
    79 	private static final String PROTOCOL = "XMPP";
    75     private final Chat mAdaptee;
    80 
    76     private final Contact mParticipant;
    81 	private final Chat mAdaptee;
    77     private String mState;
    82 	private final Contact mParticipant;
    78     private boolean mIsOpen;
    83 	private String mState;
    79     private final List<Message> mMessages;
    84 	private boolean mIsOpen;
    80     private final RemoteCallbackList<IMessageListener> mRemoteListeners = new RemoteCallbackList<IMessageListener>();
    85 	private final List<Message> mMessages;
    81     private final MsgListener mMsgListener = new MsgListener();
    86 	private final RemoteCallbackList<IMessageListener> mRemoteListeners = new RemoteCallbackList<IMessageListener>();
    82     private boolean mIsHistory;
    87 	private final MsgListener mMsgListener = new MsgListener();
       
    88 	private SessionID mOtrSessionId;
       
    89 	private boolean mIsHistory;
    83     private File mHistoryPath;
    90     private File mHistoryPath;
    84     private String mAccountUser;
    91     private String mAccountUser;
    85 
    92 
    86     /**
    93     /**
    87      * Constructor.
    94 	 * Constructor.
    88      * @param chat The chat to adapt
    95 	 * @param chat The chat to adapt
    89      */
    96 	 */
    90     public ChatAdapter(final Chat chat) {
    97 	public ChatAdapter(final Chat chat) {
    91 	mAdaptee = chat;
    98 		mAdaptee = chat;
    92 	mParticipant = new Contact(chat.getParticipant());
    99 		mParticipant = new Contact(chat.getParticipant());
    93 	mMessages = new LinkedList<Message>();
   100 		mMessages = new LinkedList<Message>();
    94 	mAdaptee.addMessageListener(mMsgListener);
   101 		mAdaptee.addMessageListener(mMsgListener);
    95     }
   102 	}
    96 
   103 
    97     /**
   104 	/**
    98      * {@inheritDoc}
   105 	 * {@inheritDoc}
    99      */
   106 	 */
   100     @Override
   107 	@Override
   101     public Contact getParticipant() throws RemoteException {
   108 	public Contact getParticipant() throws RemoteException {
   102 	return mParticipant;
   109 		return mParticipant;
   103     }
   110 	}
   104 
   111 
   105     /**
   112     /**
   106      * {@inheritDoc}
   113      * {@inheritDoc}
   107      */
   114      */
   108     @Override
   115     @Override
   109     public void sendMessage(com.beem.project.beem.service.Message message) throws RemoteException {
   116     public void sendMessage(com.beem.project.beem.service.Message message) throws RemoteException {
   110 	org.jivesoftware.smack.packet.Message send = new org.jivesoftware.smack.packet.Message();
   117 	org.jivesoftware.smack.packet.Message send = new org.jivesoftware.smack.packet.Message();
       
   118 	String msgBody = message.getBody();
   111 	send.setTo(message.getTo());
   119 	send.setTo(message.getTo());
   112 	send.setBody(message.getBody());
   120 	Log.w(TAG, "message to " + message.getTo());
       
   121 
       
   122 		if (mOtrSessionId != null) {
       
   123 			String body;
       
   124 			try {
       
   125 				body = BeemOtrManager.getInstance().getOtrManager().transformSending(mOtrSessionId, msgBody);
       
   126 				msgBody = body;
       
   127 			} catch (OtrException e) {
       
   128 				e.printStackTrace();
       
   129 			}
       
   130 		}
       
   131 
       
   132 	send.setBody(msgBody);
   113 	send.setThread(message.getThread());
   133 	send.setThread(message.getThread());
   114 	send.setSubject(message.getSubject());
   134 	send.setSubject(message.getSubject());
   115 	send.setType(org.jivesoftware.smack.packet.Message.Type.chat);
   135 	send.setType(org.jivesoftware.smack.packet.Message.Type.chat);
   116 	// TODO gerer les messages contenant des XMPPError
   136 	// TODO gerer les messages contenant des XMPPError
   117 	// send.set
   137 	// send.set
   124 	String state = Environment.getExternalStorageState();
   144 	String state = Environment.getExternalStorageState();
   125 	if (mIsHistory && Environment.MEDIA_MOUNTED.equals(state))
   145 	if (mIsHistory && Environment.MEDIA_MOUNTED.equals(state))
   126 	    saveHistory(message, mAccountUser);
   146 	    saveHistory(message, mAccountUser);
   127     }
   147     }
   128 
   148 
       
   149 	public void sendMessage(String msg) {
       
   150 		Message msgToSend = new Message(mParticipant.getJIDWithRes(), Message.MSG_TYPE_CHAT);
       
   151 		msgToSend.setBody(msg);
       
   152 		try {
       
   153 			sendMessage(msgToSend);
       
   154 		} catch (RemoteException e) {
       
   155 			e.printStackTrace();
       
   156 		}
       
   157 	}
       
   158 
   129     /**
   159     /**
   130      * {@inheritDoc}
   160      * {@inheritDoc}
   131      */
   161      */
   132     @Override
   162     @Override
   133     public void addMessageListener(IMessageListener listen) {
   163     public void addMessageListener(IMessageListener listen) {
   142     public void removeMessageListener(IMessageListener listen) {
   172     public void removeMessageListener(IMessageListener listen) {
   143 	if (listen != null) {
   173 	if (listen != null) {
   144 	    mRemoteListeners.unregister(listen);
   174 	    mRemoteListeners.unregister(listen);
   145 	}
   175 	}
   146     }
   176     }
       
   177 
   147 
   178 
   148     /**
   179     /**
   149      * {@inheritDoc}
   180      * {@inheritDoc}
   150      */
   181      */
   151     @Override
   182     @Override
   285      */
   316      */
   286     private class MsgListener implements ChatStateListener {
   317     private class MsgListener implements ChatStateListener {
   287 	/**
   318 	/**
   288 	 * Constructor.
   319 	 * Constructor.
   289 	 */
   320 	 */
   290 	public MsgListener() {
   321 	public MsgListener() { }
   291 	}
   322 
       
   323 		@Override
       
   324 		public void processMessage(Chat chat, org.jivesoftware.smack.packet.Message message) {
       
   325 			Message  msg = new Message(message);
       
   326 			Log.d(TAG, "new msg " + msg.getBody());
       
   327 
       
   328 			if (mOtrSessionId != null) {
       
   329 				String body;
       
   330 				try {
       
   331 					body = BeemOtrManager.getInstance().getOtrManager().transformReceiving(mOtrSessionId, msg.getBody());
       
   332 					msg.setBody(body);
       
   333 				} catch (OtrException e) {
       
   334 					e.printStackTrace();
       
   335 				}			
       
   336 			}
       
   337 
       
   338 			//TODO add que les message pas de type errors
       
   339 			ChatAdapter.this.addMessage(msg);
       
   340 			final int n = mRemoteListeners.beginBroadcast();
       
   341 			for (int i = 0; i < n; i++) {
       
   342 				IMessageListener listener = mRemoteListeners.getBroadcastItem(i);
       
   343 				try {
       
   344 					if (listener != null)
       
   345 						listener.processMessage(ChatAdapter.this, msg);
       
   346 				} catch (RemoteException e) {
       
   347 					Log.w(TAG, "Error while diffusing message to listener", e);
       
   348 				}
       
   349 			}
       
   350 			mRemoteListeners.finishBroadcast();
       
   351 		}
       
   352 
       
   353 		/**
       
   354 		 * {@inheritDoc}
       
   355 		 */
       
   356 		@Override
       
   357 		public void stateChanged(Chat chat, ChatState state) {
       
   358 			mState = state.name();
       
   359 			final int n = mRemoteListeners.beginBroadcast();
       
   360 
       
   361 			for (int i = 0; i < n; i++) {
       
   362 				IMessageListener listener = mRemoteListeners.getBroadcastItem(i);
       
   363 				try {
       
   364 					listener.stateChanged(ChatAdapter.this);
       
   365 				} catch (RemoteException e) {
       
   366 					Log.w(TAG, e.getMessage());
       
   367 				}
       
   368 			}
       
   369 			mRemoteListeners.finishBroadcast();
       
   370 		}
       
   371 
       
   372 
       
   373 	}
       
   374 	/**
       
   375 	 * This method is executed when the otr session status change.
       
   376 	 * @param otrState the new state of otr session.
       
   377 	 */
       
   378 	public	void otrStateChanged(final String otrState) {
       
   379 		final int n = mRemoteListeners.beginBroadcast();
       
   380 
       
   381 		if ("FINISHED".equals(otrState)) {
       
   382 			BeemOtrManager.getInstance().removeChat(mOtrSessionId);
       
   383 			mOtrSessionId = null;
       
   384 		}
       
   385 		for (int i = 0; i < n; i++) {
       
   386 			IMessageListener listener = mRemoteListeners.getBroadcastItem(i);
       
   387 			try {
       
   388 				listener.otrStateChanged(otrState);
       
   389 			} catch (RemoteException e) {
       
   390 				Log.w(TAG, e.getMessage());
       
   391 			}
       
   392 		}
       
   393 		mRemoteListeners.finishBroadcast();
       
   394 	}
       
   395 
   292 
   396 
   293 	@Override
   397 	@Override
   294 	public void processMessage(Chat chat, org.jivesoftware.smack.packet.Message message) {
   398 	public void startOtrSession() throws RemoteException {
   295 	    Message msg = new Message(message);
   399 		if (mOtrSessionId != null)
   296 	    //TODO add que les message pas de type errors
   400 			return ;
   297 	    ChatAdapter.this.addMessage(msg);
   401 
   298 	    final int n = mRemoteListeners.beginBroadcast();
   402 		mOtrSessionId = new SessionID(mParticipant.getJIDWithRes(), mParticipant.getJID(), PROTOCOL);
   299 	    for (int i = 0; i < n; i++) {
       
   300 		IMessageListener listener = mRemoteListeners.getBroadcastItem(i);
       
   301 		try {
   403 		try {
   302 		    if (listener != null)
   404 			BeemOtrManager.getInstance().addChat(mOtrSessionId, this);
   303 			listener.processMessage(ChatAdapter.this, msg);
   405 			BeemOtrManager.getInstance().getOtrManager().startSession(mOtrSessionId);
   304 		} catch (RemoteException e) {
   406 		} catch (OtrException e) {
   305 		    Log.w(TAG, "Error while diffusing message to listener", e);
   407 			mOtrSessionId = null;
   306 		}
   408 			e.printStackTrace();
   307 	    }
   409 			throw new RemoteException();
   308 	    mRemoteListeners.finishBroadcast();
   410 		}
   309 	}
   411 	}
   310 
   412 
   311 	/**
       
   312 	 * {@inheritDoc}
       
   313 	 */
       
   314 	@Override
   413 	@Override
   315 	public void stateChanged(Chat chat, ChatState state) {
   414 	public void endOtrSession() throws RemoteException {
   316 	    mState = state.name();
   415 		if (mOtrSessionId == null)
   317 	    final int n = mRemoteListeners.beginBroadcast();
   416 			return ;
   318 
   417 
   319 	    for (int i = 0; i < n; i++) {
       
   320 		IMessageListener listener = mRemoteListeners.getBroadcastItem(i);
       
   321 		try {
   418 		try {
   322 		    listener.stateChanged(ChatAdapter.this);
   419 			BeemOtrManager.getInstance().getOtrManager().endSession(mOtrSessionId);			
   323 		} catch (RemoteException e) {
   420 		} catch (OtrException e) {
   324 		    Log.w(TAG, e.getMessage());
   421 			e.printStackTrace();
   325 		}
   422 			throw new RemoteException();
   326 	    }
   423 		}
   327 	    mRemoteListeners.finishBroadcast();
   424 		BeemOtrManager.getInstance().removeChat(mOtrSessionId);
   328 	}
   425 		mOtrSessionId = null;
   329     }
   426 	}
       
   427 
       
   428 	@Override
       
   429 	public void listenOtrSession() throws RemoteException {
       
   430 		if (mOtrSessionId != null)
       
   431 			return ;
       
   432 
       
   433 		mOtrSessionId = new SessionID(mParticipant.getJIDWithRes(), mParticipant.getJID(), PROTOCOL);
       
   434 		BeemOtrManager.getInstance().addChat(mOtrSessionId, this);
       
   435 		//OtrEngineImpl will make a call to "this.getSession(sessionID)" which will instantiate our session.
       
   436 		BeemOtrManager.getInstance().getOtrManager().getSessionStatus(mOtrSessionId);
       
   437 
       
   438 	}
   330 }
   439 }
       
   440