FileDocCategorySizeDatePackage
ContactListTreeAdapter.javaAPI DocAndroid 1.5 API26741Wed May 06 22:42:46 BST 2009com.android.im.app

ContactListTreeAdapter

public class ContactListTreeAdapter extends android.widget.BaseExpandableListAdapter implements android.widget.AbsListView.OnScrollListener

Fields Summary
private static final String[]
CONTACT_LIST_PROJECTION
private static final int
COLUMN_CONTACT_LIST_ID
private static final int
COLUMN_CONTACT_LIST_NAME
android.app.Activity
mActivity
SimpleAlertHandler
mHandler
private android.view.LayoutInflater
mInflate
private long
mProviderId
long
mAccountId
android.database.Cursor
mOngoingConversations
android.database.Cursor
mSubscriptions
boolean
mDataValid
ListTreeAdapter
mAdapter
private boolean
mHideOfflineContacts
final MyContentObserver
mContentObserver
final MyDataSetObserver
mDataSetObserver
private ArrayList
mExpandedGroups
private static final int
TOKEN_CONTACT_LISTS
private static final int
TOKEN_ONGOING_CONVERSATION
private static final int
TOKEN_SUBSCRITPTION
private static final String
NON_CHAT_AND_BLOCKED_CONTACTS
private static final String
CONTACTS_SELECTION
private static final String
ONLINE_CONTACT_SELECTION
static final String[]
CONTACT_COUNT_PROJECTION
android.content.ContentQueryMap
mOnlineContactsCountMap
private QueryHandler
mQueryHandler
private int
mScrollState
private boolean
mAutoRequery
private boolean
mRequeryPending
Constructors Summary
public ContactListTreeAdapter(com.android.im.IImConnection conn, android.app.Activity activity)

        mActivity = activity;
        mInflate = activity.getLayoutInflater();
        mHandler = new SimpleAlertHandler(activity);

        mAdapter = new ListTreeAdapter(null);

        mContentObserver = new MyContentObserver();
        mDataSetObserver = new MyDataSetObserver();
        mExpandedGroups = new ArrayList<Integer>();
        mQueryHandler = new QueryHandler(activity);

        changeConnection(conn);
    
Methods Summary
public voidchangeConnection(com.android.im.IImConnection conn)

        mQueryHandler.cancelOperation(TOKEN_ONGOING_CONVERSATION);
        mQueryHandler.cancelOperation(TOKEN_SUBSCRITPTION);
        mQueryHandler.cancelOperation(TOKEN_CONTACT_LISTS);

        synchronized (this) {
            if (mOngoingConversations != null) {
                mOngoingConversations.close();
                mOngoingConversations = null;
            }
            if (mSubscriptions != null) {
                mSubscriptions.close();
                mSubscriptions = null;
            }
            if (mOnlineContactsCountMap != null) {
                mOnlineContactsCountMap.close();
            }
        }

        mAdapter.notifyDataSetChanged();
        if (conn != null) {
            try {
                mProviderId = conn.getProviderId();
                mAccountId = conn.getAccountId();
                startQueryOngoingConversations();
                startQueryContactLists();
                startQuerySubscriptions();
            } catch (RemoteException e) {
                // Service died!
            }
        }
    
public java.lang.ObjectgetChild(int groupPosition, int childPosition)

        if (isPosForOngoingConversation(groupPosition)) {
            // No cursor exists for the "Empty" TextView item
            if (getOngoingConversationCount() == 0) return null;
            return moveTo(getOngoingConversations(), childPosition);
        } else if (isPosForSubscription(groupPosition)) {
            return moveTo(getSubscriptions(), childPosition);
        } else {
            return mAdapter.getChild(getChildAdapterPosition(groupPosition), childPosition);
        }
    
private intgetChildAdapterPosition(int groupPosition)

        if (getSubscriptionCount() > 0) {
            return groupPosition - 2;
        } else {
            return groupPosition - 1;
        }
    
public longgetChildId(int groupPosition, int childPosition)

        if (isPosForOngoingConversation(groupPosition)) {
            // No cursor id exists for the "Empty" TextView item
            if (getOngoingConversationCount() == 0) return 0;
            return getId(getOngoingConversations(), childPosition);
        } else if (isPosForSubscription(groupPosition)) {
            return getId(getSubscriptions(), childPosition);
        } else {
            return mAdapter.getChildId(getChildAdapterPosition(groupPosition), childPosition);
        }
    
public android.view.ViewgetChildView(int groupPosition, int childPosition, boolean isLastChild, android.view.View convertView, android.view.ViewGroup parent)

        boolean isOngoingConversation = isPosForOngoingConversation(groupPosition);
        boolean displayEmpty = isOngoingConversation && (getOngoingConversationCount() == 0);
        if (isOngoingConversation || isPosForSubscription(groupPosition)) {
            View view = null;
            if (convertView != null) {
                // use the convert view if it matches the type required by displayEmpty
                if (displayEmpty && (convertView instanceof TextView)) {
                    view = convertView;
                    ((TextView) view).setText(mActivity.getText(R.string.empty_conversation_group));
                } else if (!displayEmpty && (convertView instanceof ContactView)) {
                     view = convertView;
                }
            }
            if (view == null) {
                if (displayEmpty) {
                    view = newEmptyView(parent);
                } else {
                    view = newChildView(parent);
                }
            }
            if (!displayEmpty) {
                Cursor cursor = isPosForOngoingConversation(groupPosition)
                        ? getOngoingConversations() : getSubscriptions();
                cursor.moveToPosition(childPosition);
                ((ContactView) view).bind(cursor, null, isScrolling());
            }
            return view;
        } else {
            return mAdapter.getChildView(getChildAdapterPosition(groupPosition), childPosition,
                    isLastChild, convertView, parent);
        }
    
public intgetChildrenCount(int groupPosition)

        if (!mDataValid) {
            return 0;
        }
        if (isPosForOngoingConversation(groupPosition)) {
            // if there are no ongoing conversations, we want to display "empty" textview
            int count = getOngoingConversationCount();
            if (count == 0) {
                count = 1;
            }
            return count;
        } else if (isPosForSubscription(groupPosition)) {
            return getSubscriptionCount();
        } else {
            // XXX getChildrenCount() may be called with an invalid groupPosition that is larger
            // than the total number of all groups.
            int position = getChildAdapterPosition(groupPosition);
            if (position >= mAdapter.getGroupCount()) {
                Log.w(ImApp.LOG_TAG, "getChildrenCount out of range");
                return 0;
            }
            return mAdapter.getChildrenCount(position);
        }
    
public int[]getExpandedGroups()

        ArrayList<Integer> expandedGroups = mExpandedGroups;
        int size = expandedGroups.size();
        int[] res = new int[size];
        for (int i = 0; i < size; i++) {
            res[i] = expandedGroups.get(i);
        }
        return res;
    
public java.lang.ObjectgetGroup(int groupPosition)

        if (isPosForOngoingConversation(groupPosition)
                || isPosForSubscription(groupPosition)) {
            return null;
        } else {
            return mAdapter.getGroup(getChildAdapterPosition(groupPosition));
        }
    
public intgetGroupCount()

        if (!mDataValid) {
            return 0;
        }
        int count = mAdapter.getGroupCount();

        // ongoing conversations
        count++;

        if (getSubscriptionCount() > 0) {
            count++;
        }

        return count;
    
public longgetGroupId(int groupPosition)

        if (isPosForOngoingConversation(groupPosition) || isPosForSubscription(groupPosition)) {
            return 0;
        } else {
            return mAdapter.getGroupId(getChildAdapterPosition(groupPosition));
        }
    
public android.view.ViewgetGroupView(int groupPosition, boolean isExpanded, android.view.View convertView, android.view.ViewGroup parent)

        if (isPosForOngoingConversation(groupPosition) || isPosForSubscription(groupPosition)) {
            View v;
            if (convertView != null) {
                v = convertView;
            } else {
                v = newGroupView(parent);
            }

            TextView text1 = (TextView)v.findViewById(R.id.text1);
            TextView text2 = (TextView)v.findViewById(R.id.text2);

            Resources r = v.getResources();
            ImApp app = ImApp.getApplication(mActivity);
            BrandingResources brandingRes = app.getBrandingResource(mProviderId);
            String text = isPosForOngoingConversation(groupPosition) ?
                    brandingRes.getString(
                            BrandingResourceIDs.STRING_ONGOING_CONVERSATION,
                            getOngoingConversationCount()) :
                    r.getString(R.string.subscriptions);
            text1.setText(text);
            text2.setVisibility(View.GONE);
            return v;
        } else {
            return mAdapter.getGroupView(getChildAdapterPosition(groupPosition), isExpanded,
                    convertView, parent);
        }
    
private longgetId(android.database.Cursor cursor, int position)

        if (cursor.moveToPosition(position)) {
            return cursor.getLong(ContactView.COLUMN_CONTACT_ID);
        }
        return 0;
    
private intgetOngoingConversationCount()

        Cursor c = getOngoingConversations();
        return c == null ? 0 : c.getCount();
    
private synchronized android.database.CursorgetOngoingConversations()

        if (mOngoingConversations == null) {
            startQueryOngoingConversations();
        }
        return mOngoingConversations;
    
private intgetSubscriptionCount()

        Cursor c = getSubscriptions();
        return c == null ? 0 : c.getCount();
    
private synchronized android.database.CursorgetSubscriptions()

        if (mSubscriptions == null) {
            startQuerySubscriptions();
        }
        return mSubscriptions;
    
public booleanhasStableIds()

        return true;
    
public booleanisChildSelectable(int groupPosition, int childPosition)

        if (isPosForOngoingConversation(groupPosition)) {
            // "Empty" TextView is not selectable
            if (getOngoingConversationCount()==0) return false;
            return true;
        }
        if (isPosForSubscription(groupPosition)) return true;
        return mAdapter.isChildSelectable(getChildAdapterPosition(groupPosition), childPosition);
    
public booleanisPosForOngoingConversation(int groupPosition)

        return groupPosition == 0;
    
public booleanisPosForSubscription(int groupPosition)

        return groupPosition == 1 && getSubscriptionCount() > 0;
    
public booleanisScrolling()

        return mScrollState == OnScrollListener.SCROLL_STATE_FLING;
    
static final voidlog(java.lang.String msg)


         
        Log.d(ImApp.LOG_TAG, "<ContactListAdapter>" + msg);
    
private android.database.CursormoveTo(android.database.Cursor cursor, int position)

        if (cursor.moveToPosition(position)) {
            return cursor;
        }
        return null;
    
android.view.ViewnewChildView(android.view.ViewGroup parent)

        return mInflate.inflate(R.layout.contact_view, parent, false);
    
android.view.ViewnewEmptyView(android.view.ViewGroup parent)

        return mInflate.inflate(R.layout.empty_conversation_group_view, parent, false);
    
android.view.ViewnewGroupView(android.view.ViewGroup parent)

        return mInflate.inflate(R.layout.group_view, parent, false);
    
public voidonGroupCollapsed(int groupPosition)

        super.onGroupCollapsed(groupPosition);
        mExpandedGroups.remove(Integer.valueOf(groupPosition));
        int pos = getChildAdapterPosition(groupPosition);
        if (pos >= 0) {
            mAdapter.onGroupCollapsed(pos);
        }
    
public voidonGroupExpanded(int groupPosition)

        super.onGroupExpanded(groupPosition);
        mExpandedGroups.add(groupPosition);
        int pos = getChildAdapterPosition(groupPosition);
        if (pos >= 0) {
            mAdapter.onGroupExpanded(pos);
        }
    
public voidonScroll(android.widget.AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)

        // no op
    
public voidonScrollStateChanged(android.widget.AbsListView view, int scrollState)

        int oldState = mScrollState;

        mScrollState = scrollState;
        //  If we just finished a fling then some items may not have an icon
        //  So force a full redraw now that the fling is complete
        if (oldState == OnScrollListener.SCROLL_STATE_FLING) {
            notifyDataSetChanged();
        }
    
public voidregisterDataSetObserver(android.database.DataSetObserver observer)

        mAdapter.registerDataSetObserver(observer);
        super.registerDataSetObserver(observer);
    
public voidsetHideOfflineContacts(boolean hide)

        if (mHideOfflineContacts != hide) {
            mHideOfflineContacts = hide;
            mAdapter.notifyDataSetChanged();
        }
    
synchronized voidsetOngoingConversations(android.database.Cursor c)

        if (mOngoingConversations != null) {
            mOngoingConversations.unregisterContentObserver(mContentObserver);
            mOngoingConversations.unregisterDataSetObserver(mDataSetObserver);
            mOngoingConversations.close();
        }
        c.registerContentObserver(mContentObserver);
        c.registerDataSetObserver(mDataSetObserver);
        mOngoingConversations = c;
    
synchronized voidsetSubscriptions(android.database.Cursor c)

        if (mSubscriptions != null) {
            mSubscriptions.close();
        }
        // we don't need to register observers on mSubscriptions because
        // we already have observers on mOngoingConversations and they
        // will be notified if there is any changes of subscription
        // since the two cursors come from the same table.
        mSubscriptions = c;
    
public booleanstableIds()

        return true;
    
public voidstartAutoRequery()

        if (Log.isLoggable(ImApp.LOG_TAG, Log.DEBUG)){
            log("startAutoRequery()");
        }
        mAutoRequery = true;
        if (mRequeryPending) {
            mRequeryPending = false;
            startQueryOngoingConversations();
        }
    
private voidstartQueryContactLists()

        if (Log.isLoggable(ImApp.LOG_TAG, Log.DEBUG)){
            log("startQueryContactLists()");
        }

        Uri uri = Im.ContactList.CONTENT_URI;
        uri = ContentUris.withAppendedId(uri, mProviderId);
        uri = ContentUris.withAppendedId(uri, mAccountId);

        mQueryHandler.startQuery(TOKEN_CONTACT_LISTS, null, uri, CONTACT_LIST_PROJECTION,
                null, null, Im.ContactList.DEFAULT_SORT_ORDER);
    
voidstartQueryContacts(long listId)

        if (Log.isLoggable(ImApp.LOG_TAG, Log.DEBUG)){
            log("startQueryContacts - listId=" + listId);
        }

        String selection = mHideOfflineContacts ? ONLINE_CONTACT_SELECTION : CONTACTS_SELECTION;
        String[] args = { Long.toString(listId) };
        int token = (int)listId;
        mQueryHandler.startQuery(token, null, Im.Contacts.CONTENT_URI,
                ContactView.CONTACT_PROJECTION, selection, args, Im.Contacts.DEFAULT_SORT_ORDER);
    
voidstartQueryOngoingConversations()

        if (Log.isLoggable(ImApp.LOG_TAG, Log.DEBUG)){
            log("startQueryOngoingConversations()");
        }

        Uri uri = Im.Contacts.CONTENT_URI_CHAT_CONTACTS_BY;
        uri = ContentUris.withAppendedId(uri, mProviderId);
        uri = ContentUris.withAppendedId(uri, mAccountId);

        mQueryHandler.startQuery(TOKEN_ONGOING_CONVERSATION, null, uri,
                ContactView.CONTACT_PROJECTION, null, null, Im.Contacts.DEFAULT_SORT_ORDER);
    
voidstartQuerySubscriptions()

        if (Log.isLoggable(ImApp.LOG_TAG, Log.DEBUG)){
            log("startQuerySubscriptions()");
        }

        Uri uri = Im.Contacts.CONTENT_URI_CONTACTS_BY;
        uri = ContentUris.withAppendedId(uri, mProviderId);
        uri = ContentUris.withAppendedId(uri, mAccountId);

        mQueryHandler.startQuery(TOKEN_SUBSCRITPTION, null, uri,
                ContactView.CONTACT_PROJECTION,
                String.format("%s=%d AND %s=%d",
                    Im.Contacts.SUBSCRIPTION_STATUS, Im.Contacts.SUBSCRIPTION_STATUS_SUBSCRIBE_PENDING,
                    Im.Contacts.SUBSCRIPTION_TYPE, Im.Contacts.SUBSCRIPTION_TYPE_FROM),
                null,Im.Contacts.DEFAULT_SORT_ORDER);
    
public voidunregisterDataSetObserver(android.database.DataSetObserver observer)

        mAdapter.unregisterDataSetObserver(observer);
        super.unregisterDataSetObserver(observer);