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