1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.dialer.filterednumber; 18 19 import com.google.common.base.Preconditions; 20 21 import android.content.ContentResolver; 22 import android.content.ContentValues; 23 import android.database.Cursor; 24 import android.os.AsyncTask; 25 26 import com.android.dialer.compat.BlockedNumbersSdkCompat; 27 import com.android.dialer.compat.FilteredNumberCompat; 28 import com.android.dialer.database.FilteredNumberContract; 29 import com.android.dialer.database.FilteredNumberContract.FilteredNumber; 30 import com.android.dialer.database.FilteredNumberContract.FilteredNumberColumns; 31 import com.android.incallui.Log; 32 33 /** 34 * Class which should be used to migrate numbers from {@link FilteredNumberContract} blocking to 35 * {@link android.provider.BlockedNumberContract} blocking. 36 */ 37 public class BlockedNumbersMigrator { 38 39 private static final String TAG = "BlockedNumbersMigrator"; 40 41 /** 42 * Listener for the operation to migrate from {@link FilteredNumberContract} blocking to 43 * {@link android.provider.BlockedNumberContract} blocking. 44 */ 45 public interface Listener { 46 47 /** 48 * Called when the migration operation is finished. 49 */ 50 void onComplete(); 51 } 52 53 private final ContentResolver mContentResolver; 54 55 /** 56 * Creates a new BlockedNumbersMigrate, using the given {@link ContentResolver} to perform 57 * queries against the blocked numbers tables. 58 * 59 * @param contentResolver The ContentResolver 60 * @throws NullPointerException if contentResolver is null 61 */ 62 public BlockedNumbersMigrator(ContentResolver contentResolver) { 63 mContentResolver = Preconditions.checkNotNull(contentResolver); 64 } 65 66 /** 67 * Copies all of the numbers in the {@link FilteredNumberContract} block list to the 68 * {@link android.provider.BlockedNumberContract} block list. 69 * 70 * @param listener {@link Listener} called once the migration is complete. 71 * @return {@code true} if the migrate can be attempted, {@code false} otherwise. 72 * @throws NullPointerException if listener is null 73 */ 74 public boolean migrate(final Listener listener) { 75 Log.i(TAG, "migrate - start"); 76 if (!FilteredNumberCompat.canUseNewFiltering()) { 77 Log.i(TAG, "migrate - can't use new filtering"); 78 return false; 79 } 80 Preconditions.checkNotNull(listener); 81 new AsyncTask<Void, Void, Boolean>() { 82 @Override 83 protected Boolean doInBackground(Void... params) { 84 Log.i(TAG, "migrate - start background migration"); 85 return migrateToNewBlockingInBackground(mContentResolver); 86 } 87 88 @Override 89 protected void onPostExecute(Boolean isSuccessful) { 90 Log.i(TAG, "migrate - marking migration complete"); 91 FilteredNumberCompat.setHasMigratedToNewBlocking(isSuccessful); 92 Log.i(TAG, "migrate - calling listener"); 93 listener.onComplete(); 94 } 95 }.execute(); 96 return true; 97 } 98 99 private static boolean migrateToNewBlockingInBackground(ContentResolver resolver) { 100 try (Cursor cursor = resolver.query(FilteredNumber.CONTENT_URI, 101 new String[]{FilteredNumberColumns.NUMBER}, null, null, null)) { 102 if (cursor == null) { 103 Log.i(TAG, "migrate - cursor was null"); 104 return false; 105 } 106 107 Log.i(TAG, "migrate - attempting to migrate " + cursor.getCount() + "numbers"); 108 109 int numMigrated = 0; 110 while (cursor.moveToNext()) { 111 String originalNumber = cursor 112 .getString(cursor.getColumnIndex(FilteredNumberColumns.NUMBER)); 113 if (isNumberInNewBlocking(resolver, originalNumber)) { 114 Log.i(TAG, "migrate - number was already blocked in new blocking"); 115 continue; 116 } 117 ContentValues values = new ContentValues(); 118 values.put(BlockedNumbersSdkCompat.COLUMN_ORIGINAL_NUMBER, originalNumber); 119 resolver.insert(BlockedNumbersSdkCompat.CONTENT_URI, values); 120 ++numMigrated; 121 } 122 Log.i(TAG, "migrate - migration complete. " + numMigrated + " numbers migrated."); 123 return true; 124 } 125 } 126 127 private static boolean isNumberInNewBlocking(ContentResolver resolver, String originalNumber) { 128 try (Cursor cursor = resolver.query(BlockedNumbersSdkCompat.CONTENT_URI, 129 new String[]{BlockedNumbersSdkCompat._ID}, 130 BlockedNumbersSdkCompat.COLUMN_ORIGINAL_NUMBER + " = ?", 131 new String[] {originalNumber}, null)) { 132 return cursor != null && cursor.getCount() != 0; 133 } 134 } 135 } 136