From c412f94fb20db5cd177421e373fdf941e0135c81 Mon Sep 17 00:00:00 2001 From: Andrew Lee Date: Thu, 15 Oct 2015 10:45:19 -0700 Subject: Add import for SEND_TO_VOICEMAIL. + Add utility class for async import functions. + Move check for contacts with SEND_TO_VOICEMAIl to util. + Add function for adding phone numbers of contacts with SEND_TO_VOICEMAIL to the block list, then clearing the SEND_TO_VOICEMAIL flag. + Fixed bug where the import text would not be shown for an empty block list. Rearranged layouts slightly to facilitate this. + Protect against null listeners in FilteredNumberAsyncQueryHandler. Bug: 23351616 Change-Id: Id526e16f20a3d28966bbc5e458cecfcd03ecb20f --- .../database/FilteredNumberAsyncQueryHandler.java | 8 +- .../filterednumber/BlockedNumberFragment.java | 82 +++------- .../dialer/filterednumber/FilteredNumbersUtil.java | 181 +++++++++++++++++++++ 3 files changed, 214 insertions(+), 57 deletions(-) create mode 100644 src/com/android/dialer/filterednumber/FilteredNumbersUtil.java (limited to 'src') diff --git a/src/com/android/dialer/database/FilteredNumberAsyncQueryHandler.java b/src/com/android/dialer/database/FilteredNumberAsyncQueryHandler.java index c5d2f6f70..25613a6f8 100644 --- a/src/com/android/dialer/database/FilteredNumberAsyncQueryHandler.java +++ b/src/com/android/dialer/database/FilteredNumberAsyncQueryHandler.java @@ -202,7 +202,9 @@ public class FilteredNumberAsyncQueryHandler extends AsyncQueryHandler { new Listener() { @Override public void onInsertComplete(int token, Object cookie, Uri uri) { - listener.onBlockComplete(uri); + if (listener != null ) { + listener.onBlockComplete(uri); + } } }, getContentUri(null), values); } @@ -241,7 +243,9 @@ public class FilteredNumberAsyncQueryHandler extends AsyncQueryHandler { startDelete(NO_TOKEN, new Listener() { @Override public void onDeleteComplete(int token, Object cookie, int result) { - listener.onUnblockComplete(result, values); + if (listener != null) { + listener.onUnblockComplete(result, values); + } } }, uri, null, null); } diff --git a/src/com/android/dialer/filterednumber/BlockedNumberFragment.java b/src/com/android/dialer/filterednumber/BlockedNumberFragment.java index 5740305f7..60c35ab9b 100644 --- a/src/com/android/dialer/filterednumber/BlockedNumberFragment.java +++ b/src/com/android/dialer/filterednumber/BlockedNumberFragment.java @@ -21,45 +21,49 @@ import android.content.CursorLoader; import android.content.Intent; import android.content.Loader; import android.database.Cursor; -import android.os.AsyncTask; import android.os.Bundle; -import android.provider.ContactsContract.Contacts; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.android.dialer.R; import com.android.dialer.database.FilteredNumberContract; +import com.android.dialer.filterednumber.FilteredNumbersUtil.CheckForSendToVoicemailContactListener; +import com.android.dialer.filterednumber.FilteredNumbersUtil.ImportSendToVoicemailContactsListener; public class BlockedNumberFragment extends ListFragment implements LoaderManager.LoaderCallbacks, View.OnClickListener { - private static class SendToVoicemailContactQuery { - static final String[] PROJECTION = { - Contacts._ID - }; - - static final String SELECT_SEND_TO_VOICEMAIL_TRUE = Contacts.SEND_TO_VOICEMAIL + "=1"; - } - private BlockedNumberAdapter mAdapter; + private View mImportSettings; + private View mImportButton; @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - LayoutInflater inflater = LayoutInflater.from(getContext()); - getListView().addHeaderView(inflater.inflate(R.layout.blocked_number_header, null)); if (mAdapter == null) { mAdapter = new BlockedNumberAdapter(getContext()); } setListAdapter(mAdapter); getActivity().findViewById(R.id.add_number_button).setOnClickListener(this); - getListView().getEmptyView().findViewById(R.id.add_number_button).setOnClickListener(this); - mImportSettings = getActivity().findViewById(R.id.importsettings); + mImportSettings = getActivity().findViewById(R.id.import_settings); + mImportButton = getActivity().findViewById(R.id.import_button); + mImportButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + FilteredNumbersUtil.importSendToVoicemailContacts( + getActivity(), new ImportSendToVoicemailContactsListener() { + @Override + public void onImportComplete() { + mImportSettings.setVisibility(View.GONE); + } + }); + } + }); } @Override @@ -77,7 +81,15 @@ public class BlockedNumberFragment extends ListFragment implements @Override public void onResume() { super.onResume(); - checkForSendToVoicemailContact(); + + FilteredNumbersUtil.checkForSendToVoicemailContact( + getActivity(), new CheckForSendToVoicemailContactListener() { + @Override + public void onComplete(boolean hasSendToVoicemailContact) { + final int visibility = hasSendToVoicemailContact ? View.VISIBLE : View.GONE; + mImportSettings.setVisibility(visibility); + } + }); } @Override @@ -121,44 +133,4 @@ public class BlockedNumberFragment extends ListFragment implements manageBlockedNumbersActivity.enterSearchUi(); } } - - /** - * Checks if there exists a contact with {@code Contacts.SEND_TO_VOICEMAIL} set to true, - * and updates the visibility of the import settings buttons accordingly. - */ - private void checkForSendToVoicemailContact() { - final AsyncTask task = new AsyncTask() { - @Override - public Boolean doInBackground(Object[] params) { - if (getActivity() == null) { - return false; - } - - final Cursor cursor = getActivity().getContentResolver().query( - Contacts.CONTENT_URI, - SendToVoicemailContactQuery.PROJECTION, - SendToVoicemailContactQuery.SELECT_SEND_TO_VOICEMAIL_TRUE, - null, - null); - - boolean hasSendToVoicemailContacts = false; - if (cursor != null) { - try { - hasSendToVoicemailContacts = cursor.getCount() > 0; - } finally { - cursor.close(); - } - } - - return hasSendToVoicemailContacts; - } - - @Override - public void onPostExecute(Boolean hasSendToVoicemailContact) { - final int visibility = hasSendToVoicemailContact ? View.VISIBLE : View.GONE; - mImportSettings.setVisibility(visibility); - } - }; - task.execute(); - } } diff --git a/src/com/android/dialer/filterednumber/FilteredNumbersUtil.java b/src/com/android/dialer/filterednumber/FilteredNumbersUtil.java new file mode 100644 index 000000000..56417e11d --- /dev/null +++ b/src/com/android/dialer/filterednumber/FilteredNumbersUtil.java @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.dialer.filterednumber; + +import android.content.Context; +import android.content.ContentValues; +import android.database.Cursor; +import android.os.AsyncTask; +import android.provider.ContactsContract.Data; +import android.provider.ContactsContract.CommonDataKinds.Phone; +import android.provider.ContactsContract.Contacts; +import android.text.TextUtils; +import android.widget.Toast; + +import java.util.LinkedList; +import java.util.List; + +import com.android.dialer.R; +import com.android.dialer.database.FilteredNumberAsyncQueryHandler; + +/** + * Utility to help with tasks related to importing filtered numbers, namely migrating the + * SEND_TO_VOICEMAIL from Contacts. + */ +public class FilteredNumbersUtil { + + public interface CheckForSendToVoicemailContactListener { + public void onComplete(boolean hasSendToVoicemailContact); + } + + public interface ImportSendToVoicemailContactsListener { + public void onImportComplete(); + } + + private static class ContactsQuery { + static final String[] PROJECTION = { + Contacts._ID + }; + + static final String SELECT_SEND_TO_VOICEMAIL_TRUE = Contacts.SEND_TO_VOICEMAIL + "=1"; + + static final int ID_COLUMN_INDEX = 0; + } + + private static class PhoneQuery { + static final String[] PROJECTION = { + Phone.NORMALIZED_NUMBER, + Phone.NUMBER + }; + + static final int NORMALIZED_NUMBER_COLUMN_INDEX = 0; + static final int NUMBER_COLUMN_INDEX = 1; + + static final String SELECT_SEND_TO_VOICEMAIL_TRUE = Contacts.SEND_TO_VOICEMAIL + "=1"; + } + + /** + * Checks if there exists a contact with {@code Contacts.SEND_TO_VOICEMAIL} set to true. + */ + public static void checkForSendToVoicemailContact( + final Context context, final CheckForSendToVoicemailContactListener listener) { + final AsyncTask task = new AsyncTask() { + @Override + public Boolean doInBackground(Object[] params) { + if (context == null) { + return false; + } + + final Cursor cursor = context.getContentResolver().query( + Contacts.CONTENT_URI, + ContactsQuery.PROJECTION, + ContactsQuery.SELECT_SEND_TO_VOICEMAIL_TRUE, + null, + null); + + boolean hasSendToVoicemailContacts = false; + if (cursor != null) { + try { + hasSendToVoicemailContacts = cursor.getCount() > 0; + } finally { + cursor.close(); + } + } + + return hasSendToVoicemailContacts; + } + + @Override + public void onPostExecute(Boolean hasSendToVoicemailContact) { + if (listener != null) { + listener.onComplete(hasSendToVoicemailContact); + } + } + }; + task.execute(); + } + + /** + * Blocks all the phone numbers of any contacts marked as SEND_TO_VOICEMAIL, then clears the + * SEND_TO_VOICEMAIL flag on those contacts. + */ + public static void importSendToVoicemailContacts( + final Context context, final ImportSendToVoicemailContactsListener listener) { + final FilteredNumberAsyncQueryHandler mFilteredNumberAsyncQueryHandler = + new FilteredNumberAsyncQueryHandler(context.getContentResolver()); + + final AsyncTask task = new AsyncTask() { + @Override + public Boolean doInBackground(Object[] params) { + if (context == null) { + return false; + } + + // Get the phone number of contacts marked as SEND_TO_VOICEMAIL. + final Cursor phoneCursor = context.getContentResolver().query( + Phone.CONTENT_URI, + PhoneQuery.PROJECTION, + PhoneQuery.SELECT_SEND_TO_VOICEMAIL_TRUE, + null, + null); + + if (phoneCursor == null) { + return false; + } + + try { + while (phoneCursor.moveToNext()) { + final String normalizedNumber = phoneCursor.getString( + PhoneQuery.NORMALIZED_NUMBER_COLUMN_INDEX); + final String number = phoneCursor.getString( + PhoneQuery.NUMBER_COLUMN_INDEX); + if (normalizedNumber != null) { + // Block the phone number of the contact. + mFilteredNumberAsyncQueryHandler.blockNumber( + null, normalizedNumber, number, null); + } + } + } finally { + phoneCursor.close(); + } + + // Clear SEND_TO_VOICEMAIL on all contacts. The setting has been imported to Dialer. + ContentValues newValues = new ContentValues(); + newValues.put(Contacts.SEND_TO_VOICEMAIL, 0); + context.getContentResolver().update( + Contacts.CONTENT_URI, + newValues, + ContactsQuery.SELECT_SEND_TO_VOICEMAIL_TRUE, + null); + + return true; + } + + @Override + public void onPostExecute(Boolean success) { + if (success) { + if (listener != null) { + listener.onImportComplete(); + } + } else if (context != null) { + String toastStr = context.getString(R.string.send_to_voicemail_import_failed); + Toast.makeText(context, toastStr, Toast.LENGTH_SHORT).show(); + } + } + }; + task.execute(); + } +} -- cgit v1.2.3