1a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Maipackage com.android.contacts.editor;
2a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai
3a172180513fce7670fa1b2093c72966f6a377444Gary Maiimport android.content.AsyncTaskLoader;
4a172180513fce7670fa1b2093c72966f6a377444Gary Maiimport android.content.ContentResolver;
5a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Maiimport android.content.Context;
6a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Maiimport android.database.Cursor;
7a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Maiimport android.net.Uri;
8a172180513fce7670fa1b2093c72966f6a377444Gary Maiimport android.os.Parcel;
9a172180513fce7670fa1b2093c72966f6a377444Gary Maiimport android.os.Parcelable;
10ba10be290e9a1b105743784ab6cc602bbf3078d8Gary Maiimport android.provider.ContactsContract;
11a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Maiimport android.provider.ContactsContract.Contacts;
123a53328fe057610d44f228666c92c3c5ac2d4799Gary Maiimport android.provider.ContactsContract.Data;
133a53328fe057610d44f228666c92c3c5ac2d4799Gary Maiimport android.provider.ContactsContract.Profile;
14a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Maiimport android.provider.ContactsContract.RawContacts;
15a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai
1669c182afb0e6d82a341a28b4317aa703af768906Gary Maiimport com.android.contacts.model.AccountTypeManager;
1769c182afb0e6d82a341a28b4317aa703af768906Gary Maiimport com.android.contacts.model.account.AccountType;
18a172180513fce7670fa1b2093c72966f6a377444Gary Mai
19a172180513fce7670fa1b2093c72966f6a377444Gary Maiimport java.util.ArrayList;
203a53328fe057610d44f228666c92c3c5ac2d4799Gary Maiimport java.util.HashMap;
213a53328fe057610d44f228666c92c3c5ac2d4799Gary Maiimport java.util.Map;
22a172180513fce7670fa1b2093c72966f6a377444Gary Mai
23a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai/**
24a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai * Loader for the pick a raw contact to edit activity. Loads all raw contact metadata for the
25a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai * given Contact {@link Uri}.
26a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai */
27a172180513fce7670fa1b2093c72966f6a377444Gary Maipublic class PickRawContactLoader extends
28a172180513fce7670fa1b2093c72966f6a377444Gary Mai        AsyncTaskLoader<PickRawContactLoader.RawContactsMetadata> {
29a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai    private Uri mContactUri;
30a172180513fce7670fa1b2093c72966f6a377444Gary Mai    private RawContactsMetadata mCachedResult;
31a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai
32a172180513fce7670fa1b2093c72966f6a377444Gary Mai    private static final String[] RAW_CONTACT_PROJECTION = new String[] {
33a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai            RawContacts.ACCOUNT_NAME,
34a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai            RawContacts.ACCOUNT_TYPE,
35a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai            RawContacts.DATA_SET,
36a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai            RawContacts._ID,
37a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai            RawContacts.DISPLAY_NAME_PRIMARY,
38a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai            RawContacts.DISPLAY_NAME_ALTERNATIVE
39a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai    };
40a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai
41a172180513fce7670fa1b2093c72966f6a377444Gary Mai    private static final String RAW_CONTACT_SELECTION = RawContacts.CONTACT_ID + "=?";
42a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai
43a172180513fce7670fa1b2093c72966f6a377444Gary Mai    private static final int ACCOUNT_NAME = 0;
44a172180513fce7670fa1b2093c72966f6a377444Gary Mai    private static final int ACCOUNT_TYPE = 1;
45a172180513fce7670fa1b2093c72966f6a377444Gary Mai    private static final int DATA_SET = 2;
46a172180513fce7670fa1b2093c72966f6a377444Gary Mai    private static final int RAW_CONTACT_ID = 3;
47a172180513fce7670fa1b2093c72966f6a377444Gary Mai    private static final int DISPLAY_NAME_PRIMARY = 4;
48a172180513fce7670fa1b2093c72966f6a377444Gary Mai    private static final int DISPLAY_NAME_ALTERNATIVE = 5;
49a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai
503a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai    private static final String PHOTO_SELECTION_PREFIX =
513a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai            ContactsContract.Data.RAW_CONTACT_ID + " IN (";
523a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai    private static final String PHOTO_SELECTION_SUFFIX = ") AND " + ContactsContract.Data.MIMETYPE
533a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai            + "=\"" + ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE + "\"";
543a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai
55a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai    public PickRawContactLoader(Context context, Uri contactUri) {
56a172180513fce7670fa1b2093c72966f6a377444Gary Mai        super(context);
57a172180513fce7670fa1b2093c72966f6a377444Gary Mai        mContactUri = ensureIsContactUri(contactUri);
58a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai    }
59a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai
60a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai    @Override
61a172180513fce7670fa1b2093c72966f6a377444Gary Mai    public RawContactsMetadata loadInBackground() {
62a172180513fce7670fa1b2093c72966f6a377444Gary Mai        final ContentResolver resolver = getContext().getContentResolver();
63a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai        // Get the id of the contact we're looking at.
64a172180513fce7670fa1b2093c72966f6a377444Gary Mai        final Cursor contactCursor = resolver.query(
653a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai                mContactUri, new String[] {Contacts._ID, Contacts.IS_USER_PROFILE}, null,
66a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai                null, null);
67a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai
68a172180513fce7670fa1b2093c72966f6a377444Gary Mai        if (contactCursor == null) {
69a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai            return null;
70a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai        }
71a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai
72a172180513fce7670fa1b2093c72966f6a377444Gary Mai        if (contactCursor.getCount() < 1) {
73a172180513fce7670fa1b2093c72966f6a377444Gary Mai            contactCursor.close();
74a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai            return null;
75a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai        }
76a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai
77a172180513fce7670fa1b2093c72966f6a377444Gary Mai        final RawContactsMetadata result = new RawContactsMetadata();
78a172180513fce7670fa1b2093c72966f6a377444Gary Mai        try {
79a172180513fce7670fa1b2093c72966f6a377444Gary Mai            contactCursor.moveToFirst();
80b9065ddb28a2040cabda251891be2062b5260217Gary Mai            result.contactId = contactCursor.getLong(/* Contacts._ID */ 0);
81a172180513fce7670fa1b2093c72966f6a377444Gary Mai            result.isUserProfile = contactCursor.getInt(/* Contacts.IS_USER_PROFILE */ 1) == 1;
82a172180513fce7670fa1b2093c72966f6a377444Gary Mai        } finally {
83a172180513fce7670fa1b2093c72966f6a377444Gary Mai            contactCursor.close();
84a172180513fce7670fa1b2093c72966f6a377444Gary Mai        }
85ba10be290e9a1b105743784ab6cc602bbf3078d8Gary Mai
86a172180513fce7670fa1b2093c72966f6a377444Gary Mai        // Load RawContact data
87a172180513fce7670fa1b2093c72966f6a377444Gary Mai        final Uri rawContactUri;
88a172180513fce7670fa1b2093c72966f6a377444Gary Mai        if (result.isUserProfile) {
89a172180513fce7670fa1b2093c72966f6a377444Gary Mai            rawContactUri = ContactsContract.Profile.CONTENT_RAW_CONTACTS_URI;
90ba10be290e9a1b105743784ab6cc602bbf3078d8Gary Mai        } else {
91a172180513fce7670fa1b2093c72966f6a377444Gary Mai            rawContactUri = RawContacts.CONTENT_URI;
92a172180513fce7670fa1b2093c72966f6a377444Gary Mai        }
93a172180513fce7670fa1b2093c72966f6a377444Gary Mai
94a172180513fce7670fa1b2093c72966f6a377444Gary Mai        final Cursor rawContactCursor = resolver.query(
95a172180513fce7670fa1b2093c72966f6a377444Gary Mai                rawContactUri, RAW_CONTACT_PROJECTION, RAW_CONTACT_SELECTION,
96b9065ddb28a2040cabda251891be2062b5260217Gary Mai                new String[] {Long.toString(result.contactId)}, null);
97a172180513fce7670fa1b2093c72966f6a377444Gary Mai
98a172180513fce7670fa1b2093c72966f6a377444Gary Mai        if (rawContactCursor == null) {
99a172180513fce7670fa1b2093c72966f6a377444Gary Mai            return null;
100a172180513fce7670fa1b2093c72966f6a377444Gary Mai        }
101a172180513fce7670fa1b2093c72966f6a377444Gary Mai
102cea6f3d1448e3a2832dad57339917ce878594b24Gary Mai        if (rawContactCursor.getCount() < 1) {
103cea6f3d1448e3a2832dad57339917ce878594b24Gary Mai            rawContactCursor.close();
104cea6f3d1448e3a2832dad57339917ce878594b24Gary Mai            return null;
105cea6f3d1448e3a2832dad57339917ce878594b24Gary Mai        }
106cea6f3d1448e3a2832dad57339917ce878594b24Gary Mai
107a172180513fce7670fa1b2093c72966f6a377444Gary Mai        rawContactCursor.moveToPosition(-1);
1083a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai        final StringBuilder photoSelection = new StringBuilder(PHOTO_SELECTION_PREFIX);
1093a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai        final Map<Long, RawContact> rawContactMap = new HashMap<>();
110a172180513fce7670fa1b2093c72966f6a377444Gary Mai        try {
111a172180513fce7670fa1b2093c72966f6a377444Gary Mai            while (rawContactCursor.moveToNext()) {
112a172180513fce7670fa1b2093c72966f6a377444Gary Mai                RawContact rawContact = new RawContact();
113a172180513fce7670fa1b2093c72966f6a377444Gary Mai                rawContact.id = rawContactCursor.getLong(RAW_CONTACT_ID);
1143a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai                photoSelection.append(rawContact.id).append(',');
115a172180513fce7670fa1b2093c72966f6a377444Gary Mai                rawContact.displayName = rawContactCursor.getString(DISPLAY_NAME_PRIMARY);
116a172180513fce7670fa1b2093c72966f6a377444Gary Mai                rawContact.displayNameAlt = rawContactCursor.getString(DISPLAY_NAME_ALTERNATIVE);
117a172180513fce7670fa1b2093c72966f6a377444Gary Mai                rawContact.accountName = rawContactCursor.getString(ACCOUNT_NAME);
118a172180513fce7670fa1b2093c72966f6a377444Gary Mai                rawContact.accountType = rawContactCursor.getString(ACCOUNT_TYPE);
119a172180513fce7670fa1b2093c72966f6a377444Gary Mai                rawContact.accountDataSet = rawContactCursor.getString(DATA_SET);
120a172180513fce7670fa1b2093c72966f6a377444Gary Mai                result.rawContacts.add(rawContact);
1213a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai                rawContactMap.put(rawContact.id, rawContact);
122a172180513fce7670fa1b2093c72966f6a377444Gary Mai            }
123a172180513fce7670fa1b2093c72966f6a377444Gary Mai        } finally {
124a172180513fce7670fa1b2093c72966f6a377444Gary Mai            rawContactCursor.close();
125a172180513fce7670fa1b2093c72966f6a377444Gary Mai        }
1263a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai
1273a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai        // Remove the last ','
1283a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai        if (photoSelection.length() > 0) {
1293a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai            photoSelection.deleteCharAt(photoSelection.length() - 1);
1303a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai        }
1313a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai        photoSelection.append(PHOTO_SELECTION_SUFFIX);
1323a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai
1333a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai        final Uri dataUri = result.isUserProfile
1343a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai                ? Uri.withAppendedPath(Profile.CONTENT_URI, Data.CONTENT_URI.getPath())
1353a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai                : Data.CONTENT_URI;
1363a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai        final Cursor photoCursor = resolver.query(
1373a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai                dataUri,
1383a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai                new String[] {Data.RAW_CONTACT_ID, Contacts.Photo._ID},
1393a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai                photoSelection.toString(), null, null);
1403a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai
1413a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai        if (photoCursor != null) {
1423a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai            try {
1433a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai                photoCursor.moveToPosition(-1);
1443a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai                while (photoCursor.moveToNext()) {
1453a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai                    final long rawContactId = photoCursor.getLong(/* Data.RAW_CONTACT_ID */ 0);
1463a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai                    rawContactMap.get(rawContactId).photoId =
1473a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai                            photoCursor.getLong(/* PHOTO._ID */ 1);
1483a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai                }
1493a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai            } finally {
1503a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai                photoCursor.close();
1513a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai            }
1523a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai        }
153a172180513fce7670fa1b2093c72966f6a377444Gary Mai        return result;
154a172180513fce7670fa1b2093c72966f6a377444Gary Mai    }
155a172180513fce7670fa1b2093c72966f6a377444Gary Mai
156a172180513fce7670fa1b2093c72966f6a377444Gary Mai    @Override
157a172180513fce7670fa1b2093c72966f6a377444Gary Mai    public void deliverResult(RawContactsMetadata data) {
158a172180513fce7670fa1b2093c72966f6a377444Gary Mai        mCachedResult = data;
159a172180513fce7670fa1b2093c72966f6a377444Gary Mai        if (isStarted()) {
160a172180513fce7670fa1b2093c72966f6a377444Gary Mai            super.deliverResult(data);
161ba10be290e9a1b105743784ab6cc602bbf3078d8Gary Mai        }
162a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai    }
163a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai
164a172180513fce7670fa1b2093c72966f6a377444Gary Mai    @Override
165a172180513fce7670fa1b2093c72966f6a377444Gary Mai    protected void onStartLoading() {
166a172180513fce7670fa1b2093c72966f6a377444Gary Mai        super.onStartLoading();
167a172180513fce7670fa1b2093c72966f6a377444Gary Mai        if (mCachedResult == null) {
168a172180513fce7670fa1b2093c72966f6a377444Gary Mai            forceLoad();
169a172180513fce7670fa1b2093c72966f6a377444Gary Mai        } else {
170a172180513fce7670fa1b2093c72966f6a377444Gary Mai            deliverResult(mCachedResult);
171a172180513fce7670fa1b2093c72966f6a377444Gary Mai        }
172ba10be290e9a1b105743784ab6cc602bbf3078d8Gary Mai    }
173ba10be290e9a1b105743784ab6cc602bbf3078d8Gary Mai
174a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai    /**
175a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai     * Ensures that this is a valid contact URI. If invalid, then an exception is
176a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai     * thrown. Otherwise, the original URI is returned.
177a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai     */
178a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai    private static Uri ensureIsContactUri(final Uri uri) {
179a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai        if (uri == null) {
180a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai            throw new IllegalArgumentException("Uri must not be null");
181a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai        }
182a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai        if (!uri.toString().startsWith(Contacts.CONTENT_URI.toString())) {
183a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai            throw new IllegalArgumentException("Invalid contact Uri: " + uri);
184a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai        }
185a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai        return uri;
186a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai    }
187a172180513fce7670fa1b2093c72966f6a377444Gary Mai
188a172180513fce7670fa1b2093c72966f6a377444Gary Mai    public static class RawContactsMetadata implements Parcelable {
189a172180513fce7670fa1b2093c72966f6a377444Gary Mai        public static final Parcelable.Creator<RawContactsMetadata> CREATOR =
190a172180513fce7670fa1b2093c72966f6a377444Gary Mai                new Parcelable.Creator<RawContactsMetadata>() {
191a172180513fce7670fa1b2093c72966f6a377444Gary Mai                    @Override
192a172180513fce7670fa1b2093c72966f6a377444Gary Mai                    public RawContactsMetadata createFromParcel(Parcel source) {
193a172180513fce7670fa1b2093c72966f6a377444Gary Mai                        return new RawContactsMetadata(source);
194a172180513fce7670fa1b2093c72966f6a377444Gary Mai                    }
195a172180513fce7670fa1b2093c72966f6a377444Gary Mai
196a172180513fce7670fa1b2093c72966f6a377444Gary Mai                    @Override
197a172180513fce7670fa1b2093c72966f6a377444Gary Mai                    public RawContactsMetadata[] newArray(int size) {
198a172180513fce7670fa1b2093c72966f6a377444Gary Mai                        return new RawContactsMetadata[size];
199a172180513fce7670fa1b2093c72966f6a377444Gary Mai                    }
200a172180513fce7670fa1b2093c72966f6a377444Gary Mai                };
201a172180513fce7670fa1b2093c72966f6a377444Gary Mai
202b9065ddb28a2040cabda251891be2062b5260217Gary Mai        public long contactId;
203a172180513fce7670fa1b2093c72966f6a377444Gary Mai        public boolean isUserProfile;
204a172180513fce7670fa1b2093c72966f6a377444Gary Mai        public boolean showReadOnly = false;
205a172180513fce7670fa1b2093c72966f6a377444Gary Mai        public ArrayList<RawContact> rawContacts = new ArrayList<>();
206a172180513fce7670fa1b2093c72966f6a377444Gary Mai
207a172180513fce7670fa1b2093c72966f6a377444Gary Mai        public RawContactsMetadata() {}
208a172180513fce7670fa1b2093c72966f6a377444Gary Mai
209a172180513fce7670fa1b2093c72966f6a377444Gary Mai        private RawContactsMetadata(Parcel in) {
210b9065ddb28a2040cabda251891be2062b5260217Gary Mai            contactId = in.readLong();
211a172180513fce7670fa1b2093c72966f6a377444Gary Mai            isUserProfile = in.readInt() == 1;
212a172180513fce7670fa1b2093c72966f6a377444Gary Mai            showReadOnly = in.readInt() == 1;
213a172180513fce7670fa1b2093c72966f6a377444Gary Mai            in.readTypedList(rawContacts, RawContact.CREATOR);
214a172180513fce7670fa1b2093c72966f6a377444Gary Mai        }
215a172180513fce7670fa1b2093c72966f6a377444Gary Mai
216a172180513fce7670fa1b2093c72966f6a377444Gary Mai        /**
217a172180513fce7670fa1b2093c72966f6a377444Gary Mai         * Removes all read-only raw contacts.
218a172180513fce7670fa1b2093c72966f6a377444Gary Mai         */
219a172180513fce7670fa1b2093c72966f6a377444Gary Mai        public void trimReadOnly(AccountTypeManager accountManager) {
220a172180513fce7670fa1b2093c72966f6a377444Gary Mai            for (int i = rawContacts.size() - 1; i >= 0 ; i--) {
221a172180513fce7670fa1b2093c72966f6a377444Gary Mai                final RawContact rawContact = rawContacts.get(i);
222a172180513fce7670fa1b2093c72966f6a377444Gary Mai                final AccountType account = accountManager.getAccountType(
223a172180513fce7670fa1b2093c72966f6a377444Gary Mai                        rawContact.accountType, rawContact.accountDataSet);
224a172180513fce7670fa1b2093c72966f6a377444Gary Mai                if (!account.areContactsWritable()) {
225a172180513fce7670fa1b2093c72966f6a377444Gary Mai                    rawContacts.remove(i);
226a172180513fce7670fa1b2093c72966f6a377444Gary Mai                }
227a172180513fce7670fa1b2093c72966f6a377444Gary Mai            }
228a172180513fce7670fa1b2093c72966f6a377444Gary Mai        }
229a172180513fce7670fa1b2093c72966f6a377444Gary Mai
230a172180513fce7670fa1b2093c72966f6a377444Gary Mai        /**
231a172180513fce7670fa1b2093c72966f6a377444Gary Mai         * Returns the index of the first writable account in this contact or -1 if none exist.
232a172180513fce7670fa1b2093c72966f6a377444Gary Mai         */
233a172180513fce7670fa1b2093c72966f6a377444Gary Mai        public int getIndexOfFirstWritableAccount(AccountTypeManager accountManager) {
234a172180513fce7670fa1b2093c72966f6a377444Gary Mai            for (int i = 0; i < rawContacts.size(); i++) {
235a172180513fce7670fa1b2093c72966f6a377444Gary Mai                final RawContact rawContact = rawContacts.get(i);
236a172180513fce7670fa1b2093c72966f6a377444Gary Mai                final AccountType account = accountManager.getAccountType(
237a172180513fce7670fa1b2093c72966f6a377444Gary Mai                        rawContact.accountType, rawContact.accountDataSet);
238a172180513fce7670fa1b2093c72966f6a377444Gary Mai                if (account.areContactsWritable()) {
239a172180513fce7670fa1b2093c72966f6a377444Gary Mai                    return i;
240a172180513fce7670fa1b2093c72966f6a377444Gary Mai                }
241a172180513fce7670fa1b2093c72966f6a377444Gary Mai            }
242a172180513fce7670fa1b2093c72966f6a377444Gary Mai
243a172180513fce7670fa1b2093c72966f6a377444Gary Mai            return -1;
244a172180513fce7670fa1b2093c72966f6a377444Gary Mai        }
245a172180513fce7670fa1b2093c72966f6a377444Gary Mai
246a172180513fce7670fa1b2093c72966f6a377444Gary Mai        @Override
247a172180513fce7670fa1b2093c72966f6a377444Gary Mai        public int describeContents() {
248a172180513fce7670fa1b2093c72966f6a377444Gary Mai            return 0;
249a172180513fce7670fa1b2093c72966f6a377444Gary Mai        }
250a172180513fce7670fa1b2093c72966f6a377444Gary Mai
251a172180513fce7670fa1b2093c72966f6a377444Gary Mai        @Override
252a172180513fce7670fa1b2093c72966f6a377444Gary Mai        public void writeToParcel(Parcel dest, int flags) {
253b9065ddb28a2040cabda251891be2062b5260217Gary Mai            dest.writeLong(contactId);
254a172180513fce7670fa1b2093c72966f6a377444Gary Mai            dest.writeInt(isUserProfile ? 1 : 0);
255a172180513fce7670fa1b2093c72966f6a377444Gary Mai            dest.writeInt(showReadOnly ? 1 : 0);
256a172180513fce7670fa1b2093c72966f6a377444Gary Mai            dest.writeTypedList(rawContacts);
257a172180513fce7670fa1b2093c72966f6a377444Gary Mai        }
258a172180513fce7670fa1b2093c72966f6a377444Gary Mai    }
259a172180513fce7670fa1b2093c72966f6a377444Gary Mai
260a172180513fce7670fa1b2093c72966f6a377444Gary Mai    public static class RawContact implements Parcelable {
261a172180513fce7670fa1b2093c72966f6a377444Gary Mai        public static final Parcelable.Creator<RawContact> CREATOR =
262a172180513fce7670fa1b2093c72966f6a377444Gary Mai                new Parcelable.Creator<RawContact>() {
263a172180513fce7670fa1b2093c72966f6a377444Gary Mai                    @Override
264a172180513fce7670fa1b2093c72966f6a377444Gary Mai                    public RawContact createFromParcel(Parcel source) {
265a172180513fce7670fa1b2093c72966f6a377444Gary Mai                        return new RawContact(source);
266a172180513fce7670fa1b2093c72966f6a377444Gary Mai                    }
267a172180513fce7670fa1b2093c72966f6a377444Gary Mai
268a172180513fce7670fa1b2093c72966f6a377444Gary Mai                    @Override
269a172180513fce7670fa1b2093c72966f6a377444Gary Mai                    public RawContact[] newArray(int size) {
270a172180513fce7670fa1b2093c72966f6a377444Gary Mai                        return new RawContact[size];
271a172180513fce7670fa1b2093c72966f6a377444Gary Mai                    }
272a172180513fce7670fa1b2093c72966f6a377444Gary Mai                };
273a172180513fce7670fa1b2093c72966f6a377444Gary Mai
274a172180513fce7670fa1b2093c72966f6a377444Gary Mai        public long id;
2753a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai        public long photoId;
276a172180513fce7670fa1b2093c72966f6a377444Gary Mai        public String displayName;
277a172180513fce7670fa1b2093c72966f6a377444Gary Mai        public String displayNameAlt;
278a172180513fce7670fa1b2093c72966f6a377444Gary Mai        public String accountName;
279a172180513fce7670fa1b2093c72966f6a377444Gary Mai        public String accountType;
280a172180513fce7670fa1b2093c72966f6a377444Gary Mai        public String accountDataSet;
281a172180513fce7670fa1b2093c72966f6a377444Gary Mai
282a172180513fce7670fa1b2093c72966f6a377444Gary Mai        public RawContact() {}
283a172180513fce7670fa1b2093c72966f6a377444Gary Mai
284a172180513fce7670fa1b2093c72966f6a377444Gary Mai        private RawContact(Parcel in) {
285a172180513fce7670fa1b2093c72966f6a377444Gary Mai            id = in.readLong();
2863a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai            photoId = in.readLong();
287a172180513fce7670fa1b2093c72966f6a377444Gary Mai            displayName = in.readString();
288a172180513fce7670fa1b2093c72966f6a377444Gary Mai            displayNameAlt = in.readString();
289a172180513fce7670fa1b2093c72966f6a377444Gary Mai            accountName = in.readString();
290a172180513fce7670fa1b2093c72966f6a377444Gary Mai            accountType = in.readString();
291a172180513fce7670fa1b2093c72966f6a377444Gary Mai            accountDataSet = in.readString();
292a172180513fce7670fa1b2093c72966f6a377444Gary Mai        }
293a172180513fce7670fa1b2093c72966f6a377444Gary Mai
294a172180513fce7670fa1b2093c72966f6a377444Gary Mai        @Override
295a172180513fce7670fa1b2093c72966f6a377444Gary Mai        public int describeContents() {
296a172180513fce7670fa1b2093c72966f6a377444Gary Mai            return 0;
297a172180513fce7670fa1b2093c72966f6a377444Gary Mai        }
298a172180513fce7670fa1b2093c72966f6a377444Gary Mai
299a172180513fce7670fa1b2093c72966f6a377444Gary Mai        @Override
300a172180513fce7670fa1b2093c72966f6a377444Gary Mai        public void writeToParcel(Parcel dest, int flags) {
301a172180513fce7670fa1b2093c72966f6a377444Gary Mai            dest.writeLong(id);
3023a53328fe057610d44f228666c92c3c5ac2d4799Gary Mai            dest.writeLong(photoId);
303a172180513fce7670fa1b2093c72966f6a377444Gary Mai            dest.writeString(displayName);
304a172180513fce7670fa1b2093c72966f6a377444Gary Mai            dest.writeString(displayNameAlt);
305a172180513fce7670fa1b2093c72966f6a377444Gary Mai            dest.writeString(accountName);
306a172180513fce7670fa1b2093c72966f6a377444Gary Mai            dest.writeString(accountType);
307a172180513fce7670fa1b2093c72966f6a377444Gary Mai            dest.writeString(accountDataSet);
308a172180513fce7670fa1b2093c72966f6a377444Gary Mai        }
309a172180513fce7670fa1b2093c72966f6a377444Gary Mai    }
310a6c80b378e03ebdf6b654dbdb12f2c665fe98a80Gary Mai}
311