FileDocCategorySizeDatePackage
ImpsChatSessionManager.javaAPI DocAndroid 1.5 API9085Wed May 06 22:42:46 BST 2009com.android.im.imps

ImpsChatSessionManager

public class ImpsChatSessionManager extends com.android.im.engine.ChatSessionManager implements ServerTransactionListener
The implementation of ChatSessionManager with Wireless Village IMPS protocol.

Fields Summary
private ImpsConnection
mConnection
private ImpsTransactionManager
mTransactionManager
private ArrayList
mMessageQueue
private boolean
mStartNotifying
Constructors Summary
ImpsChatSessionManager(ImpsConnection connection)

        mConnection = connection;
        mMessageQueue = new ArrayList<Message>();

        mTransactionManager = connection.getTransactionManager();
        mTransactionManager.setTransactionListener(ImpsTags.NewMessage, this);
        mTransactionManager.setTransactionListener(ImpsTags.DeliveryReport_Request, this);
    
Methods Summary
private PrimitivecreateSendMessagePrimitive(com.android.im.engine.Message message)
Creates a SendMessage-Request primitive to send message.

param
message the message to send.
return
the SendMessage-Request primitive.

        Primitive primitive = new Primitive(ImpsTags.SendMessage_Request);

        primitive.addElement(ImpsTags.DeliveryReport,
                mConnection.getConfig().needDeliveryReport());

        PrimitiveElement msgInfo = primitive.addElement(ImpsTags.MessageInfo);
        PrimitiveElement recipient = msgInfo.addChild(ImpsTags.Recipient);
        recipient.addChild(((ImpsAddress)message.getTo()).toPrimitiveElement());
        PrimitiveElement sender = msgInfo.addChild(ImpsTags.Sender);
        sender.addChild(((ImpsAddress)message.getFrom()).toPrimitiveElement());

        // XXX: ContentType is optional and by default is "text/plain".
        // However without this the OZ IMPS server wouldn't reply to our
        // SendMessage requests and just let the HTTP connection times out.
        msgInfo.addChild(ImpsTags.ContentType, "text/plain");

        // optional
//        Calendar calendar = Calendar.getInstance();
//        calendar.setTime(message.getDateTime());
//        msgInfo.addChild(ImpsTags.DateTime, DateUtils.writeDateTime(calendar));

        String msgBody = message.getBody();
        msgInfo.addChild(ImpsTags.ContentSize, Integer.toString(msgBody.length()));
        primitive.addElement(ImpsTags.ContentData, msgBody);

        return primitive;
    
private com.android.im.engine.MessageextractMessage(Primitive primitive)
Extracts a message from a NewMessage primitive.

param
primitive the NewMessage primitive.
return
an instance of message.

        String msgBody = primitive.getElementContents(ImpsTags.ContentData);
        if (msgBody == null) {
            msgBody = "";
        }
        Message msg = new Message(msgBody);

        PrimitiveElement msgInfo = primitive.getElement(ImpsTags.MessageInfo);

        String id = msgInfo.getChildContents(ImpsTags.MessageID);
        msg.setID(id);

        PrimitiveElement sender = msgInfo.getChild(ImpsTags.Sender);
        msg.setFrom(ImpsAddress.fromPrimitiveElement(sender.getFirstChild()));

        PrimitiveElement recipent = msgInfo.getChild(ImpsTags.Recipient);
        if (recipent != null && recipent.getFirstChild() != null) {
            msg.setTo(ImpsAddress.fromPrimitiveElement(recipent.getFirstChild()));
        } else {
            msg.setTo(mConnection.getLoginUser().getAddress());
        }

        String dateTime = msgInfo.getChildContents(ImpsTags.DateTime);
        if (dateTime != null) {
            try {
                Time t = new Time();
                t.parse(dateTime);
                msg.setDateTime(new Date(t.toMillis(false /* use isDst */)));
            } catch (TimeFormatException e) {
                msg.setDateTime(new Date());
            }
        } else {
            msg.setDateTime(new Date());
        }
        return msg;
    
private com.android.im.engine.ChatSessionfindSession(com.android.im.engine.Address address)
Finds the ChatSession which the message belongs to.

param
msg the message.
return
the ChatSession or null if the session not exists.

        for(ChatSession session : mSessions) {
            ImEntity participant = session.getParticipant();
            if(participant.getAddress().equals(address)) {
                return session;
            }
        }
        return null;
    
public voidnotifyServerTransaction(ServerTransaction tx)

        Primitive primitive = tx.getRequest();

        if (ImpsTags.NewMessage.equals(primitive.getType())) {
            Message msg = extractMessage(primitive);

            // send response to the server.
            Primitive response = new Primitive(ImpsTags.MessageDelivered);
            response.addElement(ImpsTags.MessageID, msg.getID());
            tx.sendResponse(response);

            synchronized(mMessageQueue) {
                if(mStartNotifying){
                    processMessage(msg);
                } else {
                    mMessageQueue.add(msg);
                }
            }
        } else if(ImpsTags.DeliveryReport_Request.equals(primitive.getType())) {
            tx.sendStatusResponse(ImpsConstants.SUCCESS_CODE);

            // We only notify the user when an error occurs.
            ImErrorInfo error = ImpsUtils.checkResultError(primitive);
            if(error != null) {
                PrimitiveElement msgInfo = primitive.getElement(ImpsTags.MessageInfo);
                String msgId = msgInfo.getChildContents(ImpsTags.MessageID);
                PrimitiveElement recipent = msgInfo.getChild(ImpsTags.Recipient);
                ImpsAddress recipentAddress = ImpsAddress.fromPrimitiveElement(
                        recipent.getFirstChild());
                ChatSession session = findSession(recipentAddress);
                if(session != null) {
                    session.onSendMessageError(msgId, error);
                } else {
                    ImpsLog.log("Session has closed when received delivery error: "
                            + error);
                }
            }
        }
    
voidprocessMessage(com.android.im.engine.Message msg)
Processes an incoming message. Called by the sub protocol implementation when an incoming message arrived.

param
msg the incoming message.

        ImpsAddress from = (ImpsAddress) msg.getFrom();
        ImpsAddress to = (ImpsAddress) msg.getTo();

        ImpsAddress address = (to instanceof ImpsGroupAddress) ? to : from;

        synchronized (this) {
            ChatSession ses = findSession(address);
            if (ses == null) {
                ImEntity participant = address.getEntity(mConnection);
                if (participant != null) {
                    ses = createChatSession(address.getEntity(mConnection));
                } else {
                    ImpsLog.log("Message from unknown sender");
                    return;
                }
            }
            ses.onReceiveMessage(msg);
        }
    
protected voidsendMessageAsync(com.android.im.engine.ChatSession ses, com.android.im.engine.Message message)

        // force to send from the currently logged user.
        message.setFrom(mConnection.getSession().getLoginUserAddress());

        if(message.getDateTime() == null) {
            message.setDateTime(new Date());
        }
        Primitive primitive = createSendMessagePrimitive(message);
        AsyncTransaction tx = new AsyncTransaction(mTransactionManager) {

            @Override
            public void onResponseOk(Primitive response) { }

            @Override
            public void onResponseError(ImpsErrorInfo error) {
                ses.onSendMessageError(message, error);
            }
        };

        tx.sendRequest(primitive);
    
public voidstart()

        synchronized (mMessageQueue) {
            mStartNotifying = true;
            for (Message message : mMessageQueue) {
                processMessage(message);
            }
            mMessageQueue.clear();
        }