163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng/*
263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng * Copyright (C) 2011 The Android Open Source Project
363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng *
463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng * Licensed under the Apache License, Version 2.0 (the "License");
563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng * you may not use this file except in compliance with the License.
663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng * You may obtain a copy of the License at
763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng *
863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng *      http://www.apache.org/licenses/LICENSE-2.0
963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng *
1063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng * Unless required by applicable law or agreed to in writing, software
1163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng * distributed under the License is distributed on an "AS IS" BASIS,
1263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng * See the License for the specific language governing permissions and
1463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng * limitations under the License.
1563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng */
1663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengpackage com.android.contacts.common.list;
1763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
1863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport android.content.ContentUris;
1963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport android.content.Context;
2063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport android.content.res.Resources;
2163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport android.database.Cursor;
2263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport android.graphics.drawable.Drawable;
2363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport android.net.Uri;
2463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport android.provider.ContactsContract.Contacts;
2563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport android.view.View;
2663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport android.view.ViewGroup;
2763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport android.widget.BaseAdapter;
2863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport android.widget.FrameLayout;
293c4e8501b8fe4a6f508a256fd133004e1f1936a4Brian Attwellimport android.widget.TextView;
3063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
3163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport com.android.contacts.common.ContactPhotoManager;
3263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport com.android.contacts.common.ContactPresenceIconUtil;
3363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport com.android.contacts.common.ContactStatusUtil;
3463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport com.android.contacts.common.ContactTileLoaderFactory;
3563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport com.android.contacts.common.MoreContactUtils;
3663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport com.android.contacts.common.R;
3776e0b32755662d2b2a33965629e7baa6bf3964bdBrian Attwellimport com.android.contacts.common.util.ViewUtil;
3863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
3963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport java.util.ArrayList;
4063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
4163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng/**
4263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng * Arranges contacts favorites according to provided {@link DisplayType}.
4363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng * Also allows for a configurable number of columns and {@link DisplayType}
4463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng */
4563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengpublic class ContactTileAdapter extends BaseAdapter {
4663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    private static final String TAG = ContactTileAdapter.class.getSimpleName();
4763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
4863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    private DisplayType mDisplayType;
4963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    private ContactTileView.Listener mListener;
5063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    private Context mContext;
5163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    private Resources mResources;
5263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    protected Cursor mContactCursor = null;
5363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    private ContactPhotoManager mPhotoManager;
5463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    protected int mNumFrequents;
5563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
5663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    /**
5763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     * Index of the first NON starred contact in the {@link Cursor}
5863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     * Only valid when {@link DisplayType#STREQUENT} is true
5963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     */
6063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    private int mDividerPosition;
6163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    protected int mColumnCount;
6263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    private int mStarredIndex;
6363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
6463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    protected int mIdIndex;
6563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    protected int mLookupIndex;
6663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    protected int mPhotoUriIndex;
6763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    protected int mNameIndex;
6863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    protected int mPresenceIndex;
6963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    protected int mStatusIndex;
7063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
7163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    private boolean mIsQuickContactEnabled = false;
7263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    private final int mPaddingInPixels;
73fcf62ed127081833443eb13eb9e17aaf158f441aBrian Attwell    private final int mWhitespaceStartEnd;
7463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
7563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    /**
7663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     * Configures the adapter to filter and display contacts using different view types.
7763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     * TODO: Create Uris to support getting Starred_only and Frequent_only cursors.
7863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     */
7963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    public enum DisplayType {
8063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        /**
8163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng         * Displays a mixed view type of starred and frequent contacts
8263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng         */
8363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        STREQUENT,
8463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
8563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        /**
8663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng         * Display only starred contacts
8763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng         */
8863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        STARRED_ONLY,
8963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
9063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        /**
9163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng         * Display only most frequently contacted
9263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng         */
9363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        FREQUENT_ONLY,
9463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
9563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        /**
9663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng         * Display all contacts from a group in the cursor
9763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng         * Use {@link com.android.contacts.GroupMemberLoader}
9863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng         * when passing {@link Cursor} into loadFromCusor method.
9963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng         *
10063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng         * Group member logic has been moved into GroupMemberTileAdapter.  This constant is still
10163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng         * needed by calling classes.
10263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng         */
10363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        GROUP_MEMBERS
10463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    }
10563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
10663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    public ContactTileAdapter(Context context, ContactTileView.Listener listener, int numCols,
10763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            DisplayType displayType) {
10863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        mListener = listener;
10963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        mContext = context;
11063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        mResources = context.getResources();
11163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        mColumnCount = (displayType == DisplayType.FREQUENT_ONLY ? 1 : numCols);
11263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        mDisplayType = displayType;
11363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        mNumFrequents = 0;
11463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
11563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        // Converting padding in dips to padding in pixels
11663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        mPaddingInPixels = mContext.getResources()
11763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                .getDimensionPixelSize(R.dimen.contact_tile_divider_padding);
118fcf62ed127081833443eb13eb9e17aaf158f441aBrian Attwell        mWhitespaceStartEnd = mContext.getResources()
119fcf62ed127081833443eb13eb9e17aaf158f441aBrian Attwell                .getDimensionPixelSize(R.dimen.contact_tile_start_end_whitespace);
12063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
12163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        bindColumnIndices();
12263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    }
12363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
12463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    public void setPhotoLoader(ContactPhotoManager photoLoader) {
12563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        mPhotoManager = photoLoader;
12663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    }
12763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
12863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    public void setColumnCount(int columnCount) {
12963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        mColumnCount = columnCount;
13063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    }
13163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
13263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    public void setDisplayType(DisplayType displayType) {
13363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        mDisplayType = displayType;
13463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    }
13563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
13663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    public void enableQuickContact(boolean enableQuickContact) {
13763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        mIsQuickContactEnabled = enableQuickContact;
13863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    }
13963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
14063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    /**
14163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     * Sets the column indices for expected {@link Cursor}
14263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     * based on {@link DisplayType}.
14363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     */
14463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    protected void bindColumnIndices() {
14563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        mIdIndex = ContactTileLoaderFactory.CONTACT_ID;
14663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        mLookupIndex = ContactTileLoaderFactory.LOOKUP_KEY;
14763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        mPhotoUriIndex = ContactTileLoaderFactory.PHOTO_URI;
14863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        mNameIndex = ContactTileLoaderFactory.DISPLAY_NAME;
14963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        mStarredIndex = ContactTileLoaderFactory.STARRED;
15063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        mPresenceIndex = ContactTileLoaderFactory.CONTACT_PRESENCE;
15163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        mStatusIndex = ContactTileLoaderFactory.CONTACT_STATUS;
15263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    }
15363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
15415a8f475646c8338be244f65771e560e4875acddJay Shrauner    private static boolean cursorIsValid(Cursor cursor) {
15515a8f475646c8338be244f65771e560e4875acddJay Shrauner        return cursor != null && !cursor.isClosed();
15615a8f475646c8338be244f65771e560e4875acddJay Shrauner    }
15715a8f475646c8338be244f65771e560e4875acddJay Shrauner
15863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    /**
15963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     * Gets the number of frequents from the passed in cursor.
16063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     *
16163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     * This methods is needed so the GroupMemberTileAdapter can override this.
16263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     *
16363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     * @param cursor The cursor to get number of frequents from.
16463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     */
16563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    protected void saveNumFrequentsFromCursor(Cursor cursor) {
16663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
16763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        // count the number of frequents
16863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        switch (mDisplayType) {
16963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            case STARRED_ONLY:
17063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                mNumFrequents = 0;
17163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                break;
17263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            case STREQUENT:
17315a8f475646c8338be244f65771e560e4875acddJay Shrauner                mNumFrequents = cursorIsValid(cursor) ?
17415a8f475646c8338be244f65771e560e4875acddJay Shrauner                    cursor.getCount() - mDividerPosition : 0;
17563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                break;
17663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            case FREQUENT_ONLY:
17715a8f475646c8338be244f65771e560e4875acddJay Shrauner                mNumFrequents = cursorIsValid(cursor) ? cursor.getCount() : 0;
17863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                break;
17963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            default:
18063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                throw new IllegalArgumentException("Unrecognized DisplayType " + mDisplayType);
18163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        }
18263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    }
18363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
18463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    /**
18563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     * Creates {@link ContactTileView}s for each item in {@link Cursor}.
18663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     *
18763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     * Else use {@link ContactTileLoaderFactory}
18863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     */
18963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    public void setContactCursor(Cursor cursor) {
19063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        mContactCursor = cursor;
19163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        mDividerPosition = getDividerPosition(cursor);
19263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
19363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        saveNumFrequentsFromCursor(cursor);
19463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
19563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        // cause a refresh of any views that rely on this data
19663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        notifyDataSetChanged();
19763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    }
19863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
19963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    /**
20063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     * Iterates over the {@link Cursor}
20163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     * Returns position of the first NON Starred Contact
20263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     * Returns -1 if {@link DisplayType#STARRED_ONLY}
20363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     * Returns 0 if {@link DisplayType#FREQUENT_ONLY}
20463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     */
20563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    protected int getDividerPosition(Cursor cursor) {
20663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        switch (mDisplayType) {
20763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            case STREQUENT:
20815a8f475646c8338be244f65771e560e4875acddJay Shrauner                if (!cursorIsValid(cursor)) {
20915a8f475646c8338be244f65771e560e4875acddJay Shrauner                    return 0;
21015a8f475646c8338be244f65771e560e4875acddJay Shrauner                }
21163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                cursor.moveToPosition(-1);
21263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                while (cursor.moveToNext()) {
21363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                    if (cursor.getInt(mStarredIndex) == 0) {
21463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                        return cursor.getPosition();
21563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                    }
21663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                }
21715a8f475646c8338be244f65771e560e4875acddJay Shrauner
21815a8f475646c8338be244f65771e560e4875acddJay Shrauner                // There are not NON Starred contacts in cursor
21915a8f475646c8338be244f65771e560e4875acddJay Shrauner                // Set divider positon to end
22015a8f475646c8338be244f65771e560e4875acddJay Shrauner                return cursor.getCount();
22163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            case STARRED_ONLY:
22263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                // There is no divider
22363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                return -1;
22463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            case FREQUENT_ONLY:
22563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                // Divider is first
22663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                return 0;
22763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            default:
22863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                throw new IllegalStateException("Unrecognized DisplayType " + mDisplayType);
22963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        }
23063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    }
23163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
23263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    protected ContactEntry createContactEntryFromCursor(Cursor cursor, int position) {
23363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        // If the loader was canceled we will be given a null cursor.
23463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        // In that case, show an empty list of contacts.
23515a8f475646c8338be244f65771e560e4875acddJay Shrauner        if (!cursorIsValid(cursor) || cursor.getCount() <= position) {
23615a8f475646c8338be244f65771e560e4875acddJay Shrauner            return null;
23715a8f475646c8338be244f65771e560e4875acddJay Shrauner        }
23863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
23963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        cursor.moveToPosition(position);
24063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        long id = cursor.getLong(mIdIndex);
24163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        String photoUri = cursor.getString(mPhotoUriIndex);
24263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        String lookupKey = cursor.getString(mLookupIndex);
24363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
24463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        ContactEntry contact = new ContactEntry();
24563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        String name = cursor.getString(mNameIndex);
246d5b66d89be3117a04cf54ccdb02d704b1d934351Brandon Maxwell        contact.namePrimary = (name != null) ? name : mResources.getString(R.string.missing_name);
24763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        contact.status = cursor.getString(mStatusIndex);
24863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        contact.photoUri = (photoUri != null ? Uri.parse(photoUri) : null);
2496084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee        contact.lookupKey = lookupKey;
2506084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee        contact.lookupUri = ContentUris.withAppendedId(
25163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey), id);
2527c1a3efb470d5dcd978f5a1b494687bedc29fa10Christine Chen        contact.isFavorite = cursor.getInt(mStarredIndex) > 0;
25363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
2542a913bd7024f2ccd0e2649c49d1442e9167f9039Brian Attwell        // Set presence icon and status message
2552a913bd7024f2ccd0e2649c49d1442e9167f9039Brian Attwell        Drawable icon = null;
2562a913bd7024f2ccd0e2649c49d1442e9167f9039Brian Attwell        int presence = 0;
2572a913bd7024f2ccd0e2649c49d1442e9167f9039Brian Attwell        if (!cursor.isNull(mPresenceIndex)) {
2582a913bd7024f2ccd0e2649c49d1442e9167f9039Brian Attwell            presence = cursor.getInt(mPresenceIndex);
2592a913bd7024f2ccd0e2649c49d1442e9167f9039Brian Attwell            icon = ContactPresenceIconUtil.getPresenceIcon(mContext, presence);
2602a913bd7024f2ccd0e2649c49d1442e9167f9039Brian Attwell        }
2612a913bd7024f2ccd0e2649c49d1442e9167f9039Brian Attwell        contact.presenceIcon = icon;
26263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
2632a913bd7024f2ccd0e2649c49d1442e9167f9039Brian Attwell        String statusMessage = null;
2642a913bd7024f2ccd0e2649c49d1442e9167f9039Brian Attwell        if (mStatusIndex != 0 && !cursor.isNull(mStatusIndex)) {
2652a913bd7024f2ccd0e2649c49d1442e9167f9039Brian Attwell            statusMessage = cursor.getString(mStatusIndex);
26663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        }
2672a913bd7024f2ccd0e2649c49d1442e9167f9039Brian Attwell        // If there is no status message from the contact, but there was a presence value,
2682a913bd7024f2ccd0e2649c49d1442e9167f9039Brian Attwell        // then use the default status message string
2692a913bd7024f2ccd0e2649c49d1442e9167f9039Brian Attwell        if (statusMessage == null && presence != 0) {
2702a913bd7024f2ccd0e2649c49d1442e9167f9039Brian Attwell            statusMessage = ContactStatusUtil.getStatusString(mContext, presence);
2712a913bd7024f2ccd0e2649c49d1442e9167f9039Brian Attwell        }
2722a913bd7024f2ccd0e2649c49d1442e9167f9039Brian Attwell        contact.status = statusMessage;
27363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
27463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        return contact;
27563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    }
27663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
27763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    /**
27863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     * Returns the number of frequents that will be displayed in the list.
27963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     */
28063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    public int getNumFrequents() {
28163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        return mNumFrequents;
28263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    }
28363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
28463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    @Override
28563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    public int getCount() {
28615a8f475646c8338be244f65771e560e4875acddJay Shrauner        if (!cursorIsValid(mContactCursor)) {
28763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            return 0;
28863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        }
28963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
29063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        switch (mDisplayType) {
29163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            case STARRED_ONLY:
29263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                return getRowCount(mContactCursor.getCount());
29363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            case STREQUENT:
29463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                // Takes numbers of rows the Starred Contacts Occupy
29563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                int starredRowCount = getRowCount(mDividerPosition);
29663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
29763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                // Compute the frequent row count which is 1 plus the number of frequents
29863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                // (to account for the divider) or 0 if there are no frequents.
29963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                int frequentRowCount = mNumFrequents == 0 ? 0 : mNumFrequents + 1;
30063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
30163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                // Return the number of starred plus frequent rows
30263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                return starredRowCount + frequentRowCount;
30363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            case FREQUENT_ONLY:
30463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                // Number of frequent contacts
30563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                return mContactCursor.getCount();
30663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            default:
30763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                throw new IllegalArgumentException("Unrecognized DisplayType " + mDisplayType);
30863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        }
30963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    }
31063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
31163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    /**
31263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     * Returns the number of rows required to show the provided number of entries
31363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     * with the current number of columns.
31463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     */
31563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    protected int getRowCount(int entryCount) {
31663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        return entryCount == 0 ? 0 : ((entryCount - 1) / mColumnCount) + 1;
31763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    }
31863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
31963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    public int getColumnCount() {
32063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        return mColumnCount;
32163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    }
32263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
32363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    /**
32463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     * Returns an ArrayList of the {@link ContactEntry}s that are to appear
32563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     * on the row for the given position.
32663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     */
32763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    @Override
32863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    public ArrayList<ContactEntry> getItem(int position) {
32963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        ArrayList<ContactEntry> resultList = new ArrayList<ContactEntry>(mColumnCount);
33063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        int contactIndex = position * mColumnCount;
33163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
33263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        switch (mDisplayType) {
33363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            case FREQUENT_ONLY:
33463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                resultList.add(createContactEntryFromCursor(mContactCursor, position));
33563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                break;
33663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            case STARRED_ONLY:
33763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                for (int columnCounter = 0; columnCounter < mColumnCount; columnCounter++) {
33863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                    resultList.add(createContactEntryFromCursor(mContactCursor, contactIndex));
33963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                    contactIndex++;
34063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                }
34163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                break;
34263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            case STREQUENT:
34363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                if (position < getRowCount(mDividerPosition)) {
34463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                    for (int columnCounter = 0; columnCounter < mColumnCount &&
34563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                            contactIndex != mDividerPosition; columnCounter++) {
34663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                        resultList.add(createContactEntryFromCursor(mContactCursor, contactIndex));
34763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                        contactIndex++;
34863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                    }
34963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                } else {
35063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                    /*
35163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                     * Current position minus how many rows are before the divider and
35263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                     * Minus 1 for the divider itself provides the relative index of the frequent
35363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                     * contact being displayed. Then add the dividerPostion to give the offset
35463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                     * into the contacts cursor to get the absoulte index.
35563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                     */
35663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                    contactIndex = position - getRowCount(mDividerPosition) - 1 + mDividerPosition;
35763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                    resultList.add(createContactEntryFromCursor(mContactCursor, contactIndex));
35863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                }
35963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                break;
36063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            default:
36163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                throw new IllegalStateException("Unrecognized DisplayType " + mDisplayType);
36263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        }
36363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        return resultList;
36463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    }
36563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
36663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    @Override
36763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    public long getItemId(int position) {
36863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        // As we show several selectable items for each ListView row,
36963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        // we can not determine a stable id. But as we don't rely on ListView's selection,
37063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        // this should not be a problem.
37163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        return position;
37263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    }
37363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
37463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    @Override
37563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    public boolean areAllItemsEnabled() {
3762a913bd7024f2ccd0e2649c49d1442e9167f9039Brian Attwell        return (mDisplayType != DisplayType.STREQUENT);
37763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    }
37863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
37963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    @Override
38063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    public boolean isEnabled(int position) {
38163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        return position != getRowCount(mDividerPosition);
38263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    }
38363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
38463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    @Override
38563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    public View getView(int position, View convertView, ViewGroup parent) {
38663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        int itemViewType = getItemViewType(position);
38763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
38863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        if (itemViewType == ViewTypes.DIVIDER) {
38963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            // Checking For Divider First so not to cast convertView
3903c4e8501b8fe4a6f508a256fd133004e1f1936a4Brian Attwell            final TextView textView = (TextView) (convertView == null ? getDivider() : convertView);
3913c4e8501b8fe4a6f508a256fd133004e1f1936a4Brian Attwell            setDividerPadding(textView, position == 0);
3923c4e8501b8fe4a6f508a256fd133004e1f1936a4Brian Attwell            return textView;
39363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        }
39463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
39563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        ContactTileRow contactTileRowView = (ContactTileRow) convertView;
39663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        ArrayList<ContactEntry> contactList = getItem(position);
39763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
39863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        if (contactTileRowView == null) {
39963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            // Creating new row if needed
40063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            contactTileRowView = new ContactTileRow(mContext, itemViewType);
40163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        }
40263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
40363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        contactTileRowView.configureRow(contactList, position == getCount() - 1);
40463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        return contactTileRowView;
40563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    }
40663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
40763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    /**
40863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     * Divider uses a list_seperator.xml along with text to denote
40963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     * the most frequently contacted contacts.
41063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     */
4113c4e8501b8fe4a6f508a256fd133004e1f1936a4Brian Attwell    private TextView getDivider() {
4122a913bd7024f2ccd0e2649c49d1442e9167f9039Brian Attwell        return MoreContactUtils.createHeaderView(mContext, R.string.favoritesFrequentContacted);
41363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    }
41463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
4153c4e8501b8fe4a6f508a256fd133004e1f1936a4Brian Attwell    private void setDividerPadding(TextView headerTextView, boolean isFirstRow) {
4163c4e8501b8fe4a6f508a256fd133004e1f1936a4Brian Attwell        MoreContactUtils.setHeaderViewBottomPadding(mContext, headerTextView, isFirstRow);
4173c4e8501b8fe4a6f508a256fd133004e1f1936a4Brian Attwell    }
4183c4e8501b8fe4a6f508a256fd133004e1f1936a4Brian Attwell
41963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    private int getLayoutResourceId(int viewType) {
42063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        switch (viewType) {
42163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            case ViewTypes.STARRED:
42263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                return mIsQuickContactEnabled ?
42363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                        R.layout.contact_tile_starred_quick_contact : R.layout.contact_tile_starred;
42463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            case ViewTypes.FREQUENT:
4252a913bd7024f2ccd0e2649c49d1442e9167f9039Brian Attwell                return R.layout.contact_tile_frequent;
42663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            default:
42763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                throw new IllegalArgumentException("Unrecognized viewType " + viewType);
42863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        }
42963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    }
43063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    @Override
43163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    public int getViewTypeCount() {
43263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        return ViewTypes.COUNT;
43363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    }
43463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
43563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    @Override
43663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    public int getItemViewType(int position) {
43763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        /*
43863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng         * Returns view type based on {@link DisplayType}.
43963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng         * {@link DisplayType#STARRED_ONLY} and {@link DisplayType#GROUP_MEMBERS}
44063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng         * are {@link ViewTypes#STARRED}.
44163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng         * {@link DisplayType#FREQUENT_ONLY} is {@link ViewTypes#FREQUENT}.
44263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng         * {@link DisplayType#STREQUENT} mixes both {@link ViewTypes}
44363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng         * and also adds in {@link ViewTypes#DIVIDER}.
44463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng         */
44563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        switch (mDisplayType) {
44663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            case STREQUENT:
44763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                if (position < getRowCount(mDividerPosition)) {
44863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                    return ViewTypes.STARRED;
44963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                } else if (position == getRowCount(mDividerPosition)) {
45063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                    return ViewTypes.DIVIDER;
45163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                } else {
45263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                    return ViewTypes.FREQUENT;
45363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                }
45463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            case STARRED_ONLY:
45563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                return ViewTypes.STARRED;
45663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            case FREQUENT_ONLY:
45763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                return ViewTypes.FREQUENT;
45863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            default:
45963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                throw new IllegalStateException("Unrecognized DisplayType " + mDisplayType);
46063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        }
46163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    }
46263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
46363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    /**
46463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     * Returns the "frequent header" position. Only available when STREQUENT or
46563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     * STREQUENT_PHONE_ONLY is used for its display type.
46663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     */
46763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    public int getFrequentHeaderPosition() {
46863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        return getRowCount(mDividerPosition);
46963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    }
47063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
47163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    /**
47263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     * Acts as a row item composed of {@link ContactTileView}
47363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     *
47463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     * TODO: FREQUENT doesn't really need it.  Just let {@link #getView} return
47563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     */
47663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    private class ContactTileRow extends FrameLayout {
47763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        private int mItemViewType;
47863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        private int mLayoutResId;
47963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
48063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        public ContactTileRow(Context context, int itemViewType) {
48163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            super(context);
48263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            mItemViewType = itemViewType;
48363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            mLayoutResId = getLayoutResourceId(mItemViewType);
48474caac49e59c78f28639b83b9cce71e802a78406Chiao Cheng
48574caac49e59c78f28639b83b9cce71e802a78406Chiao Cheng            // Remove row (but not children) from accessibility node tree.
48674caac49e59c78f28639b83b9cce71e802a78406Chiao Cheng            setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
48763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        }
48863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
48963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        /**
49063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng         * Configures the row to add {@link ContactEntry}s information to the views
49163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng         */
49263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        public void configureRow(ArrayList<ContactEntry> list, boolean isLastRow) {
49363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            int columnCount = mItemViewType == ViewTypes.FREQUENT ? 1 : mColumnCount;
49463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
49563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            // Adding tiles to row and filling in contact information
49663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            for (int columnCounter = 0; columnCounter < columnCount; columnCounter++) {
49763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                ContactEntry entry =
49863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                        columnCounter < list.size() ? list.get(columnCounter) : null;
49963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                addTileFromEntry(entry, columnCounter, isLastRow);
50063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            }
50163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        }
50263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
50363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        private void addTileFromEntry(ContactEntry entry, int childIndex, boolean isLastRow) {
50463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            final ContactTileView contactTile;
50563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
50663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            if (getChildCount() <= childIndex) {
50763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                contactTile = (ContactTileView) inflate(mContext, mLayoutResId, null);
50863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                // Note: the layoutparam set here is only actually used for FREQUENT.
50963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                // We override onMeasure() for STARRED and we don't care the layout param there.
51063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                Resources resources = mContext.getResources();
51163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
512440a8fb48d25b4281bd4b00ca5070da59129be14Brian Attwell                        ViewGroup.LayoutParams.MATCH_PARENT,
51363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                        ViewGroup.LayoutParams.WRAP_CONTENT);
51463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                params.setMargins(
515fcf62ed127081833443eb13eb9e17aaf158f441aBrian Attwell                        mWhitespaceStartEnd,
51663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                        0,
517fcf62ed127081833443eb13eb9e17aaf158f441aBrian Attwell                        mWhitespaceStartEnd,
51863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                        0);
51963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                contactTile.setLayoutParams(params);
52063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                contactTile.setPhotoManager(mPhotoManager);
52163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                contactTile.setListener(mListener);
52263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                addView(contactTile);
52363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            } else {
52463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                contactTile = (ContactTileView) getChildAt(childIndex);
52563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            }
52663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            contactTile.loadFromContact(entry);
52763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
52863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            switch (mItemViewType) {
52963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                case ViewTypes.STARRED:
530d6371d642f898ad455eb12719adc0a1123009481Brian Attwell                    // Set padding between tiles. Divide mPaddingInPixels between left and right
531d6371d642f898ad455eb12719adc0a1123009481Brian Attwell                    // tiles as evenly as possible.
532d6371d642f898ad455eb12719adc0a1123009481Brian Attwell                    contactTile.setPaddingRelative(
533fcf62ed127081833443eb13eb9e17aaf158f441aBrian Attwell                            (mPaddingInPixels + 1) / 2, 0,
534fcf62ed127081833443eb13eb9e17aaf158f441aBrian Attwell                            mPaddingInPixels
535d6371d642f898ad455eb12719adc0a1123009481Brian Attwell                            / 2, 0);
53663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                    break;
53763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                case ViewTypes.FREQUENT:
53863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                    contactTile.setHorizontalDividerVisibility(
53963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                            isLastRow ? View.GONE : View.VISIBLE);
54063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                    break;
54163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                default:
54263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                    break;
54363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            }
54463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        }
54563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
54663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        @Override
54763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
54863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            switch (mItemViewType) {
54963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                case ViewTypes.STARRED:
55063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                    onLayoutForTiles();
55163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                    return;
55263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                default:
55363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                    super.onLayout(changed, left, top, right, bottom);
55463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                    return;
55563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            }
55663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        }
55763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
55863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        private void onLayoutForTiles() {
55963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            final int count = getChildCount();
56063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
561fcf62ed127081833443eb13eb9e17aaf158f441aBrian Attwell            // Amount of margin needed on the left is based on difference between offset and padding
562fcf62ed127081833443eb13eb9e17aaf158f441aBrian Attwell            int childLeft = mWhitespaceStartEnd - (mPaddingInPixels + 1) / 2;
563fcf62ed127081833443eb13eb9e17aaf158f441aBrian Attwell
56463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            // Just line up children horizontally.
56563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            for (int i = 0; i < count; i++) {
56676e0b32755662d2b2a33965629e7baa6bf3964bdBrian Attwell                final int rtlAdjustedIndex = ViewUtil.isViewLayoutRtl(this) ? count - i - 1 : i;
56746027b7f219f30e1d413639caca990cb9d8aec64Brian Attwell                final View child = getChildAt(rtlAdjustedIndex);
56863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
56963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                // Note MeasuredWidth includes the padding.
57063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                final int childWidth = child.getMeasuredWidth();
57163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                child.layout(childLeft, 0, childLeft + childWidth, child.getMeasuredHeight());
57263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                childLeft += childWidth;
57363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            }
57463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        }
57563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
57663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        @Override
57763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
57863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            switch (mItemViewType) {
57963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                case ViewTypes.STARRED:
58063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                    onMeasureForTiles(widthMeasureSpec);
58163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                    return;
58263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                default:
58363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
58463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                    return;
58563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            }
58663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        }
58763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
58863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        private void onMeasureForTiles(int widthMeasureSpec) {
58963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            final int width = MeasureSpec.getSize(widthMeasureSpec);
59063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
59163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            final int childCount = getChildCount();
59263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            if (childCount == 0) {
59363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                // Just in case...
59463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                setMeasuredDimension(width, 0);
59563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                return;
59663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            }
59763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
59863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            // 1. Calculate image size.
599fcf62ed127081833443eb13eb9e17aaf158f441aBrian Attwell            //      = ([total width] - [total whitespace]) / [child count]
60063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            //
60163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            // 2. Set it to width/height of each children.
60263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            //    If we have a remainder, some tiles will have 1 pixel larger width than its height.
60363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            //
60463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            // 3. Set the dimensions of itself.
60563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            //    Let width = given width.
6066ee0728b5844ae60adb0d27d5f9b54d9720a11a0Brian Attwell            //    Let height = wrap content.
60763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
608fcf62ed127081833443eb13eb9e17aaf158f441aBrian Attwell            final int totalWhitespaceInPixels = (mColumnCount - 1) * mPaddingInPixels
609fcf62ed127081833443eb13eb9e17aaf158f441aBrian Attwell                    + mWhitespaceStartEnd * 2;
61063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
61163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            // Preferred width / height for images (excluding the padding).
61263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            // The actual width may be 1 pixel larger than this if we have a remainder.
613fcf62ed127081833443eb13eb9e17aaf158f441aBrian Attwell            final int imageSize = (width - totalWhitespaceInPixels) / mColumnCount;
614fcf62ed127081833443eb13eb9e17aaf158f441aBrian Attwell            final int remainder = width - (imageSize * mColumnCount) - totalWhitespaceInPixels;
61563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
61663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            for (int i = 0; i < childCount; i++) {
61763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                final View child = getChildAt(i);
6186ee0728b5844ae60adb0d27d5f9b54d9720a11a0Brian Attwell                final int childWidth = imageSize + child.getPaddingRight() + child.getPaddingLeft()
61963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                        // Compensate for the remainder
62063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                        + (i < remainder ? 1 : 0);
6216ee0728b5844ae60adb0d27d5f9b54d9720a11a0Brian Attwell
62263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                child.measure(
62363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                        MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.EXACTLY),
6246ee0728b5844ae60adb0d27d5f9b54d9720a11a0Brian Attwell                        MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)
62563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng                        );
62663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng            }
6276ee0728b5844ae60adb0d27d5f9b54d9720a11a0Brian Attwell            setMeasuredDimension(width, getChildAt(0).getMeasuredHeight());
62863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        }
62963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    }
63063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
63163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    protected static class ViewTypes {
63263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        public static final int COUNT = 4;
63363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        public static final int STARRED = 0;
63463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        public static final int DIVIDER = 1;
63563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        public static final int FREQUENT = 2;
63663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    }
63763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng}
638