1d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell/*
2d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell * Copyright (C) 2015 The Android Open Source Project
3d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell *
4d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell * Licensed under the Apache License, Version 2.0 (the "License");
5d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell * you may not use this file except in compliance with the License.
6d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell * You may obtain a copy of the License at
7d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell *
8d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell *      http://www.apache.org/licenses/LICENSE-2.0
9d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell *
10d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell * Unless required by applicable law or agreed to in writing, software
11d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell * distributed under the License is distributed on an "AS IS" BASIS,
12d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell * See the License for the specific language governing permissions and
14d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell * limitations under the License.
15d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell */
16d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell
17d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwellpackage com.android.contacts.interactions;
18d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell
19d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwellimport android.app.Activity;
20d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwellimport android.app.AlertDialog;
21d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwellimport android.app.Fragment;
22d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwellimport android.app.FragmentManager;
23d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwellimport android.app.LoaderManager.LoaderCallbacks;
24d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwellimport android.content.Context;
25d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwellimport android.content.CursorLoader;
26d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwellimport android.content.DialogInterface;
27d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwellimport android.content.DialogInterface.OnDismissListener;
28d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwellimport android.content.Loader;
29d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwellimport android.database.Cursor;
30d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwellimport android.os.Bundle;
31d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwellimport android.provider.ContactsContract.RawContacts;
32f62b488f4f88a00aa932866e2a355f10aa0bc030James Laskeyimport android.text.TextUtils;
33d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwellimport android.util.Log;
34d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell
350a49afa2ad697307cc04ef4cb86570574fa720f2Gary Maiimport com.android.contacts.ContactSaveService;
360a49afa2ad697307cc04ef4cb86570574fa720f2Gary Maiimport com.android.contacts.R;
370a49afa2ad697307cc04ef4cb86570574fa720f2Gary Maiimport com.android.contacts.model.AccountTypeManager;
380a49afa2ad697307cc04ef4cb86570574fa720f2Gary Maiimport com.android.contacts.model.account.AccountType;
390a49afa2ad697307cc04ef4cb86570574fa720f2Gary Maiimport com.android.contacts.preference.ContactsPreferences;
400a49afa2ad697307cc04ef4cb86570574fa720f2Gary Maiimport com.android.contacts.util.ContactDisplayUtils;
410a49afa2ad697307cc04ef4cb86570574fa720f2Gary Mai
420a49afa2ad697307cc04ef4cb86570574fa720f2Gary Maiimport com.google.common.collect.Sets;
430a49afa2ad697307cc04ef4cb86570574fa720f2Gary Mai
44d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwellimport java.util.HashSet;
45d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwellimport java.util.TreeSet;
46d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell
47d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell/**
48d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell * An interaction invoked to delete multiple contacts.
49d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell *
50d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell * This class is very similar to {@link ContactDeletionInteraction}.
51d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell */
52d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwellpublic class ContactMultiDeletionInteraction extends Fragment
53d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        implements LoaderCallbacks<Cursor> {
54d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell
55d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    public interface MultiContactDeleteListener {
56d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        void onDeletionFinished();
57d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    }
58d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell
59d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    private static final String FRAGMENT_TAG = "deleteMultipleContacts";
6011798d44eb59efc943ba5c78635426d3b773db19Wenyi Wang    private static final String TAG = "ContactMultiDeletion";
61d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    private static final String KEY_ACTIVE = "active";
62d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    private static final String KEY_CONTACTS_IDS = "contactIds";
63d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    public static final String ARG_CONTACT_IDS = "contactIds";
64d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell
65d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    private static final String[] RAW_CONTACT_PROJECTION = new String[] {
66d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            RawContacts._ID,
67d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            RawContacts.ACCOUNT_TYPE,
68d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            RawContacts.DATA_SET,
69d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            RawContacts.CONTACT_ID,
70e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey            RawContacts.DISPLAY_NAME_PRIMARY,
71e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey            RawContacts.DISPLAY_NAME_ALTERNATIVE
72d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    };
73d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell
74d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    private static final int COLUMN_INDEX_RAW_CONTACT_ID = 0;
75d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    private static final int COLUMN_INDEX_ACCOUNT_TYPE = 1;
76d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    private static final int COLUMN_INDEX_DATA_SET = 2;
77d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    private static final int COLUMN_INDEX_CONTACT_ID = 3;
78e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey    private static final int COLUMN_INDEX_DISPLAY_NAME = 4;
79e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey    private static final int COLUMN_INDEX_DISPLAY_NAME_ALT = 5;
80d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell
81d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    private boolean mIsLoaderActive;
82d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    private TreeSet<Long> mContactIds;
83d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    private Context mContext;
84d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    private AlertDialog mDialog;
85587b8f22be5f0e0a7e0b7ea362d81632e4bada66Wenyi Wang    private MultiContactDeleteListener mListener;
86d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell
87d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    /**
88d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell     * Starts the interaction.
89d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell     *
90587b8f22be5f0e0a7e0b7ea362d81632e4bada66Wenyi Wang     * @param hostFragment the fragment within which to start the interaction
91d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell     * @param contactIds the IDs of contacts to be deleted
92d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell     * @return the newly created interaction
93d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell     */
94d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    public static ContactMultiDeletionInteraction start(
95587b8f22be5f0e0a7e0b7ea362d81632e4bada66Wenyi Wang            Fragment hostFragment, TreeSet<Long> contactIds) {
96d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        if (contactIds == null) {
97d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            return null;
98d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        }
99d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell
100587b8f22be5f0e0a7e0b7ea362d81632e4bada66Wenyi Wang        final FragmentManager fragmentManager = hostFragment.getFragmentManager();
101d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        ContactMultiDeletionInteraction fragment =
102d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell                (ContactMultiDeletionInteraction) fragmentManager.findFragmentByTag(FRAGMENT_TAG);
103d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        if (fragment == null) {
104d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            fragment = new ContactMultiDeletionInteraction();
105d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            fragment.setContactIds(contactIds);
106d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            fragmentManager.beginTransaction().add(fragment, FRAGMENT_TAG)
107d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell                    .commitAllowingStateLoss();
108d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        } else {
109d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            fragment.setContactIds(contactIds);
110d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        }
111d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        return fragment;
112d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    }
113d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell
114d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    @Override
115d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    public void onAttach(Activity activity) {
116d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        super.onAttach(activity);
117d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        mContext = activity;
118d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    }
119d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell
120d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    @Override
121d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    public void onDestroyView() {
122d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        super.onDestroyView();
123d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        if (mDialog != null && mDialog.isShowing()) {
124d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            mDialog.setOnDismissListener(null);
125d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            mDialog.dismiss();
126d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            mDialog = null;
127d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        }
128d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    }
129d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell
130d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    public void setContactIds(TreeSet<Long> contactIds) {
131d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        mContactIds = contactIds;
132d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        mIsLoaderActive = true;
133d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        if (isStarted()) {
134d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            Bundle args = new Bundle();
135d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            args.putSerializable(ARG_CONTACT_IDS, mContactIds);
136d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            getLoaderManager().restartLoader(R.id.dialog_delete_multiple_contact_loader_id,
137d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell                    args, this);
138d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        }
139d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    }
140d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell
141d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    private boolean isStarted() {
142d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        return isAdded();
143d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    }
144d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell
145d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    @Override
146d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    public void onStart() {
147d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        if (mIsLoaderActive) {
148d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            Bundle args = new Bundle();
149d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            args.putSerializable(ARG_CONTACT_IDS, mContactIds);
150d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            getLoaderManager().initLoader(
151d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell                    R.id.dialog_delete_multiple_contact_loader_id, args, this);
152d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        }
153d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        super.onStart();
154d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    }
155d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell
156d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    @Override
157d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    public void onStop() {
158d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        super.onStop();
159d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        if (mDialog != null) {
160d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            mDialog.hide();
161d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        }
162d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    }
163d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell
164d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    @Override
165d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
166d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        final TreeSet<Long> contactIds = (TreeSet<Long>) args.getSerializable(ARG_CONTACT_IDS);
167d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        final Object[] parameterObject = contactIds.toArray();
168d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        final String[] parameters = new String[contactIds.size()];
169d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell
170d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        final StringBuilder builder = new StringBuilder();
171d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        for (int i = 0; i < contactIds.size(); i++) {
172d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            parameters[i] = String.valueOf(parameterObject[i]);
173d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            builder.append(RawContacts.CONTACT_ID + " =?");
174d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            if (i == contactIds.size() -1) {
175d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell                break;
176d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            }
177d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            builder.append(" OR ");
178d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        }
179d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        return new CursorLoader(mContext, RawContacts.CONTENT_URI, RAW_CONTACT_PROJECTION,
180d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell                builder.toString(), parameters, null);
181d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    }
182d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell
183d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    @Override
184d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
185d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        if (mDialog != null) {
186d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            mDialog.dismiss();
187d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            mDialog = null;
188d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        }
189d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell
190d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        if (!mIsLoaderActive) {
191d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            return;
192d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        }
193d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell
194d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        if (cursor == null || cursor.isClosed()) {
195d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            Log.e(TAG, "Failed to load contacts");
196d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            return;
197d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        }
198d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell
199d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        // This cursor may contain duplicate raw contacts, so we need to de-dupe them first
200d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        final HashSet<Long> readOnlyRawContacts = Sets.newHashSet();
201d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        final HashSet<Long> writableRawContacts = Sets.newHashSet();
202d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        final HashSet<Long> contactIds = Sets.newHashSet();
203e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey        final HashSet<String> names = Sets.newHashSet();
204e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey
205e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey        final ContactsPreferences contactsPreferences = new ContactsPreferences(mContext);
206d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell
207d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        AccountTypeManager accountTypes = AccountTypeManager.getInstance(getActivity());
208d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        cursor.moveToPosition(-1);
209d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        while (cursor.moveToNext()) {
210d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            final long rawContactId = cursor.getLong(COLUMN_INDEX_RAW_CONTACT_ID);
211d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            final String accountType = cursor.getString(COLUMN_INDEX_ACCOUNT_TYPE);
212d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            final String dataSet = cursor.getString(COLUMN_INDEX_DATA_SET);
213d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            final long contactId = cursor.getLong(COLUMN_INDEX_CONTACT_ID);
214e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey            final String displayName = cursor.getString(COLUMN_INDEX_DISPLAY_NAME);
215e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey            final String displayNameAlt = cursor.getString(COLUMN_INDEX_DISPLAY_NAME_ALT);
216e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey
217f62b488f4f88a00aa932866e2a355f10aa0bc030James Laskey            final String name = ContactDisplayUtils.getPreferredDisplayName(displayName,
218f62b488f4f88a00aa932866e2a355f10aa0bc030James Laskey                    displayNameAlt, contactsPreferences);
219f62b488f4f88a00aa932866e2a355f10aa0bc030James Laskey            if (!TextUtils.isEmpty(name)) {
220f62b488f4f88a00aa932866e2a355f10aa0bc030James Laskey                names.add(name);
221f62b488f4f88a00aa932866e2a355f10aa0bc030James Laskey            }
222e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey
223d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            contactIds.add(contactId);
224d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            final AccountType type = accountTypes.getAccountType(accountType, dataSet);
225d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            boolean writable = type == null || type.areContactsWritable();
226d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            if (writable) {
227d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell                writableRawContacts.add(rawContactId);
228d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            } else {
229d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell                readOnlyRawContacts.add(rawContactId);
230d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            }
231d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        }
232d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell
233d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        final int readOnlyCount = readOnlyRawContacts.size();
234d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        final int writableCount = writableRawContacts.size();
235d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell
236d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        final int messageId;
237168331d85c5be43a816eb24fd37a2ebdbe61ac53Tingting Wang        int positiveButtonId = android.R.string.ok;
238d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        if (readOnlyCount > 0 && writableCount > 0) {
239d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            messageId = R.string.batch_delete_multiple_accounts_confirmation;
240d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        } else if (readOnlyCount > 0 && writableCount == 0) {
241d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            messageId = R.string.batch_delete_read_only_contact_confirmation;
24207bc6766184d7c95724c549944633061b062d8efTingting Wang            positiveButtonId = R.string.readOnlyContactWarning_positive_button;
243168331d85c5be43a816eb24fd37a2ebdbe61ac53Tingting Wang        } else if (writableCount == 1) {
244168331d85c5be43a816eb24fd37a2ebdbe61ac53Tingting Wang            messageId = R.string.single_delete_confirmation;
245168331d85c5be43a816eb24fd37a2ebdbe61ac53Tingting Wang            positiveButtonId = R.string.deleteConfirmation_positive_button;
246d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        } else {
247d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            messageId = R.string.batch_delete_confirmation;
248168331d85c5be43a816eb24fd37a2ebdbe61ac53Tingting Wang            positiveButtonId = R.string.deleteConfirmation_positive_button;
249d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        }
250d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell
251d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        // Convert set of contact ids into a format that is easily parcellable and iterated upon
252d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        // for the sake of ContactSaveService.
253d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        final Long[] contactIdObjectArray = contactIds.toArray(new Long[contactIds.size()]);
254d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        final long[] contactIdArray = new long[contactIds.size()];
255d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        for (int i = 0; i < contactIds.size(); i++) {
256d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            contactIdArray[i] = contactIdObjectArray[i];
257d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        }
258d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell
259e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey        final String[] namesArray = names.toArray(new String[names.size()]);
260e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey        showDialog(messageId, positiveButtonId, contactIdArray, namesArray);
261d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell
262d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        // We don't want onLoadFinished() calls any more, which may come when the database is
263d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        // updating.
264d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        getLoaderManager().destroyLoader(R.id.dialog_delete_multiple_contact_loader_id);
265d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    }
266d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell
267d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    @Override
268d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    public void onLoaderReset(Loader<Cursor> loader) {
269d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    }
270d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell
271e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey    private void showDialog(int messageId, int positiveButtonId, final long[] contactIds,
272e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey            final String[] namesArray) {
273d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        mDialog = new AlertDialog.Builder(getActivity())
274d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell                .setIconAttribute(android.R.attr.alertDialogIcon)
275d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell                .setMessage(messageId)
276d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell                .setNegativeButton(android.R.string.cancel, null)
277168331d85c5be43a816eb24fd37a2ebdbe61ac53Tingting Wang                .setPositiveButton(positiveButtonId,
278d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell                    new DialogInterface.OnClickListener() {
279d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell                        @Override
280d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell                        public void onClick(DialogInterface dialog, int whichButton) {
281e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey                            doDeleteContact(contactIds, namesArray);
282d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell                        }
283d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell                    }
284d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell                )
285d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell                .create();
286d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell
287d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        mDialog.setOnDismissListener(new OnDismissListener() {
288d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            @Override
289d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            public void onDismiss(DialogInterface dialog) {
290d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell                mIsLoaderActive = false;
291d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell                mDialog = null;
292d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            }
293d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        });
294d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        mDialog.show();
295d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    }
296d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell
297d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    @Override
298d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    public void onSaveInstanceState(Bundle outState) {
299d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        super.onSaveInstanceState(outState);
300d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        outState.putBoolean(KEY_ACTIVE, mIsLoaderActive);
301d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        outState.putSerializable(KEY_CONTACTS_IDS, mContactIds);
302d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    }
303d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell
304d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    @Override
305d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    public void onActivityCreated(Bundle savedInstanceState) {
306d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        super.onActivityCreated(savedInstanceState);
307d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        if (savedInstanceState != null) {
308d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            mIsLoaderActive = savedInstanceState.getBoolean(KEY_ACTIVE);
309d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell            mContactIds = (TreeSet<Long>) savedInstanceState.getSerializable(KEY_CONTACTS_IDS);
310d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        }
311d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    }
312d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell
313e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey    protected void doDeleteContact(long[] contactIds, final String[] names) {
314d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell        mContext.startService(ContactSaveService.createDeleteMultipleContactsIntent(mContext,
315e5a140a1b60854a08a0ea0dc2068e9bf7cb058e6James Laskey                contactIds, names));
316cea82125731e5068782c6907483aaab2eba5bef6Walter Jang        mListener.onDeletionFinished();
317d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    }
318d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell
319587b8f22be5f0e0a7e0b7ea362d81632e4bada66Wenyi Wang    public void setListener(MultiContactDeleteListener listener) {
320587b8f22be5f0e0a7e0b7ea362d81632e4bada66Wenyi Wang        mListener = listener;
321d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell    }
322d2962a3bb669a381d31a586df3b906033a8fa571Brian Attwell}
323