FileDocCategorySizeDatePackage
ChatSessionAdapter.javaAPI DocAndroid 1.5 API23779Wed May 06 22:42:46 BST 2009com.android.im.service

ChatSessionAdapter

public class ChatSessionAdapter extends IChatSession.Stub

Fields Summary
private static final String
NON_CHAT_MESSAGE_SELECTION
static final String
TAG
final android.os.RemoteCallbackList
mRemoteListeners
The registered remote listeners.
ImConnectionAdapter
mConnection
ChatSessionManagerAdapter
mChatManager
com.android.im.engine.ChatSession
mAdaptee
ListenerAdapter
mListenerAdapter
boolean
mIsGroupChat
StatusBarNotifier
mStatusBarNotifier
private android.content.ContentResolver
mContentResolver
android.net.Uri
mChatURI
private android.net.Uri
mMessageURI
private boolean
mConvertingToGroupChat
private static final int
MAX_HISTORY_COPY_COUNT
private HashMap
mContactStatusMap
private boolean
mHasUnreadMessages
Constructors Summary
public ChatSessionAdapter(com.android.im.engine.ChatSession adaptee, ImConnectionAdapter connection)


      
              
        mAdaptee = adaptee;
        mConnection = connection;
        RemoteImService service = connection.getContext();
        mContentResolver = service.getContentResolver();
        mStatusBarNotifier = service.getStatusBarNotifier();
        mChatManager = (ChatSessionManagerAdapter) connection.getChatSessionManager();

        mListenerAdapter = new ListenerAdapter();
        mAdaptee.addMessageListener(mListenerAdapter);

        ImEntity participant = mAdaptee.getParticipant();

        if(participant instanceof ChatGroup) {
            init((ChatGroup)participant);
        } else {
            init((Contact)participant);
        }
    
Methods Summary
public voidconvertToGroupChat()
Convert this chat session to a group chat. If it's already a group chat, nothing will happen. The method works in async mode and the registered listener will be notified when it's converted to group chat successfully. Note that the method is not thread-safe since it's always called from the UI and Android uses single thread mode for UI.

        if (mIsGroupChat || mConvertingToGroupChat) {
            return;
        }

        mConvertingToGroupChat = true;
        new ChatConvertor().convertToGroupChat();
    
private voidcopyHistoryMessages(com.android.im.engine.Contact oldParticipant)

        List<Message> historyMessages = mAdaptee.getHistoryMessages();
        int total = historyMessages.size();
        int start = total > MAX_HISTORY_COPY_COUNT ? total - MAX_HISTORY_COPY_COUNT : 0;
        for (int i = start; i < total; i++) {
            Message msg = historyMessages.get(i);
            boolean incoming = msg.getFrom().equals(oldParticipant.getAddress());
            String contact = incoming ? oldParticipant.getName() : null;
            long time = msg.getDateTime().getTime();
            insertMessageInDb(contact, msg.getBody(), time,
                    incoming ? Im.MessageType.INCOMING : Im.MessageType.OUTGOING);
        }
    
voiddeleteGroupMemberInDb(com.android.im.engine.Contact member)

        String where = Im.GroupMembers.USERNAME + "=?";
        String[] selectionArgs = { member.getAddress().getFullName() };
        long groupId = ContentUris.parseId(mChatURI);
        Uri uri = ContentUris.withAppendedId(Im.GroupMembers.CONTENT_URI, groupId);
        mContentResolver.delete(uri, where, selectionArgs);

        insertMessageInDb(member.getName(), null, System.currentTimeMillis(),
                Im.MessageType.PRESENCE_UNAVAILABLE);
    
public com.android.im.engine.ChatSessiongetAdaptee()

        return mAdaptee;
    
public java.lang.StringgetAddress()

        return mAdaptee.getParticipant().getAddress().getFullName();
    
public android.net.UrigetChatUri()

        return mChatURI;
    
private com.android.im.engine.ChatGroupManagergetGroupManager()

        return mConnection.getAdaptee().getChatGroupManager();
    
public longgetId()

        return ContentUris.parseId(mChatURI);
    
public java.lang.StringgetName()

        return mAdaptee.getParticipant().getAddress().getScreenName();
    
java.lang.StringgetNickName(java.lang.String username)

        ImEntity participant = mAdaptee.getParticipant();
        if (mIsGroupChat) {
            ChatGroup group = (ChatGroup)participant;
            List<Contact> members = group.getMembers();
            for (Contact c : members) {
                if (username.equals(c.getAddress().getFullName())) {
                    return c.getName();
                }
            }
            // not found, impossible
            return username;
        } else {
            return ((Contact)participant).getName();
        }
    
public java.lang.String[]getPariticipants()

        if (mIsGroupChat) {
            Contact self = mConnection.getLoginUser();
            ChatGroup group = (ChatGroup)mAdaptee.getParticipant();
            List<Contact> members = group.getMembers();
            String[] result = new String[members.size() - 1];
            int index = 0;
            for (Contact c : members) {
                if (!c.equals(self)) {
                    result[index++] = c.getAddress().getFullName();
                }
            }
            return result;
        } else {
            return new String[] {mAdaptee.getParticipant().getAddress().getFullName()};
        }
    
private voidinit(com.android.im.engine.ChatGroup group)

        mIsGroupChat = true;
        long groupId = insertGroupContactInDb(group);
        group.addMemberListener(mListenerAdapter);
        mMessageURI = ContentUris.withAppendedId(
                Im.GroupMessages.CONTENT_URI_GROUP_MESSAGES_BY, groupId);
        mChatURI = ContentUris.withAppendedId(Im.Chats.CONTENT_URI, groupId);
        insertOrUpdateChat(null);

        for (Contact c : group.getMembers()) {
            mContactStatusMap.put(c.getName(), c.getPresence().getStatus());
        }
    
private voidinit(com.android.im.engine.Contact contact)

        mIsGroupChat = false;
        ContactListManagerAdapter listManager =
            (ContactListManagerAdapter) mConnection.getContactListManager();
        long contactId = listManager.queryOrInsertContact(contact);

        long provider = mConnection.getProviderId();
        long account  = mConnection.getAccountId();
        String address = contact.getAddress().getFullName();
        mMessageURI = Im.Messages.getContentUriByContact(provider, account, address);
        mChatURI = ContentUris.withAppendedId(Im.Chats.CONTENT_URI, contactId);
        insertOrUpdateChat(null);

        mContactStatusMap.put(contact.getName(), contact.getPresence().getStatus());
    
private longinsertGroupContactInDb(com.android.im.engine.ChatGroup group)

        // Insert a record in contacts table
        ContentValues values = new ContentValues(4);
        values.put(Im.Contacts.USERNAME, group.getAddress().getFullName());
        values.put(Im.Contacts.NICKNAME, group.getName());
        values.put(Im.Contacts.CONTACTLIST, ContactListManagerAdapter.FAKE_TEMPORARY_LIST_ID);
        values.put(Im.Contacts.TYPE, Im.Contacts.TYPE_GROUP);

        Uri contactUri = ContentUris.withAppendedId(ContentUris.withAppendedId(
                Im.Contacts.CONTENT_URI, mConnection.mProviderId), mConnection.mAccountId);
        long id = ContentUris.parseId(mContentResolver.insert(contactUri, values));

        ArrayList<ContentValues> memberValues = new ArrayList<ContentValues>();
        Contact self = mConnection.getLoginUser();
        for (Contact member : group.getMembers()) {
            if (!member.equals(self)) { // avoid to insert the user himself
                ContentValues memberValue = new ContentValues(2);
                memberValue.put(Im.GroupMembers.USERNAME,
                        member.getAddress().getFullName());
                memberValue.put(Im.GroupMembers.NICKNAME,
                        member.getName());
                memberValues.add(memberValue);
            }
        }
        if (!memberValues.isEmpty()) {
            ContentValues[] result = new ContentValues[memberValues.size()];
            memberValues.toArray(result);
            Uri memberUri = ContentUris.withAppendedId(Im.GroupMembers.CONTENT_URI, id);
            mContentResolver.bulkInsert(memberUri, result);
        }
        return id;
    
voidinsertGroupMemberInDb(com.android.im.engine.Contact member)

        ContentValues values1 = new ContentValues(2);
        values1.put(Im.GroupMembers.USERNAME, member.getAddress().getFullName());
        values1.put(Im.GroupMembers.NICKNAME, member.getName());
        ContentValues values = values1;

        long groupId = ContentUris.parseId(mChatURI);
        Uri uri = ContentUris.withAppendedId(Im.GroupMembers.CONTENT_URI, groupId);
        mContentResolver.insert(uri, values);

        insertMessageInDb(member.getName(), null, System.currentTimeMillis(),
                Im.MessageType.PRESENCE_AVAILABLE);
    
android.net.UriinsertMessageInDb(java.lang.String contact, java.lang.String body, long time, int type)

        return insertMessageInDb(contact, body, time, type, 0/*No error*/);
    
android.net.UriinsertMessageInDb(java.lang.String contact, java.lang.String body, long time, int type, int errCode)

        ContentValues values = new ContentValues(mIsGroupChat ? 4 : 3);
        values.put(Im.BaseMessageColumns.BODY, body);
        values.put(Im.BaseMessageColumns.DATE, time);
        values.put(Im.BaseMessageColumns.TYPE, type);
        values.put(Im.BaseMessageColumns.ERROR_CODE, errCode);
        if (mIsGroupChat) {
            values.put(Im.BaseMessageColumns.CONTACT, contact);
        }

        return mContentResolver.insert(mMessageURI, values);
    
voidinsertOrUpdateChat(java.lang.String message)

        ContentValues values = new ContentValues(2);

        values.put(Im.Chats.LAST_MESSAGE_DATE, System.currentTimeMillis());
        values.put(Im.Chats.LAST_UNREAD_MESSAGE, message);
        // ImProvider.insert() will replace the chat if it already exist.
        mContentResolver.insert(mChatURI, values);
    
voidinsertPresenceUpdatesMsg(java.lang.String contact, com.android.im.engine.Presence presence)

        int status = presence.getStatus();

        Integer previousStatus = mContactStatusMap.get(contact);
        if (previousStatus != null && previousStatus == status) {
            // don't insert the presence message if it's the same status
            // with the previous presence update notification
            return;
        }

        mContactStatusMap.put(contact, status);
        int messageType;
        switch (status) {
            case Presence.AVAILABLE:
                messageType = Im.MessageType.PRESENCE_AVAILABLE;
                break;

            case Presence.AWAY:
            case Presence.IDLE:
                messageType = Im.MessageType.PRESENCE_AWAY;
                break;

            case Presence.DO_NOT_DISTURB:
                messageType = Im.MessageType.PRESENCE_DND;
                break;

            default:
                messageType = Im.MessageType.PRESENCE_UNAVAILABLE;
                break;
        }

        if(mIsGroupChat) {
            insertMessageInDb(contact, null, System.currentTimeMillis(), messageType);
        } else {
            insertMessageInDb(null, null, System.currentTimeMillis(), messageType);
        }
    
public voidinviteContact(java.lang.String contact)

        if(!mIsGroupChat){
            return;
        }
        ContactListManagerAdapter listManager =
            (ContactListManagerAdapter) mConnection.getContactListManager();
        Contact invitee = listManager.getContactByAddress(contact);
        if(invitee == null) {
            ImErrorInfo error = new ImErrorInfo(ImErrorInfo.ILLEGAL_CONTACT_ADDRESS,
                "Cannot find contact with address: " + contact);
            mListenerAdapter.onError((ChatGroup)mAdaptee.getParticipant(), error);
        } else {
            getGroupManager().inviteUserAsync((ChatGroup)mAdaptee.getParticipant(),
                    invitee);
        }
    
public booleanisGroupChatSession()

        return mIsGroupChat;
    
public voidleave()

        if (mIsGroupChat) {
            getGroupManager().leaveChatGroupAsync((ChatGroup)mAdaptee.getParticipant());
            mContentResolver.delete(mMessageURI, null, null);
        } else {
            mContentResolver.delete(mMessageURI, null, null);
        }
        mContentResolver.delete(mChatURI, null, null);
        mStatusBarNotifier.dismissChatNotification(
                mConnection.getProviderId(), getAddress());
        mChatManager.closeChatSession(this);
    
public voidleaveIfInactive()

        if (mAdaptee.getHistoryMessages().isEmpty()) {
            leave();
        }
    
public voidmarkAsRead()

        if (mHasUnreadMessages) {
            ContentValues values = new ContentValues(1);
            values.put(Im.Chats.LAST_UNREAD_MESSAGE, (String) null);
            mConnection.getContext().getContentResolver().update(mChatURI, values, null, null);

            mStatusBarNotifier.dismissChatNotification(mConnection.getProviderId(), getAddress());

            mHasUnreadMessages = false;
        }
    
voidonConvertToGroupChatSuccess(com.android.im.engine.ChatGroup group)

        Contact oldParticipant = (Contact)mAdaptee.getParticipant();
        String oldAddress = getAddress();
        mAdaptee.setParticipant(group);
        mChatManager.updateChatSession(oldAddress, this);

        Uri oldChatUri = mChatURI;
        Uri oldMessageUri = mMessageURI;
        init(group);
        copyHistoryMessages(oldParticipant);

        mContentResolver.delete(oldMessageUri, NON_CHAT_MESSAGE_SELECTION, null);
        mContentResolver.delete(oldChatUri, null, null);

        mListenerAdapter.notifyChatSessionConverted();
        mConvertingToGroupChat = false;
    
public voidregisterChatListener(com.android.im.IChatListener listener)

        if (listener != null) {
            mRemoteListeners.register(listener);
        }
    
voidremoveMessageInDb(int type)

        mContentResolver.delete(mMessageURI, Im.BaseMessageColumns.TYPE + "=?",
                new String[]{Integer.toString(type)});
    
public voidsendMessage(java.lang.String text)

        if (mConnection.getState() == ImConnection.SUSPENDED) {
            // connection has been suspended, save the message without send it
            insertMessageInDb(null, text, -1, Im.MessageType.POSTPONED);
            return;
        }

        Message msg = new Message(text);
        mAdaptee.sendMessageAsync(msg);
        long now = System.currentTimeMillis();
        insertMessageInDb(null, text, now, Im.MessageType.OUTGOING);
    
voidsendPostponedMessages()

        String[] projection = new String[] {
            BaseColumns._ID,
            Im.BaseMessageColumns.BODY,
            Im.BaseMessageColumns.DATE,
            Im.BaseMessageColumns.TYPE,
        };
        String selection = Im.BaseMessageColumns.TYPE + "=?";

        Cursor c = mContentResolver.query(mMessageURI, projection, selection,
                new String[]{Integer.toString(Im.MessageType.POSTPONED)}, null);
        if (c == null) {
            Log.e(TAG, "Query error while querying postponed messages");
            return;
        }

        while (c.moveToNext()) {
            String body = c.getString(1);
            mAdaptee.sendMessageAsync(new Message(body));

            c.updateLong(2, System.currentTimeMillis());
            c.updateInt(3, Im.MessageType.OUTGOING);
        }
        c.commitUpdates();
        c.close();
    
public voidunregisterChatListener(com.android.im.IChatListener listener)

        if (listener != null) {
            mRemoteListeners.unregister(listener);
        }