package org.awesomeapp.messenger.crypto.otr;
import android.text.TextUtils;
import org.awesomeapp.messenger.model.ChatSession;
import org.awesomeapp.messenger.model.ImErrorInfo;
import org.awesomeapp.messenger.model.Message;
import org.awesomeapp.messenger.model.MessageListener;
import java.util.ArrayList;
import java.util.List;
import net.java.otr4j.OtrException;
import net.java.otr4j.session.SessionID;
import net.java.otr4j.session.SessionStatus;
import net.java.otr4j.session.TLV;
public class OtrChatListener implements MessageListener {
public static final int TLV_DATA_REQUEST = 0x100;
public static final int TLV_DATA_RESPONSE = 0x101;
private OtrChatManager mOtrChatManager;
private MessageListener mMessageListener;
public OtrChatListener(OtrChatManager otrChatManager, MessageListener listener) {
this.mOtrChatManager = otrChatManager;
this.mMessageListener = listener;
}
@Override
public boolean onIncomingMessage(ChatSession session, Message msg) {
OtrDebugLogger.log("processing incoming message: " + msg.getID());
boolean result = false;
String body = msg.getBody();
String remoteAddress = msg.getFrom().getAddress();
String localAddress = msg.getTo().getAddress();
if (mOtrChatManager == null) {
if (!TextUtils.isEmpty(body)) {
result = true;
msg.setBody(body);
mMessageListener.onIncomingMessage(session, msg);
} else {
OtrDebugLogger.log("Decrypted incoming body was null (otrdata?)");
}
}
else {
SessionID sessionID = mOtrChatManager.getSessionId(localAddress, remoteAddress);
SessionStatus otrStatus = mOtrChatManager.getSessionStatus(sessionID);
List<TLV> tlvs = new ArrayList<TLV>();
try {
body = mOtrChatManager.decryptMessage(localAddress, remoteAddress, body, tlvs);
if (!TextUtils.isEmpty(body)) {
result = true;
msg.setBody(body);
mMessageListener.onIncomingMessage(session, msg);
} else {
OtrDebugLogger.log("Decrypted incoming body was null (otrdata?)");
}
for (TLV tlv : tlvs) {
if (tlv.getType() == TLV_DATA_REQUEST) {
OtrDebugLogger.log("Got a TLV Data Request: " + new String(tlv.getValue()));
mMessageListener.onIncomingDataRequest(session, msg, tlv.getValue());
result = true;
} else if (tlv.getType() == TLV_DATA_RESPONSE) {
OtrDebugLogger.log("Got a TLV Data Response: " + new String(tlv.getValue()));
mMessageListener.onIncomingDataResponse(session, msg, tlv.getValue());
result = true;
}
}
} catch (OtrException oe) {
OtrDebugLogger.log("error decrypting message: " + msg.getID());
// mOtrChatManager.refreshSession(sessionID.getLocalUserId(),sessionID.getRemoteUserId());
// msg.setBody("[" + "You received an unreadable encrypted message" + "]");
// mMessageListener.onIncomingMessage(session, msg);
mOtrChatManager.injectMessage(sessionID, "");
}
SessionStatus newStatus = mOtrChatManager.getSessionStatus(sessionID.getLocalUserId(), sessionID.getRemoteUserId());
if (newStatus != otrStatus) {
OtrDebugLogger.log("OTR status changed from: " + otrStatus + " to " + newStatus);
mMessageListener.onStatusChanged(session, newStatus);
}
}
return result;
}
@Override
public void onIncomingDataRequest(ChatSession session, Message msg, byte[] value) {
throw new UnsupportedOperationException();
}
@Override
public void onIncomingDataResponse(ChatSession session, Message msg, byte[] value) {
throw new UnsupportedOperationException();
}
@Override
public void onSendMessageError(ChatSession session, Message msg, ImErrorInfo error) {
mMessageListener.onSendMessageError(session, msg, error);
OtrDebugLogger.log("onSendMessageError: " + msg.toString());
}
@Override
public void onIncomingReceipt(ChatSession ses, String id) {
mMessageListener.onIncomingReceipt(ses, id);
}
@Override
public void onMessagePostponed(ChatSession ses, String id) {
mMessageListener.onMessagePostponed(ses, id);
}
@Override
public void onReceiptsExpected(ChatSession ses, boolean isExpected) {
mMessageListener.onReceiptsExpected(ses, isExpected);
}
@Override
public void onStatusChanged(ChatSession session, SessionStatus status) {
mMessageListener.onStatusChanged(session, status);
}
@Override
public void onIncomingTransferRequest(OtrDataHandler.Transfer transfer) {
mMessageListener.onIncomingTransferRequest(transfer);
}
}