19692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov/*
29692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov * Copyright (C) 2010 The Android Open Source Project
39692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov *
49692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov * Licensed under the Apache License, Version 2.0 (the "License");
59692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov * you may not use this file except in compliance with the License.
69692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov * You may obtain a copy of the License at
79692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov *
89692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov *      http://www.apache.org/licenses/LICENSE-2.0
99692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov *
109692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov * Unless required by applicable law or agreed to in writing, software
119692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov * distributed under the License is distributed on an "AS IS" BASIS,
129692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov * See the License for the specific language governing permissions and
149692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov * limitations under the License.
159692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov */
169692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov
179692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikovpackage com.android.contacts.interactions;
189692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov
199692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikovimport android.app.Activity;
209692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikovimport android.app.AlertDialog;
2166bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikovimport android.app.Fragment;
2266bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikovimport android.app.FragmentManager;
2334ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerdaimport android.app.LoaderManager;
2466bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikovimport android.app.LoaderManager.LoaderCallbacks;
259692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikovimport android.content.Context;
269692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikovimport android.content.CursorLoader;
279692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikovimport android.content.DialogInterface;
2866bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikovimport android.content.DialogInterface.OnDismissListener;
299692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikovimport android.content.Loader;
309692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikovimport android.database.Cursor;
319692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikovimport android.net.Uri;
329692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikovimport android.os.Bundle;
33355d0f4f48bafdc6c267344f7661b3cdea7741eeDmitri Plotnikovimport android.provider.ContactsContract.Contacts;
34355d0f4f48bafdc6c267344f7661b3cdea7741eeDmitri Plotnikovimport android.provider.ContactsContract.Contacts.Entity;
35e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Cheng
36e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.ContactSaveService;
37e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.R;
380d5588da244d0992c3ff8f25d0875fdf95a8c644Chiao Chengimport com.android.contacts.common.model.AccountTypeManager;
39428f008513d1591cc08fcfe2cf0c9237fb313241Chiao Chengimport com.android.contacts.common.model.account.AccountType;
40e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.google.common.annotations.VisibleForTesting;
41e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.google.common.collect.Sets;
429692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov
43355d0f4f48bafdc6c267344f7661b3cdea7741eeDmitri Plotnikovimport java.util.HashSet;
44355d0f4f48bafdc6c267344f7661b3cdea7741eeDmitri Plotnikov
459692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov/**
469692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov * An interaction invoked to delete a contact.
479692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov */
4866bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikovpublic class ContactDeletionInteraction extends Fragment
4966bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov        implements LoaderCallbacks<Cursor>, OnDismissListener {
5066bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov
5166bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov    private static final String FRAGMENT_TAG = "deleteContact";
529692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov
5366bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov    private static final String KEY_ACTIVE = "active";
54cc42b45b85456bda4dd3ca1a0b4c24b2a8c368bdDmitri Plotnikov    private static final String KEY_CONTACT_URI = "contactUri";
55c9eda37df2ff1ba2f845ae330bae364cb35fa50aDmitri Plotnikov    private static final String KEY_FINISH_WHEN_DONE = "finishWhenDone";
5666bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov    public static final String ARG_CONTACT_URI = "contactUri";
578a6f4ade05e5a8a89d91078ef9c22944450ac8baBrian Attwell    public static final int RESULT_CODE_DELETED = 3;
589692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov
5966bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov    private static final String[] ENTITY_PROJECTION = new String[] {
6066bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov        Entity.RAW_CONTACT_ID, //0
6166bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov        Entity.ACCOUNT_TYPE, //1
622b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro        Entity.DATA_SET, // 2
632b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro        Entity.CONTACT_ID, // 3
642b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro        Entity.LOOKUP_KEY, // 4
659692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov    };
669692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov
67355d0f4f48bafdc6c267344f7661b3cdea7741eeDmitri Plotnikov    private static final int COLUMN_INDEX_RAW_CONTACT_ID = 0;
68355d0f4f48bafdc6c267344f7661b3cdea7741eeDmitri Plotnikov    private static final int COLUMN_INDEX_ACCOUNT_TYPE = 1;
692b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro    private static final int COLUMN_INDEX_DATA_SET = 2;
702b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro    private static final int COLUMN_INDEX_CONTACT_ID = 3;
712b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro    private static final int COLUMN_INDEX_LOOKUP_KEY = 4;
72355d0f4f48bafdc6c267344f7661b3cdea7741eeDmitri Plotnikov
7366bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov    private boolean mActive;
7466bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov    private Uri mContactUri;
75c9eda37df2ff1ba2f845ae330bae364cb35fa50aDmitri Plotnikov    private boolean mFinishActivityWhenDone;
7666bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov    private Context mContext;
7766bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov    private AlertDialog mDialog;
789692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov
7934ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda    /** This is a wrapper around the fragment's loader manager to be used only during testing. */
8034ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda    private TestLoaderManager mTestLoaderManager;
8134ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda
8234ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda    @VisibleForTesting
8343fd1e84de5e28639062c20d35ba7bfec8a07001Dmitri Plotnikov    int mMessageId;
8443fd1e84de5e28639062c20d35ba7bfec8a07001Dmitri Plotnikov
8534ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda    /**
8634ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda     * Starts the interaction.
8734ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda     *
8834ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda     * @param activity the activity within which to start the interaction
8934ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda     * @param contactUri the URI of the contact to delete
9034ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda     * @param finishActivityWhenDone whether to finish the activity upon completion of the
9134ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda     *        interaction
9234ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda     * @return the newly created interaction
9334ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda     */
94c9eda37df2ff1ba2f845ae330bae364cb35fa50aDmitri Plotnikov    public static ContactDeletionInteraction start(
95c9eda37df2ff1ba2f845ae330bae364cb35fa50aDmitri Plotnikov            Activity activity, Uri contactUri, boolean finishActivityWhenDone) {
9634ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda        return startWithTestLoaderManager(activity, contactUri, finishActivityWhenDone, null);
9734ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda    }
9834ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda
9934ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda    /**
10034ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda     * Starts the interaction and optionally set up a {@link TestLoaderManager}.
10134ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda     *
10234ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda     * @param activity the activity within which to start the interaction
10334ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda     * @param contactUri the URI of the contact to delete
10434ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda     * @param finishActivityWhenDone whether to finish the activity upon completion of the
10534ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda     *        interaction
10634ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda     * @param testLoaderManager the {@link TestLoaderManager} to use to load the data, may be null
10734ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda     *        in which case the default {@link LoaderManager} is used
10834ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda     * @return the newly created interaction
10934ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda     */
11034ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda    @VisibleForTesting
11134ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda    static ContactDeletionInteraction startWithTestLoaderManager(
11234ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda            Activity activity, Uri contactUri, boolean finishActivityWhenDone,
11334ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda            TestLoaderManager testLoaderManager) {
114ac0e18e09199247baacba175ccc9f4ef4edffd13Dmitri Plotnikov        if (contactUri == null) {
115ac0e18e09199247baacba175ccc9f4ef4edffd13Dmitri Plotnikov            return null;
116ac0e18e09199247baacba175ccc9f4ef4edffd13Dmitri Plotnikov        }
117ac0e18e09199247baacba175ccc9f4ef4edffd13Dmitri Plotnikov
11866bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov        FragmentManager fragmentManager = activity.getFragmentManager();
11966bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov        ContactDeletionInteraction fragment =
12066bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov                (ContactDeletionInteraction) fragmentManager.findFragmentByTag(FRAGMENT_TAG);
12166bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov        if (fragment == null) {
12266bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov            fragment = new ContactDeletionInteraction();
12334ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda            fragment.setTestLoaderManager(testLoaderManager);
12466bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov            fragment.setContactUri(contactUri);
125c9eda37df2ff1ba2f845ae330bae364cb35fa50aDmitri Plotnikov            fragment.setFinishActivityWhenDone(finishActivityWhenDone);
1264b25da79091157935042d2942a8961ceba92166fMinh Pham            fragmentManager.beginTransaction().add(fragment, FRAGMENT_TAG)
1274b25da79091157935042d2942a8961ceba92166fMinh Pham                    .commitAllowingStateLoss();
12866bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov        } else {
12934ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda            fragment.setTestLoaderManager(testLoaderManager);
13066bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov            fragment.setContactUri(contactUri);
131c9eda37df2ff1ba2f845ae330bae364cb35fa50aDmitri Plotnikov            fragment.setFinishActivityWhenDone(finishActivityWhenDone);
1329692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov        }
13343fd1e84de5e28639062c20d35ba7bfec8a07001Dmitri Plotnikov        return fragment;
1349692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov    }
1359692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov
13666bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov    @Override
13734ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda    public LoaderManager getLoaderManager() {
13834ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda        // Return the TestLoaderManager if one is set up.
13934ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda        LoaderManager loaderManager = super.getLoaderManager();
14034ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda        if (mTestLoaderManager != null) {
14134ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda            // Set the delegate: this operation is idempotent, so let's just do it every time.
14234ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda            mTestLoaderManager.setDelegate(loaderManager);
14334ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda            return mTestLoaderManager;
14434ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda        } else {
14534ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda            return loaderManager;
14634ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda        }
14734ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda    }
14834ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda
14934ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda    /** Sets the TestLoaderManager that is used to wrap the actual LoaderManager in tests. */
15034ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda    private void setTestLoaderManager(TestLoaderManager mockLoaderManager) {
15134ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda        mTestLoaderManager = mockLoaderManager;
15234ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda    }
15334ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda
15434ce5e98f78b46b858d8afd450d1153c1d985426Flavio Lerda    @Override
15566bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov    public void onAttach(Activity activity) {
15666bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov        super.onAttach(activity);
15743fd1e84de5e28639062c20d35ba7bfec8a07001Dmitri Plotnikov        mContext = activity;
15866bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov    }
1599692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov
1600279fcaca57c064e156cea43706b838ba031830aDmitri Plotnikov    @Override
1610279fcaca57c064e156cea43706b838ba031830aDmitri Plotnikov    public void onDestroyView() {
1620279fcaca57c064e156cea43706b838ba031830aDmitri Plotnikov        super.onDestroyView();
1630279fcaca57c064e156cea43706b838ba031830aDmitri Plotnikov        if (mDialog != null && mDialog.isShowing()) {
1640279fcaca57c064e156cea43706b838ba031830aDmitri Plotnikov            mDialog.setOnDismissListener(null);
1650279fcaca57c064e156cea43706b838ba031830aDmitri Plotnikov            mDialog.dismiss();
1660279fcaca57c064e156cea43706b838ba031830aDmitri Plotnikov            mDialog = null;
1670279fcaca57c064e156cea43706b838ba031830aDmitri Plotnikov        }
1680279fcaca57c064e156cea43706b838ba031830aDmitri Plotnikov    }
1690279fcaca57c064e156cea43706b838ba031830aDmitri Plotnikov
17066bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov    public void setContactUri(Uri contactUri) {
17166bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov        mContactUri = contactUri;
17266bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov        mActive = true;
17366bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov        if (isStarted()) {
17466bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov            Bundle args = new Bundle();
17566bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov            args.putParcelable(ARG_CONTACT_URI, mContactUri);
17643fd1e84de5e28639062c20d35ba7bfec8a07001Dmitri Plotnikov            getLoaderManager().restartLoader(R.id.dialog_delete_contact_loader_id, args, this);
1779692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov        }
1789692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov    }
1799692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov
180c9eda37df2ff1ba2f845ae330bae364cb35fa50aDmitri Plotnikov    private void setFinishActivityWhenDone(boolean finishActivityWhenDone) {
181c9eda37df2ff1ba2f845ae330bae364cb35fa50aDmitri Plotnikov        this.mFinishActivityWhenDone = finishActivityWhenDone;
182c9eda37df2ff1ba2f845ae330bae364cb35fa50aDmitri Plotnikov
183c9eda37df2ff1ba2f845ae330bae364cb35fa50aDmitri Plotnikov    }
184c9eda37df2ff1ba2f845ae330bae364cb35fa50aDmitri Plotnikov
18566bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov    /* Visible for testing */
18666bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov    boolean isStarted() {
18766bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov        return isAdded();
18866bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov    }
1899692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov
19066bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov    @Override
19166bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov    public void onStart() {
19266bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov        if (mActive) {
19366bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov            Bundle args = new Bundle();
19466bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov            args.putParcelable(ARG_CONTACT_URI, mContactUri);
19543fd1e84de5e28639062c20d35ba7bfec8a07001Dmitri Plotnikov            getLoaderManager().initLoader(R.id.dialog_delete_contact_loader_id, args, this);
19666bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov        }
19766bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov        super.onStart();
1989692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov    }
1999692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov
20066bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov    @Override
2010279fcaca57c064e156cea43706b838ba031830aDmitri Plotnikov    public void onStop() {
2020279fcaca57c064e156cea43706b838ba031830aDmitri Plotnikov        super.onStop();
2030279fcaca57c064e156cea43706b838ba031830aDmitri Plotnikov        if (mDialog != null) {
2040279fcaca57c064e156cea43706b838ba031830aDmitri Plotnikov            mDialog.hide();
2050279fcaca57c064e156cea43706b838ba031830aDmitri Plotnikov        }
2060279fcaca57c064e156cea43706b838ba031830aDmitri Plotnikov    }
2070279fcaca57c064e156cea43706b838ba031830aDmitri Plotnikov
2080279fcaca57c064e156cea43706b838ba031830aDmitri Plotnikov    @Override
20966bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
21066bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov        Uri contactUri = args.getParcelable(ARG_CONTACT_URI);
21166bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov        return new CursorLoader(mContext,
21266bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov                Uri.withAppendedPath(contactUri, Entity.CONTENT_DIRECTORY), ENTITY_PROJECTION,
21366bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov                null, null, null);
2149692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov    }
2159692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov
21666bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov    @Override
21766bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov    public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
21866bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov        if (mDialog != null) {
21966bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov            mDialog.dismiss();
22066bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov            mDialog = null;
22166bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov        }
22266bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov
22366bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov        if (!mActive) {
22466bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov            return;
2259692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov        }
2269692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov
227355d0f4f48bafdc6c267344f7661b3cdea7741eeDmitri Plotnikov        long contactId = 0;
228355d0f4f48bafdc6c267344f7661b3cdea7741eeDmitri Plotnikov        String lookupKey = null;
229355d0f4f48bafdc6c267344f7661b3cdea7741eeDmitri Plotnikov
230355d0f4f48bafdc6c267344f7661b3cdea7741eeDmitri Plotnikov        // This cursor may contain duplicate raw contacts, so we need to de-dupe them first
231355d0f4f48bafdc6c267344f7661b3cdea7741eeDmitri Plotnikov        HashSet<Long>  readOnlyRawContacts = Sets.newHashSet();
232355d0f4f48bafdc6c267344f7661b3cdea7741eeDmitri Plotnikov        HashSet<Long>  writableRawContacts = Sets.newHashSet();
2339692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov
234a07fa5f37031e4c5cd2933de02d2db41ec153e2bDmitri Plotnikov        AccountTypeManager accountTypes = AccountTypeManager.getInstance(getActivity());
23566bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov        cursor.moveToPosition(-1);
23666bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov        while (cursor.moveToNext()) {
23766bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov            final long rawContactId = cursor.getLong(COLUMN_INDEX_RAW_CONTACT_ID);
23866bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov            final String accountType = cursor.getString(COLUMN_INDEX_ACCOUNT_TYPE);
2392b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro            final String dataSet = cursor.getString(COLUMN_INDEX_DATA_SET);
24066bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov            contactId = cursor.getLong(COLUMN_INDEX_CONTACT_ID);
24166bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov            lookupKey = cursor.getString(COLUMN_INDEX_LOOKUP_KEY);
2422b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro            AccountType type = accountTypes.getAccountType(accountType, dataSet);
24396e87fd6e808e9d853263ffeb5104f3253a18639Daniel Lehmann            boolean writable = type == null || type.areContactsWritable();
24496e87fd6e808e9d853263ffeb5104f3253a18639Daniel Lehmann            if (writable) {
24566bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov                writableRawContacts.add(rawContactId);
24696e87fd6e808e9d853263ffeb5104f3253a18639Daniel Lehmann            } else {
24796e87fd6e808e9d853263ffeb5104f3253a18639Daniel Lehmann                readOnlyRawContacts.add(rawContactId);
2489692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov            }
2499692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov        }
2509692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov
251355d0f4f48bafdc6c267344f7661b3cdea7741eeDmitri Plotnikov        int readOnlyCount = readOnlyRawContacts.size();
252355d0f4f48bafdc6c267344f7661b3cdea7741eeDmitri Plotnikov        int writableCount = writableRawContacts.size();
253355d0f4f48bafdc6c267344f7661b3cdea7741eeDmitri Plotnikov        if (readOnlyCount > 0 && writableCount > 0) {
25443fd1e84de5e28639062c20d35ba7bfec8a07001Dmitri Plotnikov            mMessageId = R.string.readOnlyContactDeleteConfirmation;
255355d0f4f48bafdc6c267344f7661b3cdea7741eeDmitri Plotnikov        } else if (readOnlyCount > 0 && writableCount == 0) {
25643fd1e84de5e28639062c20d35ba7bfec8a07001Dmitri Plotnikov            mMessageId = R.string.readOnlyContactWarning;
257355d0f4f48bafdc6c267344f7661b3cdea7741eeDmitri Plotnikov        } else if (readOnlyCount == 0 && writableCount > 1) {
25843fd1e84de5e28639062c20d35ba7bfec8a07001Dmitri Plotnikov            mMessageId = R.string.multipleContactDeleteConfirmation;
2599692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov        } else {
26043fd1e84de5e28639062c20d35ba7bfec8a07001Dmitri Plotnikov            mMessageId = R.string.deleteConfirmation;
2619692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov        }
2629692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov
26366bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov        final Uri contactUri = Contacts.getLookupUri(contactId, lookupKey);
26443fd1e84de5e28639062c20d35ba7bfec8a07001Dmitri Plotnikov        showDialog(mMessageId, contactUri);
265d7c148bc7331ee405ea2932a63cb12bde259e93cDaisuke Miyakawa
266d7c148bc7331ee405ea2932a63cb12bde259e93cDaisuke Miyakawa        // We don't want onLoadFinished() calls any more, which may come when the database is
267d7c148bc7331ee405ea2932a63cb12bde259e93cDaisuke Miyakawa        // updating.
268d7c148bc7331ee405ea2932a63cb12bde259e93cDaisuke Miyakawa        getLoaderManager().destroyLoader(R.id.dialog_delete_contact_loader_id);
2699692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov    }
2709692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov
271d7c148bc7331ee405ea2932a63cb12bde259e93cDaisuke Miyakawa    @Override
2724ef95cc3329b4ad9fa450e4090efaad9935d493fDianne Hackborn    public void onLoaderReset(Loader<Cursor> loader) {
2734ef95cc3329b4ad9fa450e4090efaad9935d493fDianne Hackborn    }
27469f9e6f0cd9b5401da55f251e9bd98e69643d7dfDmitri Plotnikov
27543fd1e84de5e28639062c20d35ba7bfec8a07001Dmitri Plotnikov    private void showDialog(int messageId, final Uri contactUri) {
27666bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov        mDialog = new AlertDialog.Builder(getActivity())
2774292dfa46123a6c0e1de9862b4d8694bfb87875aDmitri Plotnikov                .setIconAttribute(android.R.attr.alertDialogIcon)
27866bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov                .setMessage(messageId)
2799692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov                .setNegativeButton(android.R.string.cancel, null)
28066bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov                .setPositiveButton(android.R.string.ok,
28166bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov                    new DialogInterface.OnClickListener() {
28266bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov                        @Override
28366bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov                        public void onClick(DialogInterface dialog, int whichButton) {
28466bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov                            doDeleteContact(contactUri);
28566bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov                        }
28666bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov                    }
28766bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov                )
2889692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov                .create();
2899692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov
29066bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov        mDialog.setOnDismissListener(this);
29166bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov        mDialog.show();
29266bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov    }
2939692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov
29466bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov    @Override
29566bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov    public void onDismiss(DialogInterface dialog) {
29666bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov        mActive = false;
29766bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov        mDialog = null;
2989692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov    }
2999692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov
30066bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov    @Override
30166bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov    public void onSaveInstanceState(Bundle outState) {
30266bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov        super.onSaveInstanceState(outState);
30366bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov        outState.putBoolean(KEY_ACTIVE, mActive);
304cc42b45b85456bda4dd3ca1a0b4c24b2a8c368bdDmitri Plotnikov        outState.putParcelable(KEY_CONTACT_URI, mContactUri);
305c9eda37df2ff1ba2f845ae330bae364cb35fa50aDmitri Plotnikov        outState.putBoolean(KEY_FINISH_WHEN_DONE, mFinishActivityWhenDone);
3069692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov    }
3079692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov
30866bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov    @Override
30966bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov    public void onActivityCreated(Bundle savedInstanceState) {
31066bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov        super.onActivityCreated(savedInstanceState);
31166bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov        if (savedInstanceState != null) {
31266bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov            mActive = savedInstanceState.getBoolean(KEY_ACTIVE);
313cc42b45b85456bda4dd3ca1a0b4c24b2a8c368bdDmitri Plotnikov            mContactUri = savedInstanceState.getParcelable(KEY_CONTACT_URI);
314c9eda37df2ff1ba2f845ae330bae364cb35fa50aDmitri Plotnikov            mFinishActivityWhenDone = savedInstanceState.getBoolean(KEY_FINISH_WHEN_DONE);
31566bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov        }
3169692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov    }
3179692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov
31866bca8f360c9e21b6a47006f21db7b46b6b46340Dmitri Plotnikov    protected void doDeleteContact(Uri contactUri) {
3197d8cabb65b02096583b928c64ae455d1f79e5633Dmitri Plotnikov        mContext.startService(ContactSaveService.createDeleteContactIntent(mContext, contactUri));
320c9eda37df2ff1ba2f845ae330bae364cb35fa50aDmitri Plotnikov        if (isAdded() && mFinishActivityWhenDone) {
3218a6f4ade05e5a8a89d91078ef9c22944450ac8baBrian Attwell            getActivity().setResult(RESULT_CODE_DELETED);
322c9eda37df2ff1ba2f845ae330bae364cb35fa50aDmitri Plotnikov            getActivity().finish();
323c9eda37df2ff1ba2f845ae330bae364cb35fa50aDmitri Plotnikov        }
3249692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov    }
3259692f2664e678b0a264c586c70cc4a9c0ffabc21Dmitri Plotnikov}
326