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 |
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 |