diff options
Diffstat (limited to 'src/com/android/dialer/compat/FilteredNumberCompat.java')
-rw-r--r-- | src/com/android/dialer/compat/FilteredNumberCompat.java | 393 |
1 files changed, 0 insertions, 393 deletions
diff --git a/src/com/android/dialer/compat/FilteredNumberCompat.java b/src/com/android/dialer/compat/FilteredNumberCompat.java deleted file mode 100644 index 8d8e9a2a5..000000000 --- a/src/com/android/dialer/compat/FilteredNumberCompat.java +++ /dev/null @@ -1,393 +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.compat; - -import com.google.common.base.MoreObjects; -import com.google.common.base.Preconditions; - -import android.app.FragmentManager; -import android.content.ContentResolver; -import android.content.ContentUris; -import android.content.ContentValues; -import android.content.Context; -import android.content.Intent; -import android.net.Uri; -import android.os.UserManager; -import android.preference.PreferenceManager; -import android.support.annotation.Nullable; -import android.telecom.TelecomManager; -import android.telephony.PhoneNumberUtils; -import android.util.Log; - -import com.android.contacts.common.compat.CompatUtils; -import com.android.contacts.common.compat.TelecomManagerUtil; -import com.android.contacts.common.testing.NeededForTesting; -import com.android.dialer.DialerApplication; -import com.android.dialer.database.FilteredNumberAsyncQueryHandler; -import com.android.dialer.database.FilteredNumberAsyncQueryHandler.OnCheckBlockedListener; -import com.android.dialer.database.FilteredNumberContract.FilteredNumber; -import com.android.dialer.database.FilteredNumberContract.FilteredNumberColumns; -import com.android.dialer.database.FilteredNumberContract.FilteredNumberSources; -import com.android.dialer.database.FilteredNumberContract.FilteredNumberTypes; -import com.android.dialer.filterednumber.BlockNumberDialogFragment; -import com.android.dialer.filterednumber.BlockNumberDialogFragment.Callback; -import com.android.dialer.filterednumber.BlockedNumbersMigrator; -import com.android.dialer.filterednumber.BlockedNumbersSettingsActivity; -import com.android.dialer.filterednumber.MigrateBlockedNumbersDialogFragment; -import com.android.dialerbind.ObjectFactory; - -import java.util.ArrayList; -import java.util.List; - -/** - * Compatibility class to encapsulate logic to switch between call blocking using - * {@link com.android.dialer.database.FilteredNumberContract} and using - * {@link android.provider.BlockedNumberContract}. This class should be used rather than explicitly - * referencing columns from either contract class in situations where both blocking solutions may be - * used. - */ -public class FilteredNumberCompat { - - private static final String TAG = "FilteredNumberCompat"; - - protected static final String HAS_MIGRATED_TO_NEW_BLOCKING_KEY = "migratedToNewBlocking"; - - private static Boolean isEnabledForTest; - - private static Context contextForTest; - - /** - * @return The column name for ID in the filtered number database. - */ - public static String getIdColumnName() { - return useNewFiltering() ? BlockedNumbersSdkCompat._ID : FilteredNumberColumns._ID; - } - - /** - * @return The column name for type in the filtered number database. Will be {@code null} for - * the framework blocking implementation. - */ - @Nullable - public static String getTypeColumnName() { - return useNewFiltering() ? null : FilteredNumberColumns.TYPE; - } - - /** - * @return The column name for source in the filtered number database. Will be {@code null} for - * the framework blocking implementation - */ - @Nullable - public static String getSourceColumnName() { - return useNewFiltering() ? null : FilteredNumberColumns.SOURCE; - } - - /** - * @return The column name for the original number in the filtered number database. - */ - public static String getOriginalNumberColumnName() { - return useNewFiltering() ? BlockedNumbersSdkCompat.COLUMN_ORIGINAL_NUMBER - : FilteredNumberColumns.NUMBER; - } - - /** - * @return The column name for country iso in the filtered number database. Will be {@code null} - * the framework blocking implementation - */ - @Nullable - public static String getCountryIsoColumnName() { - return useNewFiltering() ? null : FilteredNumberColumns.COUNTRY_ISO; - } - - /** - * @return The column name for the e164 formatted number in the filtered number database. - */ - public static String getE164NumberColumnName() { - return useNewFiltering() ? BlockedNumbersSdkCompat.E164_NUMBER - : FilteredNumberColumns.NORMALIZED_NUMBER; - } - - /** - * @return {@code true} if the current SDK version supports using new filtering, {@code false} - * otherwise. - */ - public static boolean canUseNewFiltering() { - if (isEnabledForTest != null) { - return CompatUtils.isNCompatible() && isEnabledForTest; - } - return CompatUtils.isNCompatible() && ObjectFactory - .isNewBlockingEnabled(DialerApplication.getContext()); - } - - /** - * @return {@code true} if the new filtering should be used, i.e. it's enabled and any necessary - * migration has been performed, {@code false} otherwise. - */ - public static boolean useNewFiltering() { - return canUseNewFiltering() && hasMigratedToNewBlocking(); - } - - /** - * @return {@code true} if the user has migrated to use - * {@link android.provider.BlockedNumberContract} blocking, {@code false} otherwise. - */ - public static boolean hasMigratedToNewBlocking() { - return PreferenceManager.getDefaultSharedPreferences(DialerApplication.getContext()) - .getBoolean(HAS_MIGRATED_TO_NEW_BLOCKING_KEY, false); - } - - /** - * Called to inform this class whether the user has fully migrated to use - * {@link android.provider.BlockedNumberContract} blocking or not. - * - * @param hasMigrated {@code true} if the user has migrated, {@code false} otherwise. - */ - @NeededForTesting - public static void setHasMigratedToNewBlocking(boolean hasMigrated) { - PreferenceManager.getDefaultSharedPreferences( - MoreObjects.firstNonNull(contextForTest, DialerApplication.getContext())).edit() - .putBoolean(HAS_MIGRATED_TO_NEW_BLOCKING_KEY, hasMigrated).apply(); - } - - @NeededForTesting - public static void setIsEnabledForTest(Boolean isEnabled) { - isEnabledForTest = isEnabled; - } - - @NeededForTesting - public static void setContextForTest(Context context) { - contextForTest = context; - } - - /** - * Gets the content {@link Uri} for number filtering. - * - * @param id The optional id to append with the base content uri. - * @return The Uri for number filtering. - */ - public static Uri getContentUri(@Nullable Integer id) { - if (id == null) { - return getBaseUri(); - } - return ContentUris.withAppendedId(getBaseUri(), id); - } - - - private static Uri getBaseUri() { - return useNewFiltering() ? BlockedNumbersSdkCompat.CONTENT_URI : FilteredNumber.CONTENT_URI; - } - - /** - * Removes any null column names from the given projection array. This method is intended to be - * used to strip out any column names that aren't available in every version of number blocking. - * Example: - * {@literal - * getContext().getContentResolver().query( - * someUri, - * // Filtering ensures that no non-existant columns are queried - * FilteredNumberCompat.filter(new String[] {FilteredNumberCompat.getIdColumnName(), - * FilteredNumberCompat.getTypeColumnName()}, - * FilteredNumberCompat.getE164NumberColumnName() + " = ?", - * new String[] {e164Number}); - * } - * - * @param projection The projection array. - * @return The filtered projection array. - */ - @Nullable - public static String[] filter(@Nullable String[] projection) { - if (projection == null) { - return null; - } - List<String> filtered = new ArrayList<>(); - for (String column : projection) { - if (column != null) { - filtered.add(column); - } - } - return filtered.toArray(new String[filtered.size()]); - } - - /** - * Creates a new {@link ContentValues} suitable for inserting in the filtered number table. - * - * @param number The unformatted number to insert. - * @param e164Number (optional) The number to insert formatted to E164 standard. - * @param countryIso (optional) The country iso to use to format the number. - * @return The ContentValues to insert. - * @throws NullPointerException If number is null. - */ - public static ContentValues newBlockNumberContentValues(String number, - @Nullable String e164Number, @Nullable String countryIso) { - ContentValues contentValues = new ContentValues(); - contentValues.put(getOriginalNumberColumnName(), Preconditions.checkNotNull(number)); - if (!useNewFiltering()) { - if (e164Number == null) { - e164Number = PhoneNumberUtils.formatNumberToE164(number, countryIso); - } - contentValues.put(getE164NumberColumnName(), e164Number); - contentValues.put(getCountryIsoColumnName(), countryIso); - contentValues.put(getTypeColumnName(), FilteredNumberTypes.BLOCKED_NUMBER); - contentValues.put(getSourceColumnName(), FilteredNumberSources.USER); - } - return contentValues; - } - - /** - * Shows block number migration dialog if necessary. - * - * @param fragmentManager The {@link FragmentManager} used to show fragments. - * @param listener The {@link BlockedNumbersMigrator.Listener} to call when migration is - * complete. - * @return boolean True if migration dialog is shown. - */ - public static boolean maybeShowBlockNumberMigrationDialog( - ContentResolver contentResolver, FragmentManager fragmentManager, - BlockedNumbersMigrator.Listener listener) { - if (shouldShowMigrationDialog(true)) { - Log.i(TAG, "maybeShowBlockNumberMigrationDialog - showing migration dialog"); - MigrateBlockedNumbersDialogFragment - .newInstance(new BlockedNumbersMigrator(contentResolver), listener) - .show(fragmentManager, "MigrateBlockedNumbers"); - return true; - } - return false; - } - - /** - * Shows the flow of {@link android.app.DialogFragment}s for blocking or unblocking numbers. - * - * @param blockId The id into the blocked numbers database. - * @param number The number to block or unblock. - * @param countryIso The countryIso used to format the given number. - * @param displayNumber The form of the number to block, suitable for displaying. - * @param parentViewId The id for the containing view of the Dialog. - * @param fragmentManager The {@link FragmentManager} used to show fragments. - * @param callback (optional) The {@link Callback} to call when the block or unblock operation - * is complete. - */ - public static void showBlockNumberDialogFlow(final ContentResolver contentResolver, - final Integer blockId, final String number, final String countryIso, - final String displayNumber, final Integer parentViewId, - final FragmentManager fragmentManager, @Nullable final Callback callback) { - Log.i(TAG, "showBlockNumberDialogFlow - start"); - // If the user is blocking a number and isn't using the framework solution when they - // should be, show the migration dialog - if (shouldShowMigrationDialog(blockId == null)) { - Log.i(TAG, "showBlockNumberDialogFlow - showing migration dialog"); - MigrateBlockedNumbersDialogFragment - .newInstance(new BlockedNumbersMigrator(contentResolver), newMigrationListener( - DialerApplication.getContext().getContentResolver(), number, countryIso, - displayNumber, parentViewId, fragmentManager, callback)) - .show(fragmentManager, "MigrateBlockedNumbers"); - return; - } - Log.i(TAG, "showBlockNumberDialogFlow - showing block number dialog"); - BlockNumberDialogFragment - .show(blockId, number, countryIso, displayNumber, parentViewId, fragmentManager, - callback); - } - - private static boolean shouldShowMigrationDialog(boolean isBlocking) { - return isBlocking && canUseNewFiltering() && !hasMigratedToNewBlocking(); - } - - private static BlockedNumbersMigrator.Listener newMigrationListener( - final ContentResolver contentResolver, final String number, final String countryIso, - final String displayNumber, final Integer parentViewId, - final FragmentManager fragmentManager, @Nullable final Callback callback) { - return new BlockedNumbersMigrator.Listener() { - @Override - public void onComplete() { - Log.i(TAG, "showBlockNumberDialogFlow - listener showing block number dialog"); - if (!hasMigratedToNewBlocking()) { - Log.i(TAG, "showBlockNumberDialogFlow - migration failed"); - return; - } - /* - * Edge case to cover here: if the user initiated the migration workflow with a - * number that's already blocked in the framework, don't show the block number - * dialog. Doing so would allow them to block the same number twice, causing a - * crash. - */ - new FilteredNumberAsyncQueryHandler(contentResolver).isBlockedNumber( - new OnCheckBlockedListener() { - @Override - public void onCheckComplete(Integer id) { - if (id != null) { - Log.i(TAG, - "showBlockNumberDialogFlow - number already blocked"); - return; - } - Log.i(TAG, "showBlockNumberDialogFlow - need to block number"); - BlockNumberDialogFragment - .show(null, number, countryIso, displayNumber, parentViewId, - fragmentManager, callback); - } - }, number, countryIso); - } - }; - } - - /** - * Creates the {@link Intent} which opens the blocked numbers management interface. - * - * @param context The {@link Context}. - * @return The intent. - */ - public static Intent createManageBlockedNumbersIntent(Context context) { - if (canUseNewFiltering() && hasMigratedToNewBlocking()) { - return TelecomManagerUtil.createManageBlockedNumbersIntent( - (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE)); - } - return new Intent(context, BlockedNumbersSettingsActivity.class); - } - - /** - * Method used to determine if block operations are possible. - * - * @param context The {@link Context}. - * @return {@code true} if the app and user can block numbers, {@code false} otherwise. - */ - public static boolean canAttemptBlockOperations(Context context) { - if (!CompatUtils.isNCompatible()) { - // Dialer blocking, must be primary user - return UserManagerCompat.isSystemUser( - (UserManager) context.getSystemService(Context.USER_SERVICE)); - } - - // Great Wall blocking, must be primary user and the default or system dialer - // TODO(maxwelb): check that we're the default or system Dialer - return BlockedNumbersSdkCompat.canCurrentUserBlockNumbers(context); - } - - /** - * Used to determine if the call blocking settings can be opened. - * - * @param context The {@link Context}. - * @return {@code true} if the current user can open the call blocking settings, {@code false} - * otherwise. - */ - public static boolean canCurrentUserOpenBlockSettings(Context context) { - if (!CompatUtils.isNCompatible()) { - // Dialer blocking, must be primary user - return UserManagerCompat.isSystemUser( - (UserManager) context.getSystemService(Context.USER_SERVICE)); - } - // BlockedNumberContract blocking, verify through Contract API - return BlockedNumbersSdkCompat.canCurrentUserBlockNumbers(context); - } -} |