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

ImpsContactListManager

public class ImpsContactListManager extends com.android.im.engine.ContactListManager implements ServerTransactionListener
An implementation of ContactListManager of Wireless Village IMPS protocol.

Fields Summary
private ImpsConnection
mConnection
private String
mDefaultDomain
ImpsTransactionManager
mTransactionManager
ImpsConnectionConfig
mConfig
boolean
mAllowAutoSubscribe
ArrayList
mSubscriptionRequests
private PresencePollingManager
mPollingMgr
Constructors Summary
ImpsContactListManager(ImpsConnection connection)
Constructs the manager with specific connection.

param
connection the connection related to the manager


                       
      
        mConnection = connection;
        mConfig = connection.getConfig();
        mDefaultDomain = mConfig.getDefaultDomain();
        mTransactionManager = connection.getTransactionManager();

        mTransactionManager.setTransactionListener(
                ImpsTags.PresenceNotification_Request, this);
        mTransactionManager.setTransactionListener(
                ImpsTags.PresenceAuth_Request, this);
    
Methods Summary
private voidaddContactToListAsync(com.android.im.engine.Contact contact, com.android.im.engine.ContactList list)

        final ArrayList<Contact> contacts = new ArrayList<Contact>();

        contacts.add(contact);
        updateContactListAsync(list, contacts, null, null, new AsyncCompletion(){
            public void onComplete() {
                notifyContactListUpdated(list,
                        ContactListListener.LIST_CONTACT_ADDED, contact);

                if (mConfig.usePrensencePolling()) {
                    fetchPresence(new ImpsAddress[]{
                            (ImpsAddress) contact.getAddress()});
                } else {
                    AsyncCompletion subscribeCompletion =  new AsyncCompletion(){
                        public void onComplete() {}

                        public void onError(ImErrorInfo error) {
                            notifyContactError(
                                    ContactListListener.ERROR_RETRIEVING_PRESENCE,
                                    error, list.getName(), contact);
                        }
                    };

                    if (mAllowAutoSubscribe) {
                        // XXX Send subscription again after add contact to make sure we
                        // can get the presence notification. Although the we set
                        // AutoSubscribe True when subscribe presence after load contacts,
                        // the server might not send presence notification.
                        subscribeToListAsync(list, subscribeCompletion);
                    } else {
                        subscribeToContactsAsync(contacts, subscribeCompletion);
                    }
                }
            }

            public void onError(ImErrorInfo error) {
                // XXX Workaround to convert 402 error to 531. Some
                // servers might return 402 - Bad parameter instead of
                // 531 - Unknown user if the user input an invalid user ID.
                if (error.getCode() == ImpsErrorInfo.BAD_PARAMETER) {
                    error = new ImErrorInfo(ImpsErrorInfo.UNKNOWN_USER,
                            error.getDescription());
                }
                notifyContactError(ContactListListener.ERROR_ADDING_CONTACT,
                        error, list.getName(), contact);
            }
        });
    
public voidapproveSubscriptionRequest(java.lang.String contact)

        handleSubscriptionRequest(contact, true);
    
private PrimitivebuildBlockContactReq(java.lang.String address, boolean block)

        Primitive request = new Primitive(ImpsTags.BlockEntity_Request);
        ImpsVersion version = mConfig.getImpsVersion();

        if (version == ImpsVersion.IMPS_VERSION_13) {
            request.addElement(ImpsTags.BlockListInUse, true);
            request.addElement(ImpsTags.GrantListInUse, false);
        }

        PrimitiveElement blockList = request.addElement(ImpsTags.BlockList);
        if (version != ImpsVersion.IMPS_VERSION_13) {
            blockList.addChild(ImpsTags.InUse, true);
        }
        PrimitiveElement entityList = blockList.addChild(block ?
                ImpsTags.AddList : ImpsTags.RemoveList);
        entityList.addChild(ImpsTags.UserID, address);
        return request;
    
private PrimitivebuildCreateListReq(java.lang.String name, java.util.Collection contacts, boolean isDefault, ImpsAddress listAddress)

        Primitive createListRequest = new Primitive(ImpsTags.CreateList_Request);
        createListRequest.addElement(listAddress.toPrimitiveElement());

        // add initial contacts, if any
        if (null != contacts && !contacts.isEmpty()) {
            PrimitiveElement nickList = createListRequest.addElement(ImpsTags.NickList);

            for (Contact contact : contacts) {
                nickList.addChild(buildNickNameElem(contact));
            }
        }

        PrimitiveElement contactListProp = createListRequest.addElement(
                ImpsTags.ContactListProperties);

        contactListProp.addPropertyChild(ImpsConstants.DisplayName, name);
        contactListProp.addPropertyChild(ImpsConstants.Default,
                ImpsUtils.toImpsBool(isDefault));

        return createListRequest;
    
private PrimitivebuildDelListReq(com.android.im.engine.ContactList list)

        Primitive delListRequest = new Primitive(ImpsTags.DeleteList_Request);
        delListRequest.addElement(((ImpsAddress)list.getAddress())
                .toPrimitiveElement());
        return delListRequest;
    
private PrimitivebuildListManageRequest(com.android.im.engine.ContactList list, java.util.Collection contactsToAdd, java.util.Collection contactsToRemove, java.lang.String listName)

        // Create ListManage request
        Primitive req = new Primitive(ImpsTags.ListManage_Request);
        req.addElement(((ImpsAddress)list.getAddress()).toPrimitiveElement());
        req.addElement(ImpsTags.ReceiveList, false);

        // If there are any pending added contacts, add them to the addNickList
        if (contactsToAdd != null && !contactsToAdd.isEmpty()) {
            PrimitiveElement addList = req.addElement(ImpsTags.AddNickList);

            for (Contact c : contactsToAdd) {
                PrimitiveElement nickNameElem = addList.addChild(ImpsTags.NickName);
                nickNameElem.addChild(ImpsTags.Name, c.getName());
                nickNameElem.addChild(ImpsTags.UserID, c.getAddress().getFullName());
            }
        }

        // If there are any pending removed contacts, add them to the removeNickList
        if (contactsToRemove != null && !contactsToRemove.isEmpty()) {
            PrimitiveElement removeList = req.addElement(ImpsTags.RemoveNickList);

            for (Contact c : contactsToRemove) {
                removeList.addChild(ImpsTags.UserID, c.getAddress().getFullName());
            }
        }

        // Add the list properties
        if (listName != null) {
            PrimitiveElement requestProps = req.addElement(ImpsTags.ContactListProperties);
            requestProps.addPropertyChild(ImpsConstants.DisplayName, listName);
        }

        return req;
    
private PrimitiveElementbuildNickNameElem(com.android.im.engine.Contact contact)
Generate NickName element for a specific contact.

param
contact the contact which provides the info of the NickName elem
return

        PrimitiveElement nickName = new PrimitiveElement(ImpsTags.NickName);

        nickName.addChild(ImpsTags.Name, contact.getName());
        nickName.addChild(((ImpsAddress)contact.getAddress()).toPrimitiveElement());

        return nickName;
    
private PrimitivebuildSubscribePresenceRequest(java.util.ArrayList addresses)

        Primitive request = new Primitive(ImpsTags.SubscribePresence_Request);

        // XXX: Workaround on OZ IMPS GTalk server which only supports a few
        // basic presence attributes. The PresenceSubList is optional and an
        // empty List or missing list indicates all available presence
        // attributes are desired but the OZ server doens't quite follow the
        // spec here. It won't send any PresenceNotification either when we
        // don't send PresenceSubList or we request more PA than it supports.
        if(mConfig.supportBasicPresenceOnly()){
            PrimitiveElement presenceList = request.addElement(ImpsTags.PresenceSubList);
            presenceList.setAttribute(ImpsTags.XMLNS, mConfig.getPresenceNs());
            for(String pa : ImpsClientCapability.getBasicPresenceAttributes()) {
                presenceList.addChild(pa);
            }
        }

        for (ImpsAddress address : addresses) {
            request.addElement(address.toPrimitiveElement());
        }

        return request;
    
private PrimitivebuildSubscribeToContactsRequest(java.util.ArrayList contacts)

        ArrayList<ImpsAddress> addresses = new ArrayList<ImpsAddress>();

        for (Contact contact : contacts) {
            addresses.add((ImpsAddress)contact.getAddress());
        }

        Primitive request = buildSubscribePresenceRequest(addresses);
        return request;
    
private PrimitivebuildSubscribeToListsRequest(java.util.Collection lists)

        ArrayList<ImpsAddress> addresses = new ArrayList<ImpsAddress>();

        for (ContactList list : lists) {
            addresses.add((ImpsAddress)list.getAddress());
        }

        Primitive subscribePresenceRequest = buildSubscribePresenceRequest(addresses);

        subscribePresenceRequest.addElement(ImpsTags.AutoSubscribe, true);

        return subscribePresenceRequest;
    
public com.android.im.engine.ContactcreateTemporaryContact(java.lang.String address)

        ImpsAddress impsAddr = new ImpsUserAddress(normalizeAddress(address));
        return new Contact(impsAddr, impsAddr.getScreenName());
    
public voiddeclineSubscriptionRequest(java.lang.String contact)

        handleSubscriptionRequest(contact, false);
    
protected voiddoAddContactToListAsync(java.lang.String addressStr, com.android.im.engine.ContactList list)

        ImpsUserAddress address = new ImpsUserAddress(addressStr);

        Contact contact;
        if (getContact(address) != null) {
            contact = getContact(address);
        } else {
            contact = new Contact(address, address.getScreenName());
        }

        if (isBlocked(contact)) {
            throw new ImException(ImErrorInfo.CANT_ADD_BLOCKED_CONTACT,
            "Contact has been blocked");
        }

        addContactToListAsync(contact, list);
    
protected voiddoBlockContactAsync(java.lang.String address, boolean block)

        Primitive request = buildBlockContactReq(address, block);
        final Address contactAddress = new ImpsUserAddress(address);
        AsyncTransaction tx = new AsyncTransaction(mTransactionManager) {

            @Override
            public void onResponseError(ImpsErrorInfo error) {
                Contact c = getContact(contactAddress);
                if(c == null) {
                    c = new Contact(contactAddress, contactAddress.getScreenName());
                }
                notifyContactError(
                        block ? ContactListListener.ERROR_BLOCKING_CONTACT
                                : ContactListListener.ERROR_UNBLOCKING_CONTACT,
                        error, null, c);
            }

            @Override
            public void onResponseOk(Primitive response) {
                Contact c = getContact(contactAddress);
                if(c == null) {
                    c = new Contact(contactAddress, contactAddress.getScreenName());
                }
                notifyBlockContact(c, block);
            }
        };
        tx.sendRequest(request);
    
protected voiddoCreateContactListAsync(java.lang.String name, java.util.Collection contacts, boolean isDefault)

        ImpsAddress selfAddress = mConnection.getSession().getLoginUserAddress();
        ImpsAddress listAddress = new ImpsContactListAddress(selfAddress, name);

        final ContactList list = new ContactList(listAddress, name,
                isDefault, contacts, this);

        Primitive createListRequest = buildCreateListReq(name, contacts,
                isDefault, listAddress);

        AsyncTransaction tx = new AsyncTransaction(mTransactionManager) {

            @Override
            public void onResponseError(ImpsErrorInfo error) {
                notifyContactError(ContactListListener.ERROR_CREATING_LIST,
                        error, name, null);
            }

            @Override
            public void onResponseOk(Primitive response) {
                notifyContactListCreated(list);

                if (mConfig.usePrensencePolling()) {
                    getPresencePollingManager().resetPollingContacts();
                } else {
                    subscribeToListAsync(list, null);
                }
            }
        };

        tx.sendRequest(createListRequest);
    
public voiddoDeleteContactListAsync(com.android.im.engine.ContactList list)
Delete a specified contact list asyncLoginWrapper.

param
list the contact list to be deleted

        Primitive delListRequest = buildDelListReq(list);

        AsyncTransaction tx = new AsyncTransaction(mTransactionManager) {

            @Override
            public void onResponseError(ImpsErrorInfo error) {
                notifyContactError(ContactListListener.ERROR_DELETING_LIST,
                        error, list.getName(), null);
            }

            @Override
            public void onResponseOk(Primitive response) {
                notifyContactListDeleted(list);
                if (mConfig.usePrensencePolling()) {
                    getPresencePollingManager().resetPollingContacts();
                } else if (!mAllowAutoSubscribe) {
                    unsubscribeToListAsync(list, new AsyncCompletion(){
                        public void onComplete() {}

                        public void onError(ImErrorInfo error) {
                            // don't bother to alert this error since the
                            // list has already been removed.
                            ImpsLog.log("Warning: unsubscribing list presence failed");
                        }
                    });
                }
            }
        };

        tx.sendRequest(delListRequest);
    
protected voiddoRemoveContactFromListAsync(com.android.im.engine.Contact contact, com.android.im.engine.ContactList list)

        ArrayList<Contact> contacts = new ArrayList<Contact>();

        contacts.add(contact);
        updateContactListAsync(list, null, contacts, null, new AsyncCompletion(){
            public void onComplete() {
                ImpsLog.log("removed contact");
                notifyContactListUpdated(list,
                        ContactListListener.LIST_CONTACT_REMOVED, contact);

                if (!mAllowAutoSubscribe) {
                    unsubscribeToContactAsync(contact, new AsyncCompletion(){
                        public void onComplete() {}

                        public void onError(ImErrorInfo error) {
                            // don't bother to alert this error since the
                            // contact has already been removed.
                            ImpsLog.log("Warning: unsubscribing contact presence failed");
                        }
                    });
                }
            }

            public void onError(ImErrorInfo error) {
                ImpsLog.log("remove contact error:" + error);
                notifyContactError(ContactListListener.ERROR_REMOVING_CONTACT,
                        error, list.getName(), contact);
            }
        });
    
private voidextractAndNotifyPresence(PrimitiveElement content)

        ArrayList<Contact> updated = new ArrayList<Contact>();
        PresenceMapping presenceMapping = mConfig.getPresenceMapping();

        ArrayList<PrimitiveElement> presenceList = content.getChildren(ImpsTags.Presence);
        for (PrimitiveElement presenceElem : presenceList) {
            String userId = presenceElem.getChildContents(ImpsTags.UserID);
            if (userId == null) {
                continue;
            }
            PrimitiveElement presenceSubList = presenceElem.getChild(ImpsTags.PresenceSubList);
            Presence presence = ImpsPresenceUtils.extractPresence(presenceSubList, presenceMapping);
            // Find out the contact in all lists and update their presence
            for(ContactList list : mContactLists) {
                Contact contact = list.getContact(userId);
                if (contact != null) {
                    contact.setPresence(presence);
                    updated.add(contact);
                }
            }
        }
        if (!updated.isEmpty()) {
            notifyContactsPresenceUpdated(updated.toArray(new Contact[updated.size()]));
        }
    
voidextractBlockedContacts(Primitive response)

        mBlockedList.clear();
        PrimitiveElement blockList = response.getElement(ImpsTags.BlockList);
        if(blockList == null) {
            return;
        }
        PrimitiveElement entityList = blockList.getChild(ImpsTags.EntityList);
        if(entityList == null) {
            return;
        }
        for (PrimitiveElement entity : entityList.getChildren()) {
            if (ImpsTags.UserID.equals(entity.getTagName())) {
                String userId = entity.getContents();
                if (userId == null || userId.length() == 0) {
                    ImpsLog.logError("Empty UserID in BlockList");
                    continue;
                }
                ImpsAddress userAddress = new ImpsUserAddress(entity.getContents());
                notifyBlockContact(new Contact(userAddress, userAddress.getScreenName()),
                        true);
            }
        }
    
com.android.im.engine.ContactListextractContactList(Primitive response, ImpsAddress address)

        String screenName = address.getScreenName();
        boolean isDefault = false;
        PrimitiveElement propertyElem = response.getElement(ImpsTags.ContactListProperties);
        if (null != propertyElem) {
            for (PrimitiveElement elem : propertyElem.getChildren()) {
                if (elem.getTagName().equals(ImpsTags.Property)) {
                    String name = elem.getChildContents(ImpsTags.Name);
                    String value = elem.getChildContents(ImpsTags.Value);

                    if (name.equals(ImpsConstants.DisplayName)) {
                        screenName = value;
                    } else if (name.equals(ImpsTags.Default)) {
                        isDefault = ImpsUtils.isTrue(value);
                    }
                }
            }
        }

        PrimitiveElement nickListElem = response.getElement(ImpsTags.NickList);
        if (null == nickListElem) {
            return new ContactList(address, screenName, isDefault, null, this);
        }

        Vector<Contact> contacts = new Vector<Contact>();
        for (PrimitiveElement elem : nickListElem.getChildren()) {
            String id = null;
            String name = null;

            String tag = elem.getTagName();
            if (tag.equals(ImpsTags.NickName)) {
                id = elem.getChild(ImpsTags.UserID).getContents();
                name = elem.getChild(ImpsTags.Name).getContents();
            } else if (tag.equals(ImpsTags.UserID)){
                id = elem.getContents();
            }

            if (id != null) {
                Address contactAddress = new ImpsUserAddress(id);
                Contact c = getContact(contactAddress);
                if (c == null) {
                    if (name == null) {
                        name = contactAddress.getScreenName();
                    }
                    c = new Contact(contactAddress, name);
                }
                contacts.add(c);
            }
        }
        return new ContactList(address, screenName, isDefault, contacts, this);
    
java.util.VectorextractListAddresses(Primitive response)

        Vector<ImpsContactListAddress> addresses = new Vector<ImpsContactListAddress>();

        for (PrimitiveElement child : response.getContentElement()
                .getChildren()) {
            if (child.getTagName().equals(ImpsTags.ContactList)) {
                // FIXME: ignore the PEP contact lists for now
                // PEP: "Presence Enhanced Phonebook and Instant Messaging
                // Application Category" specification from Nokia and SonyEricsson.
                //  ~IM_subscriptions
                //  ~pep1.0_privatelist
                //  ~pep1.0_blocklist
                //  ~pep1.0_friendlist
                //  ~pep1.0_subscriptions-*
                if (child.getContents().contains("/~pep1.0_")) {
                    continue;
                }
                addresses.add(new ImpsContactListAddress(child.getContents()));
            }
        }

        String defaultListAddress = response.getElementContents(ImpsTags.DefaultContactList);
        if (null != defaultListAddress) {
            addresses.add(new ImpsContactListAddress(defaultListAddress));
        }

        return addresses;
    
public voidfetchPresence(ImpsAddress[] addresses)

        if (addresses == null || addresses.length == 0) {
            return;
        }

        Primitive request = new Primitive(ImpsTags.GetPresence_Request);
        for (ImpsAddress addr : addresses) {
            request.addElement(addr.toPrimitiveElement());
        }
        AsyncTransaction tx = new AsyncTransaction(mTransactionManager){
            @Override
            public void onResponseError(ImpsErrorInfo error) {
                ImpsLog.logError("Failed to get presence:" + error.toString());
            }

            @Override
            public void onResponseOk(Primitive response) {
                extractAndNotifyPresence(response.getContentElement());
            }
        };
        tx.sendRequest(request);
    
public ImpsAddress[]getAllListAddress()

        int count = mContactLists.size();
        ImpsAddress[] res = new ImpsContactListAddress[count];

        int index = 0;
        for (ContactList l : mContactLists) {
            res[index++] = (ImpsContactListAddress) l.getAddress();
        }

        return res;
    
protected com.android.im.engine.ImConnectiongetConnection()

        return mConnection;
    
PresencePollingManagergetPresencePollingManager()

        if (mPollingMgr == null) {
            mPollingMgr = new PresencePollingManager(this,
                    mConfig.getPresencePollInterval());
        }
        return mPollingMgr;
    
java.lang.StringgetPropertyValue(java.lang.String propertyName, PrimitiveElement properties)

        for (PrimitiveElement property : properties.getChildren(ImpsTags.Property)) {
            if (propertyName.equals(property.getChildContents(ImpsTags.Name))) {
                return property.getChildContents(ImpsTags.Value);
            }
        }

        return null;
    
private voidhandleSubscriptionRequest(java.lang.String contact, boolean accept)


        Primitive request = new Primitive(ImpsTags.PresenceAuthUser);
        request.addElement(ImpsTags.UserID, contact);
        request.addElement(ImpsTags.Acceptance, accept);
        AsyncTransaction tx = new AsyncTransaction(mTransactionManager){
            @Override
            public void onResponseError(ImpsErrorInfo error) {
                SubscriptionRequestListener listener = getSubscriptionRequestListener();
                if (listener != null) {
                    if (accept) {
                        listener.onApproveSubScriptionError(contact, error);
                    } else {
                        listener.onDeclineSubScriptionError(contact, error);
                    }
                }
            }

            @Override
            public void onResponseOk(Primitive response) {
                SubscriptionRequestListener listener = getSubscriptionRequestListener();
                if (listener != null) {
                    if (accept) {
                        listener.onSubscriptionApproved(contact);
                    } else {
                        listener.onSubscriptionDeclined(contact);
                    }
                }
            }
        };
        tx.sendRequest(request);
    
public synchronized voidloadContactListsAsync()

        if (getState() != LISTS_NOT_LOADED) {
            return;
        }

        setState(LISTS_LOADING);

        // load blocked list first
        Primitive request = new Primitive(ImpsTags.GetBlockedList_Request);

        AsyncTransaction tx = new AsyncTransaction(mTransactionManager) {
            @Override
            public void onResponseError(ImpsErrorInfo error) {
                // don't notify the 501 not implemented error
                if (error.getCode() != ImpsConstants.STATUS_NOT_IMPLEMENTED) {
                    notifyContactError(
                            ContactListListener.ERROR_LOADING_BLOCK_LIST,
                            error, null, null);
                }

                next();
            }

            @Override
            public void onResponseOk(Primitive response) {
                extractBlockedContacts(response);

                next();
            }

            private void next() {
                setState(BLOCKED_LIST_LOADED);
                new LoadContactsTransaction().startGetContactLists();
                //createDefaultAttributeListAsync();
            }
        };

        tx.sendRequest(request);
    
voidloadContactsOfListAsync(ImpsAddress address, AsyncCompletion completion)

        Primitive listManageRequest = new Primitive(ImpsTags.ListManage_Request);

        listManageRequest.addElement(address.toPrimitiveElement());
        listManageRequest.addElement(ImpsTags.ReceiveList, true);

        AsyncTransaction tx = new AsyncTransaction(mTransactionManager) {
            @Override
            public void onResponseError(ImpsErrorInfo error) {
                completion.onError(error);
            }

            @Override
            public void onResponseOk(Primitive response) {
                final ContactList list = extractContactList(response, address);

                mContactLists.add(list);
                if (list.isDefault()) {
                    mDefaultContactList = list;
                }

                if (mConfig.usePrensencePolling()) {
                    completion.onComplete();
                } else {
                    subscribeToListAsync(list, completion);
                }
            }
        };

        tx.sendRequest(listManageRequest);
    
public java.lang.StringnormalizeAddress(java.lang.String address)

        String s = address.toLowerCase();
        if (!s.startsWith(ImpsConstants.ADDRESS_PREFIX)) {
            s = ImpsConstants.ADDRESS_PREFIX + s;
        }
        if (mDefaultDomain != null && s.indexOf('@") == -1) {
            s = s + "@" + mDefaultDomain;
        }
        return s;
    
public voidnotifyServerTransaction(ServerTransaction tx)

        Primitive request = tx.getRequest();
        String type = request.getType();
        if (ImpsTags.PresenceNotification_Request.equals(type)) {
            tx.sendStatusResponse(ImpsConstants.SUCCESS_CODE);

            PrimitiveElement content = request.getContentElement();
            extractAndNotifyPresence(content);
        } else if (ImpsTags.PresenceAuth_Request.equals(type)) {
            tx.sendStatusResponse(ImpsConstants.SUCCESS_CODE);

            String userId = request.getElementContents(ImpsTags.UserID);
            Contact contact = getContact(userId);
            if (contact == null) {
                ImpsAddress address = new ImpsUserAddress(userId);
                contact = new Contact(address, address.getScreenName());
            }
            if (getState() < LISTS_LOADED) {
                if (mSubscriptionRequests == null) {
                    mSubscriptionRequests = new ArrayList<Contact>();
                }
                mSubscriptionRequests.add(contact);
            } else {
                SubscriptionRequestListener listener = getSubscriptionRequestListener();
                if (listener != null) {
                    listener.onSubScriptionRequest(contact);
                }
            }
        }
    
voidonContactListsLoaded()

        notifyContactListsLoaded();

        if (mConfig.usePrensencePolling()) {
            fetchPresence(getAllListAddress());
        }

        // notify the pending subscription requests received before contact
        // lists has been loaded.
        SubscriptionRequestListener listener = getSubscriptionRequestListener();
        if (mSubscriptionRequests != null && listener != null) {
            for (Contact c : mSubscriptionRequests) {
                listener.onSubScriptionRequest(c);
            }
        }
        ((ImpsChatSessionManager) mConnection.getChatSessionManager()).start();
    
voidreset()

        setState(LISTS_NOT_LOADED);
    
protected voidsetListNameAsync(java.lang.String name, com.android.im.engine.ContactList list)

        updateContactListAsync(list, null, null, name, new AsyncCompletion(){
            public void onComplete() {
                notifyContactListNameUpdated(list, name);
            }

            public void onError(ImErrorInfo error) {
                notifyContactError(ContactListListener.ERROR_RENAMING_LIST,
                        error, list.getName(), null);
            }
        });
    
voidsubscribeToAllListAsync()

        AsyncCompletion completion = new AsyncCompletion(){
            public void onComplete() {
                // do nothing
            }
            public void onError(ImErrorInfo error) {
                notifyContactError(ContactListListener.ERROR_RETRIEVING_PRESENCE,
                        error, null, null);
            }
        };
        subscribeToListsAsync(mContactLists,completion);
    
voidsubscribeToContactsAsync(java.util.ArrayList contacts, AsyncCompletion completion)

        Primitive request = buildSubscribeToContactsRequest(contacts);

        SimpleAsyncTransaction tx = new SimpleAsyncTransaction(mTransactionManager, completion);

        tx.sendRequest(request);
    
voidsubscribeToListAsync(com.android.im.engine.ContactList list, AsyncCompletion completion)

        Vector<ContactList> lists = new Vector<ContactList>();

        lists.add(list);

        subscribeToListsAsync(lists, completion);
    
voidsubscribeToListsAsync(java.util.Vector contactLists, AsyncCompletion completion)

        if (contactLists.isEmpty()) {
            return;
        }

        Primitive request = buildSubscribeToListsRequest(contactLists);

        AsyncTransaction tx = new AsyncTransaction(mTransactionManager) {
            @Override
            public void onResponseError(ImpsErrorInfo error) {
                if (error.getCode()
                        == ImpsConstants.STATUS_AUTO_SUBSCRIPTION_NOT_SUPPORTED) {
                    mAllowAutoSubscribe = false;
                    ArrayList<Contact> contacts = new ArrayList<Contact>();
                    for (ContactList list : contactLists) {
                        contacts.addAll(list.getContacts());
                    }

                    subscribeToContactsAsync(contacts, completion);
                } else {
                    if (completion != null) {
                        completion.onError(error);
                    }
                }
            }

            @Override
            public void onResponseOk(Primitive response) {
                if (completion != null) {
                    completion.onComplete();
                }
            }

        };

        tx.sendRequest(request);
    
voidunsubscribeToContactAsync(com.android.im.engine.Contact contact, AsyncCompletion completion)

        Primitive request = new Primitive(ImpsTags.UnsubscribePresence_Request);
        request.addElement(ImpsTags.User).addPropertyChild(ImpsTags.UserID,
                contact.getAddress().getFullName());

        SimpleAsyncTransaction tx = new SimpleAsyncTransaction(
                mTransactionManager, completion);

        tx.sendRequest(request);
    
voidunsubscribeToListAsync(com.android.im.engine.ContactList list, AsyncCompletion completion)

        Primitive request = new Primitive(ImpsTags.UnsubscribePresence_Request);
        request.addElement(ImpsTags.ContactList, list.getAddress().getFullName());

        SimpleAsyncTransaction tx = new SimpleAsyncTransaction(
                mTransactionManager, completion);

        tx.sendRequest(request);
    
private voidupdateContactListAsync(com.android.im.engine.ContactList list, java.util.ArrayList contactsToAdd, java.util.ArrayList contactsToRemove, java.lang.String listName, AsyncCompletion completion)

        Primitive request = buildListManageRequest(list, contactsToAdd,
                contactsToRemove, listName);

        SimpleAsyncTransaction tx = new SimpleAsyncTransaction(mTransactionManager, completion);
        tx.sendRequest(request);