diff options
Diffstat (limited to 'src/com/android/dialer/filterednumber')
11 files changed, 0 insertions, 1884 deletions
diff --git a/src/com/android/dialer/filterednumber/BlockNumberDialogFragment.java b/src/com/android/dialer/filterednumber/BlockNumberDialogFragment.java deleted file mode 100644 index 3c60a967b..000000000 --- a/src/com/android/dialer/filterednumber/BlockNumberDialogFragment.java +++ /dev/null @@ -1,320 +0,0 @@ -/* - * 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.app.AlertDialog; -import android.app.Dialog; -import android.app.DialogFragment; -import android.app.FragmentManager; -import android.content.ContentValues; -import android.content.Context; -import android.content.DialogInterface; -import android.net.Uri; -import android.os.Bundle; -import android.support.design.widget.Snackbar; -import android.text.TextUtils; -import android.view.View; -import android.widget.Toast; - -import com.android.contacts.common.util.ContactDisplayUtils; -import com.android.dialer.R; -import com.android.dialer.compat.FilteredNumberCompat; -import com.android.dialer.database.FilteredNumberAsyncQueryHandler; -import com.android.dialer.database.FilteredNumberAsyncQueryHandler.OnBlockNumberListener; -import com.android.dialer.database.FilteredNumberAsyncQueryHandler.OnUnblockNumberListener; -import com.android.dialer.voicemail.VisualVoicemailEnabledChecker; -import com.android.dialer.logging.InteractionEvent; -import com.android.dialer.logging.Logger; - -/** - * Fragment for confirming and enacting blocking/unblocking a number. Also invokes snackbar - * providing undo functionality. - */ -public class BlockNumberDialogFragment extends DialogFragment { - - /** - * Use a callback interface to update UI after success/undo. Favor this approach over other - * more standard paradigms because of the variety of scenarios in which the DialogFragment - * can be invoked (by an Activity, by a fragment, by an adapter, by an adapter list item). - * Because of this, we do NOT support retaining state on rotation, and will dismiss the dialog - * upon rotation instead. - */ - public interface Callback { - /** - * Called when a number is successfully added to the set of filtered numbers - */ - void onFilterNumberSuccess(); - - /** - * Called when a number is successfully removed from the set of filtered numbers - */ - void onUnfilterNumberSuccess(); - - /** - * Called when the action of filtering or unfiltering a number is undone - */ - void onChangeFilteredNumberUndo(); - } - - private static final String BLOCK_DIALOG_FRAGMENT = "BlockNumberDialog"; - - private static final String ARG_BLOCK_ID = "argBlockId"; - private static final String ARG_NUMBER = "argNumber"; - private static final String ARG_COUNTRY_ISO = "argCountryIso"; - private static final String ARG_DISPLAY_NUMBER = "argDisplayNumber"; - private static final String ARG_PARENT_VIEW_ID = "parentViewId"; - - private String mNumber; - private String mDisplayNumber; - private String mCountryIso; - - private FilteredNumberAsyncQueryHandler mHandler; - private View mParentView; - private VisualVoicemailEnabledChecker mVoicemailEnabledChecker; - private Callback mCallback; - - public static void show( - Integer blockId, - String number, - String countryIso, - String displayNumber, - Integer parentViewId, - FragmentManager fragmentManager, - Callback callback) { - final BlockNumberDialogFragment newFragment = BlockNumberDialogFragment.newInstance( - blockId, number, countryIso, displayNumber, parentViewId); - - newFragment.setCallback(callback); - newFragment.show(fragmentManager, BlockNumberDialogFragment.BLOCK_DIALOG_FRAGMENT); - } - - private static BlockNumberDialogFragment newInstance( - Integer blockId, - String number, - String countryIso, - String displayNumber, - Integer parentViewId) { - final BlockNumberDialogFragment fragment = new BlockNumberDialogFragment(); - final Bundle args = new Bundle(); - if (blockId != null) { - args.putInt(ARG_BLOCK_ID, blockId.intValue()); - } - if (parentViewId != null) { - args.putInt(ARG_PARENT_VIEW_ID, parentViewId.intValue()); - } - args.putString(ARG_NUMBER, number); - args.putString(ARG_COUNTRY_ISO, countryIso); - args.putString(ARG_DISPLAY_NUMBER, displayNumber); - fragment.setArguments(args); - return fragment; - } - - @Override - public Context getContext() { - return getActivity(); - } - - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - super.onCreateDialog(savedInstanceState); - final boolean isBlocked = getArguments().containsKey(ARG_BLOCK_ID); - - mNumber = getArguments().getString(ARG_NUMBER); - mDisplayNumber = getArguments().getString(ARG_DISPLAY_NUMBER); - mCountryIso = getArguments().getString(ARG_COUNTRY_ISO); - - if (TextUtils.isEmpty(mDisplayNumber)) { - mDisplayNumber = mNumber; - } - - mHandler = new FilteredNumberAsyncQueryHandler(getContext().getContentResolver()); - mVoicemailEnabledChecker = new VisualVoicemailEnabledChecker(getActivity(), null); - /** - * Choose not to update VoicemailEnabledChecker, as checks should already been done in - * all current use cases. - */ - mParentView = getActivity().findViewById(getArguments().getInt(ARG_PARENT_VIEW_ID)); - - CharSequence title; - String okText; - String message; - if (isBlocked) { - title = null; - okText = getString(R.string.unblock_number_ok); - message = ContactDisplayUtils.getTtsSpannedPhoneNumber(getResources(), - R.string.unblock_number_confirmation_title, - mDisplayNumber).toString(); - } else { - title = ContactDisplayUtils.getTtsSpannedPhoneNumber(getResources(), - R.string.block_number_confirmation_title, - mDisplayNumber); - okText = getString(R.string.block_number_ok); - if (FilteredNumberCompat.useNewFiltering()) { - message = getString(R.string.block_number_confirmation_message_new_filtering); - } else if (mVoicemailEnabledChecker.isVisualVoicemailEnabled()) { - message = getString(R.string.block_number_confirmation_message_vvm); - } else { - message = getString(R.string.block_number_confirmation_message_no_vvm); - } - } - - - AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()) - .setTitle(title) - .setMessage(message) - .setPositiveButton(okText, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - if (isBlocked) { - unblockNumber(); - } else { - blockNumber(); - } - } - }) - .setNegativeButton(android.R.string.cancel, null); - return builder.create(); - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - if (!FilteredNumbersUtil.canBlockNumber(getActivity(), mNumber, mCountryIso)) { - dismiss(); - Toast.makeText(getContext(), - ContactDisplayUtils.getTtsSpannedPhoneNumber( - getResources(), R.string.invalidNumber, mDisplayNumber), - Toast.LENGTH_SHORT).show(); - } - } - - @Override - public void onPause() { - // Dismiss on rotation. - dismiss(); - mCallback = null; - - super.onPause(); - } - - public void setCallback(Callback callback) { - mCallback = callback; - } - - private CharSequence getBlockedMessage() { - return ContactDisplayUtils.getTtsSpannedPhoneNumber(getResources(), - R.string.snackbar_number_blocked, mDisplayNumber); - } - - private CharSequence getUnblockedMessage() { - return ContactDisplayUtils.getTtsSpannedPhoneNumber(getResources(), - R.string.snackbar_number_unblocked, mDisplayNumber); - } - - private int getActionTextColor() { - return getContext().getResources().getColor(R.color.dialer_snackbar_action_text_color); - } - - private void blockNumber() { - final CharSequence message = getBlockedMessage(); - final CharSequence undoMessage = getUnblockedMessage(); - final Callback callback = mCallback; - final int actionTextColor = getActionTextColor(); - final Context context = getContext(); - - final OnUnblockNumberListener onUndoListener = new OnUnblockNumberListener() { - @Override - public void onUnblockComplete(int rows, ContentValues values) { - Snackbar.make(mParentView, undoMessage, Snackbar.LENGTH_LONG).show(); - if (callback != null) { - callback.onChangeFilteredNumberUndo(); - } - } - }; - - final OnBlockNumberListener onBlockNumberListener = new OnBlockNumberListener() { - @Override - public void onBlockComplete(final Uri uri) { - final View.OnClickListener undoListener = new View.OnClickListener() { - @Override - public void onClick(View view) { - // Delete the newly created row on 'undo'. - Logger.logInteraction(InteractionEvent.UNDO_BLOCK_NUMBER); - mHandler.unblock(onUndoListener, uri); - } - }; - - Snackbar.make(mParentView, message, Snackbar.LENGTH_LONG) - .setAction(R.string.block_number_undo, undoListener) - .setActionTextColor(actionTextColor) - .show(); - - if (callback != null) { - callback.onFilterNumberSuccess(); - } - - if (context != null && FilteredNumbersUtil.hasRecentEmergencyCall(context)) { - FilteredNumbersUtil.maybeNotifyCallBlockingDisabled(context); - } - } - }; - - mHandler.blockNumber( - onBlockNumberListener, - mNumber, - mCountryIso); - } - - private void unblockNumber() { - final CharSequence message = getUnblockedMessage(); - final CharSequence undoMessage = getBlockedMessage(); - final Callback callback = mCallback; - final int actionTextColor = getActionTextColor(); - - final OnBlockNumberListener onUndoListener = new OnBlockNumberListener() { - @Override - public void onBlockComplete(final Uri uri) { - Snackbar.make(mParentView, undoMessage, Snackbar.LENGTH_LONG).show(); - if (callback != null) { - callback.onChangeFilteredNumberUndo(); - } - } - }; - - mHandler.unblock(new OnUnblockNumberListener() { - @Override - public void onUnblockComplete(int rows, final ContentValues values) { - final View.OnClickListener undoListener = new View.OnClickListener() { - @Override - public void onClick(View view) { - // Re-insert the row on 'undo', with a new ID. - Logger.logInteraction(InteractionEvent.UNDO_UNBLOCK_NUMBER); - mHandler.blockNumber(onUndoListener, values); - } - }; - - Snackbar.make(mParentView, message, Snackbar.LENGTH_LONG) - .setAction(R.string.block_number_undo, undoListener) - .setActionTextColor(actionTextColor) - .show(); - - if (callback != null) { - callback.onUnfilterNumberSuccess(); - } - } - }, getArguments().getInt(ARG_BLOCK_ID)); - } -} diff --git a/src/com/android/dialer/filterednumber/BlockedNumbersAdapter.java b/src/com/android/dialer/filterednumber/BlockedNumbersAdapter.java deleted file mode 100644 index 10a4f5abd..000000000 --- a/src/com/android/dialer/filterednumber/BlockedNumbersAdapter.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * 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.app.FragmentManager; -import android.content.Context; -import android.database.Cursor; -import android.telephony.PhoneNumberUtils; -import android.view.View; - -import com.android.contacts.common.ContactPhotoManager; -import com.android.contacts.common.GeoUtil; -import com.android.dialer.R; -import com.android.dialer.calllog.ContactInfoHelper; -import com.android.dialer.database.FilteredNumberContract.FilteredNumberColumns; -import com.android.dialer.logging.InteractionEvent; -import com.android.dialer.logging.Logger; - -public class BlockedNumbersAdapter extends NumbersAdapter { - - private BlockedNumbersAdapter( - Context context, - FragmentManager fragmentManager, - ContactInfoHelper contactInfoHelper, - ContactPhotoManager contactPhotoManager) { - super(context, fragmentManager, contactInfoHelper, contactPhotoManager); - } - - public static BlockedNumbersAdapter newBlockedNumbersAdapter( - Context context, FragmentManager fragmentManager) { - return new BlockedNumbersAdapter( - context, - fragmentManager, - new ContactInfoHelper(context, GeoUtil.getCurrentCountryIso(context)), - ContactPhotoManager.getInstance(context)); - } - - @Override - public void bindView(View view, final Context context, Cursor cursor) { - super.bindView(view, context, cursor); - final Integer id = cursor.getInt(cursor.getColumnIndex(FilteredNumberColumns._ID)); - final String countryIso = cursor.getString(cursor.getColumnIndex( - FilteredNumberColumns.COUNTRY_ISO)); - final String number = cursor.getString(cursor.getColumnIndex(FilteredNumberColumns.NUMBER)); - final String normalizedNumber = cursor.getString(cursor.getColumnIndex( - FilteredNumberColumns.NORMALIZED_NUMBER)); - - final View deleteButton = view.findViewById(R.id.delete_button); - deleteButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - BlockNumberDialogFragment.show( - id, - number, - countryIso, - PhoneNumberUtils.formatNumber(number, countryIso), - R.id.blocked_numbers_activity_container, - getFragmentManager(), - new BlockNumberDialogFragment.Callback() { - @Override - public void onFilterNumberSuccess() {} - - @Override - public void onUnfilterNumberSuccess() { - Logger.logInteraction( - InteractionEvent.UNBLOCK_NUMBER_MANAGEMENT_SCREEN); - } - - @Override - public void onChangeFilteredNumberUndo() {} - }); - } - }); - - updateView(view, number, countryIso); - } - - @Override - public boolean isEmpty() { - // Always return false, so that the header with blocking-related options always shows. - return false; - } -} diff --git a/src/com/android/dialer/filterednumber/BlockedNumbersAutoMigrator.java b/src/com/android/dialer/filterednumber/BlockedNumbersAutoMigrator.java deleted file mode 100644 index ed0faabbe..000000000 --- a/src/com/android/dialer/filterednumber/BlockedNumbersAutoMigrator.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2016 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 com.google.common.base.Preconditions; - -import android.content.SharedPreferences; -import android.util.Log; - -import com.android.dialer.compat.FilteredNumberCompat; -import com.android.dialer.database.FilteredNumberAsyncQueryHandler; -import com.android.dialer.database.FilteredNumberAsyncQueryHandler.OnHasBlockedNumbersListener; - -/** - * Class responsible for checking if the user can be auto-migrated to {@link - * android.provider.BlockedNumberContract} blocking. In order for this to happen, the user cannot - * have any numbers that are blocked in the Dialer solution. - */ -public class BlockedNumbersAutoMigrator { - - private static final String TAG = "BlockedNumbersAuto"; - - private static final String HAS_CHECKED_AUTO_MIGRATE_KEY = "checkedAutoMigrate"; - - private final SharedPreferences sharedPreferences; - private final FilteredNumberAsyncQueryHandler queryHandler; - - /** - * Constructs the BlockedNumbersAutoMigrator with the given {@link SharedPreferences} and {@link - * FilteredNumberAsyncQueryHandler}. - * - * @param sharedPreferences The SharedPreferences used to persist information. - * @param queryHandler The FilteredNumberAsyncQueryHandler used to determine if there are - * blocked numbers. - * @throws NullPointerException if sharedPreferences or queryHandler are null. - */ - public BlockedNumbersAutoMigrator(SharedPreferences sharedPreferences, - FilteredNumberAsyncQueryHandler queryHandler) { - this.sharedPreferences = Preconditions.checkNotNull(sharedPreferences); - this.queryHandler = Preconditions.checkNotNull(queryHandler); - } - - /** - * Attempts to perform the auto-migration. Auto-migration will only be attempted once and can be - * performed only when the user has no blocked numbers. As a result of this method, the user - * will be migrated to the framework blocking solution, as determined by {@link - * FilteredNumberCompat#hasMigratedToNewBlocking()}. - */ - public void autoMigrate() { - if (!shouldAttemptAutoMigrate()) { - return; - } - - Log.i(TAG, "Attempting to auto-migrate."); - queryHandler.hasBlockedNumbers(new OnHasBlockedNumbersListener() { - @Override - public void onHasBlockedNumbers(boolean hasBlockedNumbers) { - if (hasBlockedNumbers) { - Log.i(TAG, "Not auto-migrating: blocked numbers exist."); - return; - } - Log.i(TAG, "Auto-migrating: no blocked numbers."); - FilteredNumberCompat.setHasMigratedToNewBlocking(true); - } - }); - } - - private boolean shouldAttemptAutoMigrate() { - if (sharedPreferences.contains(HAS_CHECKED_AUTO_MIGRATE_KEY)) { - Log.d(TAG, "Not attempting auto-migrate: already checked once."); - return false; - } - Log.i(TAG, "Updating state as already checked for auto-migrate."); - sharedPreferences.edit().putBoolean(HAS_CHECKED_AUTO_MIGRATE_KEY, true).apply(); - - if (!FilteredNumberCompat.canUseNewFiltering()) { - Log.i(TAG, "Not attempting auto-migrate: not available."); - return false; - } - - if (FilteredNumberCompat.hasMigratedToNewBlocking()) { - Log.i(TAG, "Not attempting auto-migrate: already migrated."); - return false; - } - return true; - } -} diff --git a/src/com/android/dialer/filterednumber/BlockedNumbersFragment.java b/src/com/android/dialer/filterednumber/BlockedNumbersFragment.java deleted file mode 100644 index b64f18691..000000000 --- a/src/com/android/dialer/filterednumber/BlockedNumbersFragment.java +++ /dev/null @@ -1,264 +0,0 @@ -/* - * 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 com.google.common.base.MoreObjects; - -import android.app.ListFragment; -import android.app.LoaderManager; -import android.content.Context; -import android.content.CursorLoader; -import android.content.Loader; -import android.database.Cursor; -import android.graphics.drawable.ColorDrawable; -import android.os.Bundle; -import android.support.v4.app.ActivityCompat; -import android.support.v7.app.ActionBar; -import android.support.v7.app.AppCompatActivity; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.TextView; - -import com.android.contacts.common.lettertiles.LetterTileDrawable; -import com.android.contacts.common.testing.NeededForTesting; -import com.android.dialer.R; -import com.android.dialer.compat.FilteredNumberCompat; -import com.android.dialer.database.FilteredNumberContract; -import com.android.dialer.filterednumber.BlockedNumbersMigrator.Listener; -import com.android.dialer.filterednumber.FilteredNumbersUtil.CheckForSendToVoicemailContactListener; -import com.android.dialer.filterednumber.FilteredNumbersUtil.ImportSendToVoicemailContactsListener; -import com.android.dialer.voicemail.VisualVoicemailEnabledChecker; - -public class BlockedNumbersFragment extends ListFragment - implements LoaderManager.LoaderCallbacks<Cursor>, View.OnClickListener, - VisualVoicemailEnabledChecker.Callback { - private static final char ADD_BLOCKED_NUMBER_ICON_LETTER = '+'; - - private BlockedNumbersMigrator blockedNumbersMigratorForTest; - protected View migratePromoView; - private TextView blockedNumbersText; - private TextView footerText; - private BlockedNumbersAdapter mAdapter; - private VisualVoicemailEnabledChecker mVoicemailEnabledChecker; - private View mImportSettings; - private View mBlockedNumbersDisabledForEmergency; - private View mBlockedNumberListDivider; - - @Override - public Context getContext() { - return getActivity(); - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - - LayoutInflater inflater = - (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); - getListView().addHeaderView(inflater.inflate(R.layout.blocked_number_header, null)); - getListView().addFooterView(inflater.inflate(R.layout.blocked_number_footer, null)); - //replace the icon for add number with LetterTileDrawable(), so it will have identical style - ImageView addNumberIcon = (ImageView) getActivity().findViewById(R.id.add_number_icon); - LetterTileDrawable drawable = new LetterTileDrawable(getResources()); - drawable.setLetter(ADD_BLOCKED_NUMBER_ICON_LETTER); - drawable.setColor(ActivityCompat.getColor(getActivity(), - R.color.add_blocked_number_icon_color)); - drawable.setIsCircular(true); - addNumberIcon.setImageDrawable(drawable); - - if (mAdapter == null) { - mAdapter = BlockedNumbersAdapter.newBlockedNumbersAdapter( - getContext(), getActivity().getFragmentManager()); - } - setListAdapter(mAdapter); - - blockedNumbersText = (TextView) getListView().findViewById(R.id.blocked_number_text_view); - migratePromoView = getListView().findViewById(R.id.migrate_promo); - getListView().findViewById(R.id.migrate_promo_allow_button).setOnClickListener(this); - mImportSettings = getListView().findViewById(R.id.import_settings); - mBlockedNumbersDisabledForEmergency = - getListView().findViewById(R.id.blocked_numbers_disabled_for_emergency); - mBlockedNumberListDivider = getActivity().findViewById(R.id.blocked_number_list_divider); - getListView().findViewById(R.id.import_button).setOnClickListener(this); - getListView().findViewById(R.id.view_numbers_button).setOnClickListener(this); - getListView().findViewById(R.id.add_number_linear_layout).setOnClickListener(this); - - footerText = (TextView) getActivity().findViewById( - R.id.blocked_number_footer_textview); - mVoicemailEnabledChecker = new VisualVoicemailEnabledChecker(getContext(),this); - mVoicemailEnabledChecker.asyncUpdate(); - updateActiveVoicemailProvider(); - } - - @Override - public void onDestroy() { - setListAdapter(null); - super.onDestroy(); - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - getLoaderManager().initLoader(0, null, this); - } - - @Override - public void onResume() { - super.onResume(); - - ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar(); - ColorDrawable backgroundDrawable = new ColorDrawable( - ActivityCompat.getColor(getActivity(), R.color.dialer_theme_color)); - actionBar.setBackgroundDrawable(backgroundDrawable); - actionBar.setDisplayShowCustomEnabled(false); - actionBar.setDisplayHomeAsUpEnabled(true); - actionBar.setDisplayShowHomeEnabled(true); - actionBar.setDisplayShowTitleEnabled(true); - actionBar.setTitle(R.string.manage_blocked_numbers_label); - - // If the device can use the framework blocking solution, users should not be able to add - // new blocked numbers from the Blocked Management UI. They will be shown a promo card - // asking them to migrate to new blocking instead. - if (FilteredNumberCompat.canUseNewFiltering()) { - migratePromoView.setVisibility(View.VISIBLE); - blockedNumbersText.setVisibility(View.GONE); - getListView().findViewById(R.id.add_number_linear_layout).setVisibility(View.GONE); - getListView().findViewById(R.id.add_number_linear_layout).setOnClickListener(null); - mBlockedNumberListDivider.setVisibility(View.GONE); - mImportSettings.setVisibility(View.GONE); - getListView().findViewById(R.id.import_button).setOnClickListener(null); - getListView().findViewById(R.id.view_numbers_button).setOnClickListener(null); - mBlockedNumbersDisabledForEmergency.setVisibility(View.GONE); - footerText.setVisibility(View.GONE); - } else { - FilteredNumbersUtil.checkForSendToVoicemailContact( - getActivity(), new CheckForSendToVoicemailContactListener() { - @Override - public void onComplete(boolean hasSendToVoicemailContact) { - final int visibility = - hasSendToVoicemailContact ? View.VISIBLE : View.GONE; - mImportSettings.setVisibility(visibility); - } - }); - } - - // All views except migrate and the block list are hidden when new filtering is available - if (!FilteredNumberCompat.canUseNewFiltering() - && FilteredNumbersUtil.hasRecentEmergencyCall(getContext())) { - mBlockedNumbersDisabledForEmergency.setVisibility(View.VISIBLE); - } else { - mBlockedNumbersDisabledForEmergency.setVisibility(View.GONE); - } - - mVoicemailEnabledChecker.asyncUpdate(); - } - - @Override - public View onCreateView( - LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - return inflater.inflate(R.layout.blocked_number_fragment, container, false); - } - - @Override - public Loader<Cursor> onCreateLoader(int id, Bundle args) { - final String[] projection = { - FilteredNumberContract.FilteredNumberColumns._ID, - FilteredNumberContract.FilteredNumberColumns.COUNTRY_ISO, - FilteredNumberContract.FilteredNumberColumns.NUMBER, - FilteredNumberContract.FilteredNumberColumns.NORMALIZED_NUMBER - }; - final String selection = FilteredNumberContract.FilteredNumberColumns.TYPE - + "=" + FilteredNumberContract.FilteredNumberTypes.BLOCKED_NUMBER; - return new CursorLoader( - getContext(), FilteredNumberContract.FilteredNumber.CONTENT_URI, projection, - selection, null, null); - } - - @Override - public void onLoadFinished(Loader<Cursor> loader, Cursor data) { - mAdapter.swapCursor(data); - if (FilteredNumberCompat.canUseNewFiltering() || data.getCount() == 0) { - mBlockedNumberListDivider.setVisibility(View.INVISIBLE); - } else { - mBlockedNumberListDivider.setVisibility(View.VISIBLE); - } - } - - @Override - public void onLoaderReset(Loader<Cursor> loader) { - mAdapter.swapCursor(null); - } - - @Override - public void onClick(final View view) { - final BlockedNumbersSettingsActivity activity = - (BlockedNumbersSettingsActivity) getActivity(); - if (activity == null) { - return; - } - - int resId = view.getId(); - if (resId == R.id.add_number_linear_layout) { - activity.showSearchUi(); - } else if (resId == R.id.view_numbers_button) { - activity.showNumbersToImportPreviewUi(); - } else if (resId == R.id.import_button) { - FilteredNumbersUtil.importSendToVoicemailContacts(activity, - new ImportSendToVoicemailContactsListener() { - @Override - public void onImportComplete() { - mImportSettings.setVisibility(View.GONE); - } - }); - } else if (resId == R.id.migrate_promo_allow_button) { - view.setEnabled(false); - MoreObjects.firstNonNull(blockedNumbersMigratorForTest, - new BlockedNumbersMigrator(getContext().getContentResolver())) - .migrate(new Listener() { - @Override - public void onComplete() { - getContext().startActivity( - FilteredNumberCompat.createManageBlockedNumbersIntent(getContext())); - // Remove this activity from the backstack - activity.finish(); - } - }); - } - } - - @Override - public void onVisualVoicemailEnabledStatusChanged(boolean newStatus){ - updateActiveVoicemailProvider(); - } - - private void updateActiveVoicemailProvider(){ - if (getActivity() == null || getActivity().isFinishing()) { - return; - } - if (mVoicemailEnabledChecker.isVisualVoicemailEnabled()) { - footerText.setText(R.string.block_number_footer_message_vvm); - } else { - footerText.setText(R.string.block_number_footer_message_no_vvm); - } - } - - @NeededForTesting - void setBlockedNumbersMigratorForTest(BlockedNumbersMigrator blockedNumbersMigrator) { - blockedNumbersMigratorForTest = blockedNumbersMigrator; - } -} diff --git a/src/com/android/dialer/filterednumber/BlockedNumbersMigrator.java b/src/com/android/dialer/filterednumber/BlockedNumbersMigrator.java deleted file mode 100644 index 373403046..000000000 --- a/src/com/android/dialer/filterednumber/BlockedNumbersMigrator.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * 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 com.google.common.base.Preconditions; - -import android.content.ContentResolver; -import android.content.ContentValues; -import android.database.Cursor; -import android.os.AsyncTask; - -import com.android.dialer.compat.BlockedNumbersSdkCompat; -import com.android.dialer.compat.FilteredNumberCompat; -import com.android.dialer.database.FilteredNumberContract; -import com.android.dialer.database.FilteredNumberContract.FilteredNumber; -import com.android.dialer.database.FilteredNumberContract.FilteredNumberColumns; -import com.android.incallui.Log; - -/** - * Class which should be used to migrate numbers from {@link FilteredNumberContract} blocking to - * {@link android.provider.BlockedNumberContract} blocking. - */ -public class BlockedNumbersMigrator { - - private static final String TAG = "BlockedNumbersMigrator"; - - /** - * Listener for the operation to migrate from {@link FilteredNumberContract} blocking to - * {@link android.provider.BlockedNumberContract} blocking. - */ - public interface Listener { - - /** - * Called when the migration operation is finished. - */ - void onComplete(); - } - - private final ContentResolver mContentResolver; - - /** - * Creates a new BlockedNumbersMigrate, using the given {@link ContentResolver} to perform - * queries against the blocked numbers tables. - * - * @param contentResolver The ContentResolver - * @throws NullPointerException if contentResolver is null - */ - public BlockedNumbersMigrator(ContentResolver contentResolver) { - mContentResolver = Preconditions.checkNotNull(contentResolver); - } - - /** - * Copies all of the numbers in the {@link FilteredNumberContract} block list to the - * {@link android.provider.BlockedNumberContract} block list. - * - * @param listener {@link Listener} called once the migration is complete. - * @return {@code true} if the migrate can be attempted, {@code false} otherwise. - * @throws NullPointerException if listener is null - */ - public boolean migrate(final Listener listener) { - Log.i(TAG, "migrate - start"); - if (!FilteredNumberCompat.canUseNewFiltering()) { - Log.i(TAG, "migrate - can't use new filtering"); - return false; - } - Preconditions.checkNotNull(listener); - new AsyncTask<Void, Void, Boolean>() { - @Override - protected Boolean doInBackground(Void... params) { - Log.i(TAG, "migrate - start background migration"); - return migrateToNewBlockingInBackground(mContentResolver); - } - - @Override - protected void onPostExecute(Boolean isSuccessful) { - Log.i(TAG, "migrate - marking migration complete"); - FilteredNumberCompat.setHasMigratedToNewBlocking(isSuccessful); - Log.i(TAG, "migrate - calling listener"); - listener.onComplete(); - } - }.execute(); - return true; - } - - private static boolean migrateToNewBlockingInBackground(ContentResolver resolver) { - try (Cursor cursor = resolver.query(FilteredNumber.CONTENT_URI, - new String[]{FilteredNumberColumns.NUMBER}, null, null, null)) { - if (cursor == null) { - Log.i(TAG, "migrate - cursor was null"); - return false; - } - - Log.i(TAG, "migrate - attempting to migrate " + cursor.getCount() + "numbers"); - - int numMigrated = 0; - while (cursor.moveToNext()) { - String originalNumber = cursor - .getString(cursor.getColumnIndex(FilteredNumberColumns.NUMBER)); - if (isNumberInNewBlocking(resolver, originalNumber)) { - Log.i(TAG, "migrate - number was already blocked in new blocking"); - continue; - } - ContentValues values = new ContentValues(); - values.put(BlockedNumbersSdkCompat.COLUMN_ORIGINAL_NUMBER, originalNumber); - resolver.insert(BlockedNumbersSdkCompat.CONTENT_URI, values); - ++numMigrated; - } - Log.i(TAG, "migrate - migration complete. " + numMigrated + " numbers migrated."); - return true; - } - } - - private static boolean isNumberInNewBlocking(ContentResolver resolver, String originalNumber) { - try (Cursor cursor = resolver.query(BlockedNumbersSdkCompat.CONTENT_URI, - new String[]{BlockedNumbersSdkCompat._ID}, - BlockedNumbersSdkCompat.COLUMN_ORIGINAL_NUMBER + " = ?", - new String[] {originalNumber}, null)) { - return cursor != null && cursor.getCount() != 0; - } - } -} diff --git a/src/com/android/dialer/filterednumber/BlockedNumbersSettingsActivity.java b/src/com/android/dialer/filterednumber/BlockedNumbersSettingsActivity.java deleted file mode 100644 index 5ce9d21f1..000000000 --- a/src/com/android/dialer/filterednumber/BlockedNumbersSettingsActivity.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * 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.support.v4.app.Fragment; -import android.support.v4.app.FragmentManager; -import android.content.Intent; -import android.net.Uri; -import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; -import android.util.Log; -import android.view.MenuItem; -import android.widget.FrameLayout; -import android.widget.FrameLayout.LayoutParams; -import android.widget.Toast; - -import com.android.contacts.common.GeoUtil; -import com.android.contacts.common.dialog.IndeterminateProgressDialog; -import com.android.contacts.common.list.OnPhoneNumberPickerActionListener; -import com.android.dialer.R; -import com.android.dialer.database.FilteredNumberAsyncQueryHandler; -import com.android.dialer.list.BlockedListSearchAdapter; -import com.android.dialer.list.OnListFragmentScrolledListener; -import com.android.dialer.list.BlockedListSearchFragment; -import com.android.dialer.list.SearchFragment; -import com.android.dialer.logging.Logger; -import com.android.dialer.logging.ScreenEvent; - -public class BlockedNumbersSettingsActivity extends AppCompatActivity - implements SearchFragment.HostInterface { - - private static final String TAG_BLOCKED_MANAGEMENT_FRAGMENT = "blocked_management"; - private static final String TAG_BLOCKED_SEARCH_FRAGMENT = "blocked_search"; - private static final String TAG_VIEW_NUMBERS_TO_IMPORT_FRAGMENT = "view_numbers_to_import"; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.blocked_numbers_activity); - - // If savedInstanceState != null, the Activity will automatically restore the last fragment. - if (savedInstanceState == null) { - showManagementUi(); - } - } - - /** - * Shows fragment with the list of currently blocked numbers and settings related to blocking. - */ - public void showManagementUi() { - BlockedNumbersFragment fragment = (BlockedNumbersFragment) getFragmentManager() - .findFragmentByTag(TAG_BLOCKED_MANAGEMENT_FRAGMENT); - if (fragment == null) { - fragment = new BlockedNumbersFragment(); - } - - getFragmentManager().beginTransaction() - .replace(R.id.blocked_numbers_activity_container, fragment, - TAG_BLOCKED_MANAGEMENT_FRAGMENT) - .commit(); - - Logger.logScreenView(ScreenEvent.BLOCKED_NUMBER_MANAGEMENT, this); - } - - /** - * Shows fragment with search UI for browsing/finding numbers to block. - */ - public void showSearchUi() { - BlockedListSearchFragment fragment = (BlockedListSearchFragment) getFragmentManager() - .findFragmentByTag(TAG_BLOCKED_SEARCH_FRAGMENT); - if (fragment == null) { - fragment = new BlockedListSearchFragment(); - fragment.setHasOptionsMenu(false); - fragment.setShowEmptyListForNullQuery(true); - fragment.setDirectorySearchEnabled(false); - } - - getFragmentManager().beginTransaction() - .replace(R.id.blocked_numbers_activity_container, fragment, - TAG_BLOCKED_SEARCH_FRAGMENT) - .addToBackStack(null) - .commit(); - - Logger.logScreenView(ScreenEvent.BLOCKED_NUMBER_ADD_NUMBER, this); - } - - /** - * Shows fragment with UI to preview the numbers of contacts currently marked as - * send-to-voicemail in Contacts. These numbers can be imported into Dialer's blocked number - * list. - */ - public void showNumbersToImportPreviewUi() { - ViewNumbersToImportFragment fragment = (ViewNumbersToImportFragment) getFragmentManager() - .findFragmentByTag(TAG_VIEW_NUMBERS_TO_IMPORT_FRAGMENT); - if (fragment == null) { - fragment = new ViewNumbersToImportFragment(); - } - - getFragmentManager().beginTransaction() - .replace(R.id.blocked_numbers_activity_container, fragment, - TAG_VIEW_NUMBERS_TO_IMPORT_FRAGMENT) - .addToBackStack(null) - .commit(); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if (item.getItemId() == android.R.id.home) { - onBackPressed(); - return true; - } - return false; - } - - @Override - public void onBackPressed() { - // TODO: Achieve back navigation without overriding onBackPressed. - if (getFragmentManager().getBackStackEntryCount() > 0) { - getFragmentManager().popBackStack(); - } else { - super.onBackPressed(); - } - } - - @Override - public boolean isActionBarShowing() { - return false; - } - - @Override - public boolean isDialpadShown() { - return false; - } - - @Override - public int getDialpadHeight() { - return 0; - } - - @Override - public int getActionBarHideOffset() { - return 0; - } - - @Override - public int getActionBarHeight() { - return 0; - } -} diff --git a/src/com/android/dialer/filterednumber/FilteredNumbersUtil.java b/src/com/android/dialer/filterednumber/FilteredNumbersUtil.java deleted file mode 100644 index 35d6f8d25..000000000 --- a/src/com/android/dialer/filterednumber/FilteredNumbersUtil.java +++ /dev/null @@ -1,369 +0,0 @@ -/* - * 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.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.content.ContentValues; -import android.content.Context; -import android.content.Intent; -import android.database.Cursor; -import android.os.AsyncTask; -import android.preference.PreferenceManager; -import android.provider.ContactsContract.CommonDataKinds.Phone; -import android.provider.ContactsContract.Contacts; -import android.provider.Settings; -import android.telephony.PhoneNumberUtils; -import android.text.TextUtils; -import android.widget.Toast; - -import com.android.contacts.common.testing.NeededForTesting; -import com.android.contacts.common.util.PermissionsUtil; -import com.android.dialer.R; -import com.android.dialer.compat.FilteredNumberCompat; -import com.android.dialer.database.FilteredNumberAsyncQueryHandler; -import com.android.dialer.database.FilteredNumberAsyncQueryHandler.OnHasBlockedNumbersListener; -import com.android.dialer.database.FilteredNumberContract.FilteredNumber; -import com.android.dialer.database.FilteredNumberContract.FilteredNumberColumns; -import com.android.dialer.logging.InteractionEvent; -import com.android.dialer.logging.Logger; - -import java.util.concurrent.TimeUnit; - -/** - * Utility to help with tasks related to filtered numbers. - */ -public class FilteredNumbersUtil { - - // Disable incoming call blocking if there was a call within the past 2 days. - private static final long RECENT_EMERGENCY_CALL_THRESHOLD_MS = 1000 * 60 * 60 * 24 * 2; - - // Pref key for storing the time of end of the last emergency call in milliseconds after epoch. - protected static final String LAST_EMERGENCY_CALL_MS_PREF_KEY = "last_emergency_call_ms"; - - // Pref key for storing whether a notification has been dispatched to notify the user that call - // blocking has been disabled because of a recent emergency call. - protected static final String NOTIFIED_CALL_BLOCKING_DISABLED_BY_EMERGENCY_CALL_PREF_KEY = - "notified_call_blocking_disabled_by_emergency_call"; - - public static final String CALL_BLOCKING_NOTIFICATION_TAG = "call_blocking"; - public static final int CALL_BLOCKING_DISABLED_BY_EMERGENCY_CALL_NOTIFICATION_ID = 10; - - /** - * Used for testing to specify that a custom threshold should be used instead of the default. - * This custom threshold will only be used when setting this log tag to VERBOSE: - * - * adb shell setprop log.tag.DebugEmergencyCall VERBOSE - * - */ - @NeededForTesting - private static final String DEBUG_EMERGENCY_CALL_TAG = "DebugEmergencyCall"; - - /** - * Used for testing to specify the custom threshold value, in milliseconds for whether an - * emergency call is "recent". The default value will be used if this custom threshold is less - * than zero. For example, to set this threshold to 60 seconds: - * - * adb shell settings put system dialer_emergency_call_threshold_ms 60000 - * - */ - @NeededForTesting - private static final String RECENT_EMERGENCY_CALL_THRESHOLD_SETTINGS_KEY = - "dialer_emergency_call_threshold_ms"; - - 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; - } - - public static class PhoneQuery { - static final String[] PROJECTION = { - Contacts._ID, - Phone.NORMALIZED_NUMBER, - Phone.NUMBER - }; - - static final int ID_COLUMN_INDEX = 0; - static final int NORMALIZED_NUMBER_COLUMN_INDEX = 1; - static final int NUMBER_COLUMN_INDEX = 2; - - 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<Object, Void, Boolean>() { - @Override - public Boolean doInBackground(Object[] params) { - if (context == null || !PermissionsUtil.hasContactsPermissions(context)) { - 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) { - Logger.logInteraction(InteractionEvent.IMPORT_SEND_TO_VOICEMAIL); - final FilteredNumberAsyncQueryHandler mFilteredNumberAsyncQueryHandler = - new FilteredNumberAsyncQueryHandler(context.getContentResolver()); - - final AsyncTask<Object, Void, Boolean> task = new AsyncTask<Object, Void, Boolean>() { - @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(); - } - - /** - * WARNING: This method should NOT be executed on the UI thread. - * Use {@code FilteredNumberAsyncQueryHandler} to asynchronously check if a number is blocked. - */ - public static boolean shouldBlockVoicemail( - Context context, String number, String countryIso, long voicemailDateMs) { - final String normalizedNumber = PhoneNumberUtils.formatNumberToE164(number, countryIso); - if (TextUtils.isEmpty(normalizedNumber)) { - return false; - } - - if (hasRecentEmergencyCall(context)) { - return false; - } - - final Cursor cursor = context.getContentResolver().query( - FilteredNumber.CONTENT_URI, - new String[] { - FilteredNumberColumns.CREATION_TIME - }, - FilteredNumberColumns.NORMALIZED_NUMBER + "=?", - new String[] { normalizedNumber }, - null); - if (cursor == null) { - return false; - } - try { - /* - * Block if number is found and it was added before this voicemail was received. - * The VVM's date is reported with precision to the minute, even though its - * magnitude is in milliseconds, so we perform the comparison in minutes. - */ - return cursor.moveToFirst() && - TimeUnit.MINUTES.convert(voicemailDateMs, TimeUnit.MILLISECONDS) >= - TimeUnit.MINUTES.convert(cursor.getLong(0), TimeUnit.MILLISECONDS); - } finally { - cursor.close(); - } - } - - public static boolean hasRecentEmergencyCall(Context context) { - if (context == null) { - return false; - } - - Long lastEmergencyCallTime = PreferenceManager.getDefaultSharedPreferences(context) - .getLong(LAST_EMERGENCY_CALL_MS_PREF_KEY, 0); - if (lastEmergencyCallTime == 0) { - return false; - } - - return (System.currentTimeMillis() - lastEmergencyCallTime) - < getRecentEmergencyCallThresholdMs(context); - } - - public static void recordLastEmergencyCallTime(Context context) { - if (context == null) { - return; - } - - PreferenceManager.getDefaultSharedPreferences(context) - .edit() - .putLong(LAST_EMERGENCY_CALL_MS_PREF_KEY, System.currentTimeMillis()) - .putBoolean(NOTIFIED_CALL_BLOCKING_DISABLED_BY_EMERGENCY_CALL_PREF_KEY, false) - .apply(); - - maybeNotifyCallBlockingDisabled(context); - } - - public static void maybeNotifyCallBlockingDisabled(final Context context) { - // The Dialer is not responsible for this notification after migrating - if (FilteredNumberCompat.useNewFiltering()) { - return; - } - // Skip if the user has already received a notification for the most recent emergency call. - if (PreferenceManager.getDefaultSharedPreferences(context) - .getBoolean(NOTIFIED_CALL_BLOCKING_DISABLED_BY_EMERGENCY_CALL_PREF_KEY, false)) { - return; - } - - // If the user has blocked numbers, notify that call blocking is temporarily disabled. - FilteredNumberAsyncQueryHandler queryHandler = - new FilteredNumberAsyncQueryHandler(context.getContentResolver()); - queryHandler.hasBlockedNumbers(new OnHasBlockedNumbersListener() { - @Override - public void onHasBlockedNumbers(boolean hasBlockedNumbers) { - if (context == null || !hasBlockedNumbers) { - return; - } - - NotificationManager notificationManager = (NotificationManager) - context.getSystemService(Context.NOTIFICATION_SERVICE); - Notification.Builder builder = new Notification.Builder(context) - .setSmallIcon(R.drawable.ic_block_24dp) - .setContentTitle(context.getString( - R.string.call_blocking_disabled_notification_title)) - .setContentText(context.getString( - R.string.call_blocking_disabled_notification_text)) - .setAutoCancel(true); - - final Intent contentIntent = - new Intent(context, BlockedNumbersSettingsActivity.class); - builder.setContentIntent(PendingIntent.getActivity( - context, 0, contentIntent, PendingIntent.FLAG_UPDATE_CURRENT)); - - notificationManager.notify( - CALL_BLOCKING_NOTIFICATION_TAG, - CALL_BLOCKING_DISABLED_BY_EMERGENCY_CALL_NOTIFICATION_ID, - builder.build()); - - // Record that the user has been notified for this emergency call. - PreferenceManager.getDefaultSharedPreferences(context) - .edit() - .putBoolean(NOTIFIED_CALL_BLOCKING_DISABLED_BY_EMERGENCY_CALL_PREF_KEY, true) - .apply(); - } - }); - } - - public static boolean canBlockNumber(Context context, String number, String countryIso) { - final String normalizedNumber = PhoneNumberUtils.formatNumberToE164(number, countryIso); - return !TextUtils.isEmpty(normalizedNumber) - && !PhoneNumberUtils.isEmergencyNumber(normalizedNumber); - } - - private static long getRecentEmergencyCallThresholdMs(Context context) { - if (android.util.Log.isLoggable( - DEBUG_EMERGENCY_CALL_TAG, android.util.Log.VERBOSE)) { - long thresholdMs = Settings.System.getLong( - context.getContentResolver(), - RECENT_EMERGENCY_CALL_THRESHOLD_SETTINGS_KEY, 0); - return thresholdMs > 0 ? thresholdMs : RECENT_EMERGENCY_CALL_THRESHOLD_MS; - } else { - return RECENT_EMERGENCY_CALL_THRESHOLD_MS; - } - } -} diff --git a/src/com/android/dialer/filterednumber/MigrateBlockedNumbersDialogFragment.java b/src/com/android/dialer/filterednumber/MigrateBlockedNumbersDialogFragment.java deleted file mode 100644 index 209665292..000000000 --- a/src/com/android/dialer/filterednumber/MigrateBlockedNumbersDialogFragment.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2016 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 com.google.common.base.Preconditions; - -import android.app.AlertDialog; -import android.app.Dialog; -import android.app.DialogFragment; -import android.content.DialogInterface; -import android.content.DialogInterface.OnShowListener; -import android.os.Bundle; -import android.view.View; -import com.android.dialer.R; -import com.android.dialer.filterednumber.BlockedNumbersMigrator.Listener; - -/** - * Dialog fragment shown to users when they need to migrate to use - * {@link android.provider.BlockedNumberContract} for blocking. - */ -public class MigrateBlockedNumbersDialogFragment extends DialogFragment { - - private BlockedNumbersMigrator mBlockedNumbersMigrator; - private BlockedNumbersMigrator.Listener mMigrationListener; - - /** - * Creates a new MigrateBlockedNumbersDialogFragment. - * - * @param blockedNumbersMigrator The {@link BlockedNumbersMigrator} which will be used to - * migrate the numbers. - * @param migrationListener The {@link BlockedNumbersMigrator.Listener} to call when the - * migration is complete. - * @return The new MigrateBlockedNumbersDialogFragment. - * @throws NullPointerException if blockedNumbersMigrator or migrationListener are {@code null}. - */ - public static DialogFragment newInstance(BlockedNumbersMigrator blockedNumbersMigrator, - BlockedNumbersMigrator.Listener migrationListener) { - MigrateBlockedNumbersDialogFragment fragment = new MigrateBlockedNumbersDialogFragment(); - fragment.mBlockedNumbersMigrator = Preconditions.checkNotNull(blockedNumbersMigrator); - fragment.mMigrationListener = Preconditions.checkNotNull(migrationListener); - return fragment; - } - - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - super.onCreateDialog(savedInstanceState); - AlertDialog dialog = new AlertDialog.Builder(getActivity()) - .setTitle(R.string.migrate_blocked_numbers_dialog_title) - .setMessage(R.string.migrate_blocked_numbers_dialog_message) - .setPositiveButton(R.string.migrate_blocked_numbers_dialog_allow_button, null) - .setNegativeButton(R.string.migrate_blocked_numbers_dialog_cancel_button, null) - .create(); - // The Dialog's buttons aren't available until show is called, so an OnShowListener - // is used to set the positive button callback. - dialog.setOnShowListener(new OnShowListener() { - @Override - public void onShow(DialogInterface dialog) { - final AlertDialog alertDialog = (AlertDialog) dialog; - alertDialog.getButton(AlertDialog.BUTTON_POSITIVE) - .setOnClickListener(newPositiveButtonOnClickListener(alertDialog)); - } - }); - return dialog; - } - - /* - * Creates a new View.OnClickListener to be used as the positive button in this dialog. The - * OnClickListener will grey out the dialog's positive and negative buttons while the migration - * is underway, and close the dialog once the migrate is complete. - */ - private View.OnClickListener newPositiveButtonOnClickListener(final AlertDialog alertDialog) { - return new View.OnClickListener() { - @Override - public void onClick(View v) { - alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false); - alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE).setEnabled(false); - mBlockedNumbersMigrator.migrate(new Listener() { - @Override - public void onComplete() { - alertDialog.dismiss(); - mMigrationListener.onComplete(); - } - }); - } - }; - } - - @Override - public void onPause() { - // The dialog is dismissed and state is cleaned up onPause, i.e. rotation. - dismiss(); - mBlockedNumbersMigrator = null; - mMigrationListener = null; - super.onPause(); - } -} diff --git a/src/com/android/dialer/filterednumber/NumbersAdapter.java b/src/com/android/dialer/filterednumber/NumbersAdapter.java deleted file mode 100644 index 17d5db343..000000000 --- a/src/com/android/dialer/filterednumber/NumbersAdapter.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * 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.app.FragmentManager; -import android.content.Context; -import android.provider.ContactsContract; -import android.provider.ContactsContract.CommonDataKinds.Phone; -import android.text.BidiFormatter; -import android.text.TextDirectionHeuristics; -import android.text.TextUtils; -import android.view.View; -import android.widget.QuickContactBadge; -import android.widget.SimpleCursorAdapter; -import android.widget.TextView; - -import com.android.contacts.common.ContactPhotoManager; -import com.android.contacts.common.ContactPhotoManager.DefaultImageRequest; -import com.android.contacts.common.compat.CompatUtils; -import com.android.contacts.common.util.UriUtils; -import com.android.dialer.R; -import com.android.dialer.calllog.ContactInfo; -import com.android.dialer.calllog.ContactInfoHelper; -import com.android.dialer.util.PhoneNumberUtil; - -public class NumbersAdapter extends SimpleCursorAdapter { - - private Context mContext; - private FragmentManager mFragmentManager; - private ContactInfoHelper mContactInfoHelper; - private BidiFormatter mBidiFormatter = BidiFormatter.getInstance(); - private ContactPhotoManager mContactPhotoManager; - - public NumbersAdapter( - Context context, - FragmentManager fragmentManager, - ContactInfoHelper contactInfoHelper, - ContactPhotoManager contactPhotoManager) { - super(context, R.layout.blocked_number_item, null, new String[]{}, new int[]{}, 0); - mContext = context; - mFragmentManager = fragmentManager; - mContactInfoHelper = contactInfoHelper; - mContactPhotoManager = contactPhotoManager; - } - - public void updateView(View view, String number, String countryIso) { - final TextView callerName = (TextView) view.findViewById(R.id.caller_name); - final TextView callerNumber = (TextView) view.findViewById(R.id.caller_number); - final QuickContactBadge quickContactBadge = - (QuickContactBadge) view.findViewById(R.id.quick_contact_photo); - quickContactBadge.setOverlay(null); - if (CompatUtils.hasPrioritizedMimeType()) { - quickContactBadge.setPrioritizedMimeType(Phone.CONTENT_ITEM_TYPE); - } - - ContactInfo info = mContactInfoHelper.lookupNumber(number, countryIso); - if (info == null) { - info = new ContactInfo(); - info.number = number; - } - final CharSequence locationOrType = getNumberTypeOrLocation(info); - final String displayNumber = getDisplayNumber(info); - final String displayNumberStr = mBidiFormatter.unicodeWrap(displayNumber, - TextDirectionHeuristics.LTR); - - String nameForDefaultImage; - if (!TextUtils.isEmpty(info.name)) { - nameForDefaultImage = info.name; - callerName.setText(info.name); - callerNumber.setText(locationOrType + " " + displayNumberStr); - } else { - nameForDefaultImage = displayNumber; - callerName.setText(displayNumberStr); - if (!TextUtils.isEmpty(locationOrType)) { - callerNumber.setText(locationOrType); - callerNumber.setVisibility(View.VISIBLE); - } else { - callerNumber.setVisibility(View.GONE); - } - } - loadContactPhoto(info, nameForDefaultImage, quickContactBadge); - } - - private void loadContactPhoto(ContactInfo info, String displayName, QuickContactBadge badge) { - final String lookupKey = info.lookupUri == null - ? null : UriUtils.getLookupKeyFromUri(info.lookupUri); - final int contactType = mContactInfoHelper.isBusiness(info.sourceType) - ? ContactPhotoManager.TYPE_BUSINESS : ContactPhotoManager.TYPE_DEFAULT; - final DefaultImageRequest request = new DefaultImageRequest(displayName, lookupKey, - contactType, true /* isCircular */); - badge.assignContactUri(info.lookupUri); - badge.setContentDescription( - mContext.getResources().getString(R.string.description_contact_details, displayName)); - mContactPhotoManager.loadDirectoryPhoto(badge, info.photoUri, - false /* darkTheme */, true /* isCircular */, request); - } - - private String getDisplayNumber(ContactInfo info) { - if (!TextUtils.isEmpty(info.formattedNumber)) { - return info.formattedNumber; - } else if (!TextUtils.isEmpty(info.number)) { - return info.number; - } else { - return ""; - } - } - - private CharSequence getNumberTypeOrLocation(ContactInfo info) { - if (!TextUtils.isEmpty(info.name)) { - return ContactsContract.CommonDataKinds.Phone.getTypeLabel( - mContext.getResources(), info.type, info.label); - } else { - return PhoneNumberUtil.getGeoDescription(mContext, info.number); - } - } - - protected Context getContext() { - return mContext; - } - - protected FragmentManager getFragmentManager() { - return mFragmentManager; - } -} diff --git a/src/com/android/dialer/filterednumber/ViewNumbersToImportAdapter.java b/src/com/android/dialer/filterednumber/ViewNumbersToImportAdapter.java deleted file mode 100644 index 58fe1d46c..000000000 --- a/src/com/android/dialer/filterednumber/ViewNumbersToImportAdapter.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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.app.FragmentManager; -import android.database.Cursor; -import android.content.Context; -import android.view.View; - -import com.android.contacts.common.ContactPhotoManager; -import com.android.contacts.common.GeoUtil; -import com.android.dialer.R; -import com.android.dialer.calllog.ContactInfoHelper; - -public class ViewNumbersToImportAdapter extends NumbersAdapter { - - private ViewNumbersToImportAdapter( - Context context, - FragmentManager fragmentManager, - ContactInfoHelper contactInfoHelper, - ContactPhotoManager contactPhotoManager) { - super(context, fragmentManager, contactInfoHelper, contactPhotoManager); - } - - public static ViewNumbersToImportAdapter newViewNumbersToImportAdapter( - Context context, FragmentManager fragmentManager) { - return new ViewNumbersToImportAdapter( - context, - fragmentManager, - new ContactInfoHelper(context, GeoUtil.getCurrentCountryIso(context)), - ContactPhotoManager.getInstance(context)); - } - - @Override - public void bindView(View view, Context context, Cursor cursor) { - super.bindView(view, context, cursor); - - final String number = cursor.getString( - FilteredNumbersUtil.PhoneQuery.NUMBER_COLUMN_INDEX); - - view.findViewById(R.id.delete_button).setVisibility(View.GONE); - updateView(view, number, null /* countryIso */); - } -} diff --git a/src/com/android/dialer/filterednumber/ViewNumbersToImportFragment.java b/src/com/android/dialer/filterednumber/ViewNumbersToImportFragment.java deleted file mode 100644 index 8b24c06da..000000000 --- a/src/com/android/dialer/filterednumber/ViewNumbersToImportFragment.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * 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.app.ListFragment; -import android.app.LoaderManager; -import android.content.Context; -import android.content.CursorLoader; -import android.content.Loader; -import android.database.Cursor; -import android.os.AsyncTask; -import android.os.Bundle; -import android.provider.ContactsContract.CommonDataKinds.Phone; -import android.provider.ContactsContract.Contacts; -import android.support.v7.app.ActionBar; -import android.support.v7.app.AppCompatActivity; -import android.text.TextUtils; -import android.util.Log; -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.ImportSendToVoicemailContactsListener; - -public class ViewNumbersToImportFragment extends ListFragment - implements LoaderManager.LoaderCallbacks<Cursor>, - View.OnClickListener { - - private ViewNumbersToImportAdapter mAdapter; - - @Override - public Context getContext() { - return getActivity(); - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - - if (mAdapter == null) { - mAdapter = ViewNumbersToImportAdapter.newViewNumbersToImportAdapter( - getContext(), getActivity().getFragmentManager()); - } - setListAdapter(mAdapter); - } - - @Override - public void onDestroy() { - setListAdapter(null); - super.onDestroy(); - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - getLoaderManager().initLoader(0, null, this); - } - - @Override - public void onResume() { - super.onResume(); - - ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar(); - actionBar.setTitle(R.string.import_send_to_voicemail_numbers_label); - actionBar.setDisplayShowCustomEnabled(false); - actionBar.setDisplayHomeAsUpEnabled(true); - actionBar.setDisplayShowHomeEnabled(true); - actionBar.setDisplayShowTitleEnabled(true); - - getActivity().findViewById(R.id.cancel_button).setOnClickListener(this); - getActivity().findViewById(R.id.import_button).setOnClickListener(this); - } - - @Override - public View onCreateView( - LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - return inflater.inflate(R.layout.view_numbers_to_import_fragment, container, false); - } - - @Override - public Loader<Cursor> onCreateLoader(int id, Bundle args) { - final CursorLoader cursorLoader = new CursorLoader( - getContext(), - Phone.CONTENT_URI, - FilteredNumbersUtil.PhoneQuery.PROJECTION, - FilteredNumbersUtil.PhoneQuery.SELECT_SEND_TO_VOICEMAIL_TRUE, - null, - null); - return cursorLoader; - } - - @Override - public void onLoadFinished(Loader<Cursor> loader, Cursor data) { - mAdapter.swapCursor(data); - } - - @Override - public void onLoaderReset(Loader<Cursor> loader) { - mAdapter.swapCursor(null); - } - - @Override - public void onClick(final View view) { - if (view.getId() == R.id.import_button) { - FilteredNumbersUtil.importSendToVoicemailContacts(getContext(), - new ImportSendToVoicemailContactsListener() { - @Override - public void onImportComplete() { - if (getActivity() != null) { - getActivity().onBackPressed(); - } - } - }); - } else if (view.getId() == R.id.cancel_button) { - getActivity().onBackPressed(); - } - } -} |