ContactListAdapter.java revision 1f1e90d36fe914a7ce51e6f9884199580115d891
1d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng/*
2d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Copyright (C) 2010 The Android Open Source Project
3d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng *
4d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Licensed under the Apache License, Version 2.0 (the "License");
5d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * you may not use this file except in compliance with the License.
6d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * You may obtain a copy of the License at
7d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng *
8d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng *      http://www.apache.org/licenses/LICENSE-2.0
9d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng *
10d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Unless required by applicable law or agreed to in writing, software
11d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * distributed under the License is distributed on an "AS IS" BASIS,
12d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * See the License for the specific language governing permissions and
14d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * limitations under the License.
15d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */
16d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengpackage com.android.contacts.common.list;
17d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
18d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.content.Context;
19d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.database.Cursor;
20d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.net.Uri;
21d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.provider.ContactsContract;
22d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.provider.ContactsContract.ContactCounts;
23d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.provider.ContactsContract.Contacts;
24d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.provider.ContactsContract.Directory;
25d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.provider.ContactsContract.SearchSnippetColumns;
26d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.text.TextUtils;
27d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.view.View;
28d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.view.ViewGroup;
29d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.widget.ListView;
30d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
316084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Leeimport com.android.contacts.common.ContactPhotoManager;
326084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Leeimport com.android.contacts.common.ContactPhotoManager.DefaultImageRequest;
33d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport com.android.contacts.common.R;
34d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
35d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng/**
36d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * A cursor adapter for the {@link ContactsContract.Contacts#CONTENT_TYPE} content type.
37d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Also includes support for including the {@link ContactsContract.Profile} record in the
38d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * list.
39d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */
40d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengpublic abstract class ContactListAdapter extends ContactEntryListAdapter {
41d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
42d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    protected static class ContactQuery {
43d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        private static final String[] CONTACT_PROJECTION_PRIMARY = new String[] {
44d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts._ID,                           // 0
45d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.DISPLAY_NAME_PRIMARY,          // 1
46d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.CONTACT_PRESENCE,              // 2
47d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.CONTACT_STATUS,                // 3
48d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.PHOTO_ID,                      // 4
49d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.PHOTO_THUMBNAIL_URI,           // 5
50d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.LOOKUP_KEY,                    // 6
51d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.IS_USER_PROFILE,               // 7
52d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        };
53d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
54d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        private static final String[] CONTACT_PROJECTION_ALTERNATIVE = new String[] {
55d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts._ID,                           // 0
56d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.DISPLAY_NAME_ALTERNATIVE,      // 1
57d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.CONTACT_PRESENCE,              // 2
58d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.CONTACT_STATUS,                // 3
59d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.PHOTO_ID,                      // 4
60d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.PHOTO_THUMBNAIL_URI,           // 5
61d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.LOOKUP_KEY,                    // 6
62d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.IS_USER_PROFILE,               // 7
63d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        };
64d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
65d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        private static final String[] FILTER_PROJECTION_PRIMARY = new String[] {
66d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts._ID,                           // 0
67d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.DISPLAY_NAME_PRIMARY,          // 1
68d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.CONTACT_PRESENCE,              // 2
69d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.CONTACT_STATUS,                // 3
70d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.PHOTO_ID,                      // 4
71d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.PHOTO_THUMBNAIL_URI,           // 5
72d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.LOOKUP_KEY,                    // 6
73d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.IS_USER_PROFILE,               // 7
74d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            SearchSnippetColumns.SNIPPET,           // 8
75d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        };
76d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
77d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        private static final String[] FILTER_PROJECTION_ALTERNATIVE = new String[] {
78d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts._ID,                           // 0
79d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.DISPLAY_NAME_ALTERNATIVE,      // 1
80d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.CONTACT_PRESENCE,              // 2
81d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.CONTACT_STATUS,                // 3
82d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.PHOTO_ID,                      // 4
83d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.PHOTO_THUMBNAIL_URI,           // 5
84d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.LOOKUP_KEY,                    // 6
85d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Contacts.IS_USER_PROFILE,               // 7
86d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            SearchSnippetColumns.SNIPPET,           // 8
87d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        };
88d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
89d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        public static final int CONTACT_ID               = 0;
90d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        public static final int CONTACT_DISPLAY_NAME     = 1;
91d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        public static final int CONTACT_PRESENCE_STATUS  = 2;
92d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        public static final int CONTACT_CONTACT_STATUS   = 3;
93d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        public static final int CONTACT_PHOTO_ID         = 4;
94d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        public static final int CONTACT_PHOTO_URI        = 5;
95d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        public static final int CONTACT_LOOKUP_KEY       = 6;
96d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        public static final int CONTACT_IS_USER_PROFILE  = 7;
97d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        public static final int CONTACT_SNIPPET          = 8;
98d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
99d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
100d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    private CharSequence mUnknownNameText;
101d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
102d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    private long mSelectedContactDirectoryId;
103d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    private String mSelectedContactLookupKey;
104d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    private long mSelectedContactId;
105e1d3c390975751ec0eec838685de90b3938e7978Paul Sliwowski    private ContactListItemView.PhotoPosition mPhotoPosition;
106d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
107d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    public ContactListAdapter(Context context) {
108d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        super(context);
109d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
110d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        mUnknownNameText = context.getText(R.string.missing_name);
111d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
112d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
113e1d3c390975751ec0eec838685de90b3938e7978Paul Sliwowski    public void setPhotoPosition(ContactListItemView.PhotoPosition photoPosition) {
114e1d3c390975751ec0eec838685de90b3938e7978Paul Sliwowski        mPhotoPosition = photoPosition;
115e1d3c390975751ec0eec838685de90b3938e7978Paul Sliwowski    }
116e1d3c390975751ec0eec838685de90b3938e7978Paul Sliwowski
117e1d3c390975751ec0eec838685de90b3938e7978Paul Sliwowski    public ContactListItemView.PhotoPosition getPhotoPosition() {
118e1d3c390975751ec0eec838685de90b3938e7978Paul Sliwowski        return mPhotoPosition;
119e1d3c390975751ec0eec838685de90b3938e7978Paul Sliwowski    }
120e1d3c390975751ec0eec838685de90b3938e7978Paul Sliwowski
121d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    public CharSequence getUnknownNameText() {
122d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        return mUnknownNameText;
123d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
124d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
125d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    public long getSelectedContactDirectoryId() {
126d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        return mSelectedContactDirectoryId;
127d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
128d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
129d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    public String getSelectedContactLookupKey() {
130d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        return mSelectedContactLookupKey;
131d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
132d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
133d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    public long getSelectedContactId() {
134d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        return mSelectedContactId;
135d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
136d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
137d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    public void setSelectedContact(long selectedDirectoryId, String lookupKey, long contactId) {
138d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        mSelectedContactDirectoryId = selectedDirectoryId;
139d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        mSelectedContactLookupKey = lookupKey;
140d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        mSelectedContactId = contactId;
141d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
142d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
143d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    protected static Uri buildSectionIndexerUri(Uri uri) {
144d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        return uri.buildUpon()
145d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                .appendQueryParameter(ContactCounts.ADDRESS_BOOK_INDEX_EXTRAS, "true").build();
146d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
147d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
148d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    @Override
149d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    public String getContactDisplayName(int position) {
150d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        return ((Cursor) getItem(position)).getString(ContactQuery.CONTACT_DISPLAY_NAME);
151d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
152d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
153d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    /**
154d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng     * Builds the {@link Contacts#CONTENT_LOOKUP_URI} for the given
155d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng     * {@link ListView} position.
156d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng     */
157d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    public Uri getContactUri(int position) {
158d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        int partitionIndex = getPartitionForPosition(position);
159d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        Cursor item = (Cursor)getItem(position);
160d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        return item != null ? getContactUri(partitionIndex, item) : null;
161d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
162d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
163d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    public Uri getContactUri(int partitionIndex, Cursor cursor) {
164d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        long contactId = cursor.getLong(ContactQuery.CONTACT_ID);
165d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        String lookupKey = cursor.getString(ContactQuery.CONTACT_LOOKUP_KEY);
166d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        Uri uri = Contacts.getLookupUri(contactId, lookupKey);
167d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        long directoryId = ((DirectoryPartition)getPartition(partitionIndex)).getDirectoryId();
168d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        if (directoryId != Directory.DEFAULT) {
169d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            uri = uri.buildUpon().appendQueryParameter(
170d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                    ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(directoryId)).build();
171d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        }
172d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        return uri;
173d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
174d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
175d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    /**
176d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng     * Returns true if the specified contact is selected in the list. For a
177d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng     * contact to be shown as selected, we need both the directory and and the
178d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng     * lookup key to be the same. We are paying no attention to the contactId,
179d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng     * because it is volatile, especially in the case of directories.
180d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng     */
181d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    public boolean isSelectedContact(int partitionIndex, Cursor cursor) {
182d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        long directoryId = ((DirectoryPartition)getPartition(partitionIndex)).getDirectoryId();
183d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        if (getSelectedContactDirectoryId() != directoryId) {
184d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            return false;
185d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        }
186d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        String lookupKey = getSelectedContactLookupKey();
187d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        if (lookupKey != null && TextUtils.equals(lookupKey,
188d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                cursor.getString(ContactQuery.CONTACT_LOOKUP_KEY))) {
189d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            return true;
190d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        }
191d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
192d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        return directoryId != Directory.DEFAULT && directoryId != Directory.LOCAL_INVISIBLE
193d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                && getSelectedContactId() == cursor.getLong(ContactQuery.CONTACT_ID);
194d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
195d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
196d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    @Override
1971f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee    protected ContactListItemView newView(
1981f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee            Context context, int partition, Cursor cursor, int position, ViewGroup parent) {
1991f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee        ContactListItemView view = super.newView(context, partition, cursor, position, parent);
200d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        view.setUnknownNameText(mUnknownNameText);
201d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        view.setQuickContactEnabled(isQuickContactEnabled());
202d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        view.setActivatedStateSupported(isSelectionVisible());
203e1d3c390975751ec0eec838685de90b3938e7978Paul Sliwowski        if (mPhotoPosition != null) {
204e1d3c390975751ec0eec838685de90b3938e7978Paul Sliwowski            view.setPhotoPosition(mPhotoPosition);
205e1d3c390975751ec0eec838685de90b3938e7978Paul Sliwowski        }
206d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        return view;
207d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
208d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
209d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    protected void bindSectionHeaderAndDivider(ContactListItemView view, int position,
210d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Cursor cursor) {
211d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        if (isSectionHeaderDisplayEnabled()) {
212d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Placement placement = getItemPlacementInSection(position);
213d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            view.setSectionHeader(placement.sectionHeader);
214d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        } else {
215d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            view.setSectionHeader(null);
216d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        }
217d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
218d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
219d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    protected void bindPhoto(final ContactListItemView view, int partitionIndex, Cursor cursor) {
220d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        if (!isPhotoSupported(partitionIndex)) {
221d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            view.removePhotoView();
222d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            return;
223d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        }
224d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
225d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        // Set the photo, if available
226d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        long photoId = 0;
227d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        if (!cursor.isNull(ContactQuery.CONTACT_PHOTO_ID)) {
228d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            photoId = cursor.getLong(ContactQuery.CONTACT_PHOTO_ID);
229d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        }
230d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
231d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        if (photoId != 0) {
2326084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee            getPhotoLoader().loadThumbnail(view.getPhotoView(), photoId, false, null);
233d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        } else {
234d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            final String photoUriString = cursor.getString(ContactQuery.CONTACT_PHOTO_URI);
235d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            final Uri photoUri = photoUriString == null ? null : Uri.parse(photoUriString);
2366084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee            DefaultImageRequest request = null;
2376084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee            if (photoUri == null) {
2386084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee                String displayName = cursor.getString(ContactQuery.CONTACT_DISPLAY_NAME);
2396084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee                String lookupKey = cursor.getString(ContactQuery.CONTACT_LOOKUP_KEY);
2406084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee                request = new DefaultImageRequest(displayName, lookupKey);
2416084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee            }
2426084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee            getPhotoLoader().loadDirectoryPhoto(view.getPhotoView(), photoUri, false, request);
243d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        }
244d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
245d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
246d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    protected void bindName(final ContactListItemView view, Cursor cursor) {
247d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        view.showDisplayName(
248d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                cursor, ContactQuery.CONTACT_DISPLAY_NAME, getContactNameDisplayOrder());
249d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        // Note: we don't show phonetic any more (See issue 5265330)
250d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
251d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
252d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    protected void bindPresenceAndStatusMessage(final ContactListItemView view, Cursor cursor) {
253d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        view.showPresenceAndStatusMessage(cursor, ContactQuery.CONTACT_PRESENCE_STATUS,
254d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                ContactQuery.CONTACT_CONTACT_STATUS);
255d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
256d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
257d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    protected void bindSearchSnippet(final ContactListItemView view, Cursor cursor) {
258d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        view.showSnippet(cursor, ContactQuery.CONTACT_SNIPPET);
259d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
260d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
261d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    public int getSelectedContactPosition() {
262d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        if (mSelectedContactLookupKey == null && mSelectedContactId == 0) {
263d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            return -1;
264d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        }
265d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
266d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        Cursor cursor = null;
267d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        int partitionIndex = -1;
268d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        int partitionCount = getPartitionCount();
269d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        for (int i = 0; i < partitionCount; i++) {
270d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            DirectoryPartition partition = (DirectoryPartition) getPartition(i);
271d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            if (partition.getDirectoryId() == mSelectedContactDirectoryId) {
272d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                partitionIndex = i;
273d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                break;
274d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            }
275d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        }
276d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        if (partitionIndex == -1) {
277d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            return -1;
278d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        }
279d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
280d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        cursor = getCursor(partitionIndex);
281d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        if (cursor == null) {
282d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            return -1;
283d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        }
284d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
285d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        cursor.moveToPosition(-1);      // Reset cursor
286d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        int offset = -1;
287d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        while (cursor.moveToNext()) {
288d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            if (mSelectedContactLookupKey != null) {
289d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                String lookupKey = cursor.getString(ContactQuery.CONTACT_LOOKUP_KEY);
290d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                if (mSelectedContactLookupKey.equals(lookupKey)) {
291d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                    offset = cursor.getPosition();
292d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                    break;
293d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                }
294d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            }
295d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            if (mSelectedContactId != 0 && (mSelectedContactDirectoryId == Directory.DEFAULT
296d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                    || mSelectedContactDirectoryId == Directory.LOCAL_INVISIBLE)) {
297d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                long contactId = cursor.getLong(ContactQuery.CONTACT_ID);
298d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                if (contactId == mSelectedContactId) {
299d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                    offset = cursor.getPosition();
300d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                    break;
301d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                }
302d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            }
303d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        }
304d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        if (offset == -1) {
305d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            return -1;
306d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        }
307d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
308d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        int position = getPositionForPartition(partitionIndex) + offset;
309d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        if (hasHeader(partitionIndex)) {
310d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            position++;
311d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        }
312d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        return position;
313d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
314d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
315d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    public boolean hasValidSelection() {
316d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        return getSelectedContactPosition() != -1;
317d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
318d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
319d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    public Uri getFirstContactUri() {
320d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        int partitionCount = getPartitionCount();
321d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        for (int i = 0; i < partitionCount; i++) {
322d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            DirectoryPartition partition = (DirectoryPartition) getPartition(i);
323d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            if (partition.isLoading()) {
324d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                continue;
325d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            }
326d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
327d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Cursor cursor = getCursor(i);
328d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            if (cursor == null) {
329d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                continue;
330d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            }
331d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
332d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            if (!cursor.moveToFirst()) {
333d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                continue;
334d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            }
335d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
336d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            return getContactUri(i, cursor);
337d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        }
338d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
339d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        return null;
340d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
341d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
342d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    @Override
343d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    public void changeCursor(int partitionIndex, Cursor cursor) {
344d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        super.changeCursor(partitionIndex, cursor);
345d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
346d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        // Check if a profile exists
347d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        if (cursor != null && cursor.getCount() > 0) {
348d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            cursor.moveToFirst();
349d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            setProfileExists(cursor.getInt(ContactQuery.CONTACT_IS_USER_PROFILE) == 1);
350d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        }
351d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
352d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
353d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    /**
354d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng     * @return Projection useful for children.
355d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng     */
356d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    protected final String[] getProjection(boolean forSearch) {
357d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        final int sortOrder = getContactNameDisplayOrder();
358d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        if (forSearch) {
359d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            if (sortOrder == ContactsContract.Preferences.DISPLAY_ORDER_PRIMARY) {
360d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                return ContactQuery.FILTER_PROJECTION_PRIMARY;
361d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            } else {
362d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                return ContactQuery.FILTER_PROJECTION_ALTERNATIVE;
363d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            }
364d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        } else {
365d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            if (sortOrder == ContactsContract.Preferences.DISPLAY_ORDER_PRIMARY) {
366d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                return ContactQuery.CONTACT_PROJECTION_PRIMARY;
367d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            } else {
368d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                return ContactQuery.CONTACT_PROJECTION_ALTERNATIVE;
369d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            }
370d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        }
371d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
372d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng}
373