From 60fb1dc7afe8fe6079785724a21bbffbdb4eac88 Mon Sep 17 00:00:00 2001 From: Brandon Maxwell Date: Fri, 26 Feb 2016 16:59:46 -0800 Subject: Updating AsyncQueryHandler with FilteredNumCompat + FilteredNumberAsyncQueryHandler needs to make use of the FilteredNumberCompat class to unsure that it is blocking/unblocking/checking the proper solution, based on which is enabled. + This CL updates the queryHandler to the FilteredNumberCompat class for the hasBlockedNumbers, isBlockedNumber, and blockNumber operations. Bug=26664600 Change-Id: I5ecf6e340a97e94bf696a0e6c4a7e922b791a6f5 --- .../database/FilteredNumberAsyncQueryHandler.java | 66 ++++--- .../FilteredNumberAsyncQueryHandlerTest.java | 217 +++++++++++++++++---- 2 files changed, 208 insertions(+), 75 deletions(-) diff --git a/src/com/android/dialer/database/FilteredNumberAsyncQueryHandler.java b/src/com/android/dialer/database/FilteredNumberAsyncQueryHandler.java index 6e64c6098..7279911ce 100644 --- a/src/com/android/dialer/database/FilteredNumberAsyncQueryHandler.java +++ b/src/com/android/dialer/database/FilteredNumberAsyncQueryHandler.java @@ -24,12 +24,13 @@ import android.database.Cursor; import android.database.DatabaseUtils; import android.database.sqlite.SQLiteDatabaseCorruptException; import android.net.Uri; +import android.support.annotation.Nullable; import android.telephony.PhoneNumberUtils; import android.text.TextUtils; +import com.android.dialer.compat.FilteredNumberCompat; 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; public class FilteredNumberAsyncQueryHandler extends AsyncQueryHandler { @@ -58,7 +59,7 @@ public class FilteredNumberAsyncQueryHandler extends AsyncQueryHandler { * Invoked after querying if a number is blocked. * @param id The ID of the row if blocked, null otherwise. */ - public void onCheckComplete(Integer id); + void onCheckComplete(Integer id); } public interface OnBlockNumberListener { @@ -66,7 +67,7 @@ public class FilteredNumberAsyncQueryHandler extends AsyncQueryHandler { * Invoked after inserting a blocked number. * @param uri The uri of the newly created row. */ - public void onBlockComplete(Uri uri); + void onBlockComplete(Uri uri); } public interface OnUnblockNumberListener { @@ -75,7 +76,7 @@ public class FilteredNumberAsyncQueryHandler extends AsyncQueryHandler { * @param rows The number of rows affected (expected value 1). * @param values The deleted data (used for restoration). */ - public void onUnblockComplete(int rows, ContentValues values); + void onUnblockComplete(int rows, ContentValues values); } public interface OnHasBlockedNumbersListener { @@ -83,7 +84,7 @@ public class FilteredNumberAsyncQueryHandler extends AsyncQueryHandler { * @param hasBlockedNumbers {@code true} if any blocked numbers are stored. * {@code false} otherwise. */ - public void onHasBlockedNumbers(boolean hasBlockedNumbers); + void onHasBlockedNumbers(boolean hasBlockedNumbers); } @Override @@ -123,6 +124,10 @@ public class FilteredNumberAsyncQueryHandler extends AsyncQueryHandler { } public final void incrementFilteredCount(Integer id) { + // No concept of counts with new filtering + if (FilteredNumberCompat.useNewFiltering()) { + return; + } startUpdate(NO_TOKEN, null, ContentUris.withAppendedId(FilteredNumber.CONTENT_URI_INCREMENT_FILTERED_COUNT, id), null, null, null); @@ -136,9 +141,10 @@ public class FilteredNumberAsyncQueryHandler extends AsyncQueryHandler { listener.onHasBlockedNumbers(cursor != null && cursor.getCount() > 0); } }, - getContentUri(null), - new String[]{ FilteredNumberColumns._ID }, - FilteredNumberColumns.TYPE + "=" + FilteredNumberTypes.BLOCKED_NUMBER, + FilteredNumberCompat.getContentUri(null), + new String[]{ FilteredNumberCompat.getIdColumnName() }, + FilteredNumberCompat.useNewFiltering() ? null : FilteredNumberColumns.TYPE + + "=" + FilteredNumberTypes.BLOCKED_NUMBER, null, null); } @@ -151,8 +157,8 @@ public class FilteredNumberAsyncQueryHandler extends AsyncQueryHandler { */ public boolean isBlockedNumber( final OnCheckBlockedListener listener, String number, String countryIso) { - final String normalizedNumber = PhoneNumberUtils.formatNumberToE164(number, countryIso); - if (TextUtils.isEmpty(normalizedNumber)) { + final String e164Number = PhoneNumberUtils.formatNumberToE164(number, countryIso); + if (TextUtils.isEmpty(e164Number)) { return false; } @@ -165,7 +171,9 @@ public class FilteredNumberAsyncQueryHandler extends AsyncQueryHandler { return; } cursor.moveToFirst(); - if (cursor.getInt(cursor.getColumnIndex(FilteredNumberColumns.TYPE)) + // New filtering doesn't have a concept of type + if (!FilteredNumberCompat.useNewFiltering() + && cursor.getInt(cursor.getColumnIndex(FilteredNumberColumns.TYPE)) != FilteredNumberTypes.BLOCKED_NUMBER) { listener.onCheckComplete(null); return; @@ -174,17 +182,18 @@ public class FilteredNumberAsyncQueryHandler extends AsyncQueryHandler { cursor.getInt(cursor.getColumnIndex(FilteredNumberColumns._ID))); } }, - getContentUri(null), - new String[]{ FilteredNumberColumns._ID, FilteredNumberColumns.TYPE }, - FilteredNumberColumns.NORMALIZED_NUMBER + " = ?", - new String[]{ normalizedNumber }, + FilteredNumberCompat.getContentUri(null), + FilteredNumberCompat.filter(new String[]{FilteredNumberCompat.getIdColumnName(), + FilteredNumberCompat.getTypeColumnName()}), + FilteredNumberCompat.getE164NumberColumnName() + " = ?", + new String[]{e164Number}, null); return true; } public void blockNumber( - final OnBlockNumberListener listener, String number, String countryIso) { + final OnBlockNumberListener listener, String number, @Nullable String countryIso) { blockNumber(listener, null, number, countryIso); } @@ -193,19 +202,11 @@ public class FilteredNumberAsyncQueryHandler extends AsyncQueryHandler { */ public void blockNumber( final OnBlockNumberListener listener, - String normalizedNumber, + @Nullable String normalizedNumber, String number, - String countryIso) { - if (normalizedNumber == null) { - normalizedNumber = PhoneNumberUtils.formatNumberToE164(number, countryIso); - } - ContentValues v = new ContentValues(); - v.put(FilteredNumberColumns.NORMALIZED_NUMBER, normalizedNumber); - v.put(FilteredNumberColumns.NUMBER, number); - v.put(FilteredNumberColumns.COUNTRY_ISO, countryIso); - v.put(FilteredNumberColumns.TYPE, FilteredNumberTypes.BLOCKED_NUMBER); - v.put(FilteredNumberColumns.SOURCE, FilteredNumberSources.USER); - blockNumber(listener, v); + @Nullable String countryIso) { + blockNumber(listener, FilteredNumberCompat.newBlockNumberContentValues(number, + normalizedNumber, countryIso)); } /** @@ -221,13 +222,14 @@ public class FilteredNumberAsyncQueryHandler extends AsyncQueryHandler { listener.onBlockComplete(uri); } } - }, getContentUri(null), values); + }, FilteredNumberCompat.getContentUri(null), values); } /** - * Removes row from database. - * Caller should call {@link FilteredNumberAsyncQueryHandler#startBlockedQuery} first. - * @param id The ID of row to remove, from {@link FilteredNumberAsyncQueryHandler#startBlockedQuery}. + * Unblocks the number with the given id. + * + * @param listener The {@link OnUnblockNumberListener} called after the number is unblocked. + * @param id The id of the number to unblock. */ public void unblock(final OnUnblockNumberListener listener, Integer id) { if (id == null) { diff --git a/tests/src/com/android/dialer/database/FilteredNumberAsyncQueryHandlerTest.java b/tests/src/com/android/dialer/database/FilteredNumberAsyncQueryHandlerTest.java index 6bb478e2a..88f38fd62 100644 --- a/tests/src/com/android/dialer/database/FilteredNumberAsyncQueryHandlerTest.java +++ b/tests/src/com/android/dialer/database/FilteredNumberAsyncQueryHandlerTest.java @@ -18,11 +18,16 @@ package com.android.dialer.database; import android.content.ContentValues; import android.net.Uri; +import android.provider.BlockedNumberContract; +import android.provider.BlockedNumberContract.BlockedNumbers; import android.test.InstrumentationTestCase; import android.test.mock.MockContentResolver; +import android.test.suitebuilder.annotation.SmallTest; +import com.android.contacts.common.compat.CompatUtils; import com.android.contacts.common.test.mocks.MockContentProvider; import com.android.contacts.common.test.mocks.MockContentProvider.Query; +import com.android.dialer.compat.FilteredNumberCompat; import com.android.dialer.database.FilteredNumberAsyncQueryHandler.OnBlockNumberListener; import com.android.dialer.database.FilteredNumberAsyncQueryHandler.OnCheckBlockedListener; import com.android.dialer.database.FilteredNumberAsyncQueryHandler.OnHasBlockedNumbersListener; @@ -33,14 +38,19 @@ import com.android.dialer.database.FilteredNumberContract.FilteredNumberTypes; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +@SmallTest public class FilteredNumberAsyncQueryHandlerTest extends InstrumentationTestCase { private static final String E164_NUMBER = "+16502530000"; private static final String NUMBER = "6502530000"; private static final String COUNTRY_ISO = "US"; private static final Integer ID = 1; - private static final Uri BLOCKED_NUMBER_URI = + private static final Uri BLOCKED_NUMBER_URI_N = CompatUtils.isNCompatible() ? + Uri.withAppendedPath(BlockedNumberContract.AUTHORITY_URI, "blocked") : null; + private static final Uri BLOCKED_NUMBER_URI_M = Uri.withAppendedPath(FilteredNumberContract.AUTHORITY_URI, "filtered_numbers_table"); + private static final Uri BLOCKED_NUMBER_URI = CompatUtils.isNCompatible() ? BLOCKED_NUMBER_URI_N + : BLOCKED_NUMBER_URI_M; private static final Uri EXPECTED_URI = Uri.fromParts("android", "google", "dialer"); private final MockContentResolver mContentResolver = new MockContentResolver(); @@ -49,40 +59,39 @@ public class FilteredNumberAsyncQueryHandlerTest extends InstrumentationTestCase @Override public void setUp() throws Exception { super.setUp(); - mContentResolver.addProvider(FilteredNumberContract.AUTHORITY, mContentProvider); + FilteredNumberCompat.setIsEnabledForTest(true); + if (CompatUtils.isNCompatible()) { + mContentResolver.addProvider(BlockedNumberContract.AUTHORITY, mContentProvider); + } else { + mContentResolver.addProvider(FilteredNumberContract.AUTHORITY, mContentProvider); + } } - public void testIsBlockedNumber_NoResults() throws Throwable { - newIsBlockedNumberExpectedQueryM().returnEmptyCursor(); - final CheckBlockedListener listener = new CheckBlockedListener(); + public void testHasBlockedNumbers_Disabled() throws Throwable { + if (!CompatUtils.isNCompatible()) { + return; + } + FilteredNumberCompat.setIsEnabledForTest(false); + final MockContentResolver resolver = new MockContentResolver(); + MockContentProvider disabledProvider = new MockContentProvider(); + resolver.addProvider(FilteredNumberContract.AUTHORITY, disabledProvider); + disabledProvider.expectQuery(BLOCKED_NUMBER_URI_M).withProjection(FilteredNumberColumns._ID) + .withSelection(FilteredNumberColumns.TYPE + "=" + + FilteredNumberTypes.BLOCKED_NUMBER, null).returnRow(ID); + final HasBlockedNumbersListener listener = new HasBlockedNumbersListener(); runTestOnUiThread(new Runnable() { @Override public void run() { - new FilteredNumberAsyncQueryHandler(mContentResolver) - .isBlockedNumber(listener, NUMBER, COUNTRY_ISO); + new FilteredNumberAsyncQueryHandler(resolver).hasBlockedNumbers(listener); } }); - assertNull(listener.waitForCallback()); - mContentProvider.verify(); - } - - public void testIsBlockedNumber() throws Throwable { - newIsBlockedNumberExpectedQueryM().returnRow(ID, FilteredNumberTypes.BLOCKED_NUMBER); - final CheckBlockedListener listener = new CheckBlockedListener(); - runTestOnUiThread(new Runnable() { - @Override - public void run() { - new FilteredNumberAsyncQueryHandler(mContentResolver) - .isBlockedNumber(listener, NUMBER, COUNTRY_ISO); - } - }); - assertEquals(ID, listener.waitForCallback()); - mContentProvider.verify(); + assertTrue(listener.waitForCallback()); + disabledProvider.verify(); } public void testHasBlockedNumbers_NoResults() throws Throwable { - newHasBlockedNumbersExpectedQueryM().returnEmptyCursor(); + newHasBlockedNumbersExpectedQuery().returnEmptyCursor(); final HasBlockedNumbersListener listener = new HasBlockedNumbersListener(); runTestOnUiThread(new Runnable() { @Override @@ -95,7 +104,7 @@ public class FilteredNumberAsyncQueryHandlerTest extends InstrumentationTestCase } public void testHasBlockedNumbers() throws Throwable { - newHasBlockedNumbersExpectedQueryM().returnRow(ID); + newHasBlockedNumbersExpectedQuery().returnRow(ID); final HasBlockedNumbersListener listener = new HasBlockedNumbersListener(); runTestOnUiThread(new Runnable() { @Override @@ -107,24 +116,90 @@ public class FilteredNumberAsyncQueryHandlerTest extends InstrumentationTestCase mContentProvider.verify(); } - private Query newIsBlockedNumberExpectedQueryM() { - return mContentProvider.expectQuery(BLOCKED_NUMBER_URI) + public void testIsBlockedNumber_Disabled() throws Throwable { + if (!CompatUtils.isNCompatible()) { + return; + } + FilteredNumberCompat.setIsEnabledForTest(false); + final MockContentResolver resolver = new MockContentResolver(); + MockContentProvider disabledProvider = new MockContentProvider(); + resolver.addProvider(FilteredNumberContract.AUTHORITY, disabledProvider); + disabledProvider.expectQuery(BLOCKED_NUMBER_URI_M) .withProjection(FilteredNumberColumns._ID, FilteredNumberColumns.TYPE) - .withSelection(FilteredNumberColumns.NORMALIZED_NUMBER + " = ?", E164_NUMBER); + .withSelection(FilteredNumberColumns.NORMALIZED_NUMBER + " = ?", E164_NUMBER) + .returnRow(ID, FilteredNumberTypes.BLOCKED_NUMBER); + final CheckBlockedListener listener = new CheckBlockedListener(); + runTestOnUiThread(new Runnable() { + @Override + public void run() { + new FilteredNumberAsyncQueryHandler(resolver) + .isBlockedNumber(listener, NUMBER, COUNTRY_ISO); + } + }); + assertEquals(ID, listener.waitForCallback()); + mContentProvider.verify(); } - private Query newHasBlockedNumbersExpectedQueryM() { - return mContentProvider.expectQuery(BLOCKED_NUMBER_URI).withProjection( - FilteredNumberColumns._ID) - .withSelection(FilteredNumberColumns.TYPE + "=" - + FilteredNumberTypes.BLOCKED_NUMBER, null); + public void testIsBlockedNumber_NoResults() throws Throwable { + newIsBlockedNumberExpectedQuery().returnEmptyCursor(); + final CheckBlockedListener listener = new CheckBlockedListener(); + + runTestOnUiThread(new Runnable() { + @Override + public void run() { + new FilteredNumberAsyncQueryHandler(mContentResolver) + .isBlockedNumber(listener, NUMBER, COUNTRY_ISO); + } + }); + assertNull(listener.waitForCallback()); + mContentProvider.verify(); + } + + public void testIsBlockedNumber() throws Throwable { + if (CompatUtils.isNCompatible()) { + newIsBlockedNumberExpectedQuery().returnRow(ID); + } else { + newIsBlockedNumberExpectedQuery().returnRow(ID, FilteredNumberTypes.BLOCKED_NUMBER); + } + final CheckBlockedListener listener = new CheckBlockedListener(); + runTestOnUiThread(new Runnable() { + @Override + public void run() { + new FilteredNumberAsyncQueryHandler(mContentResolver) + .isBlockedNumber(listener, NUMBER, COUNTRY_ISO); + } + }); + assertEquals(ID, listener.waitForCallback()); + mContentProvider.verify(); + } + + public void testBlockNumber_Disabled() throws Throwable { + if (!CompatUtils.isNCompatible()) { + return; + } + FilteredNumberCompat.setIsEnabledForTest(false); + final MockContentResolver resolver = new MockContentResolver(); + MockContentProvider disabledProvider = new MockContentProvider(); + resolver.addProvider(FilteredNumberContract.AUTHORITY, disabledProvider); + + disabledProvider.expectInsert(BLOCKED_NUMBER_URI_M, newBlockNumberContentValuesM(), + EXPECTED_URI); + final BlockNumberListener listener = new BlockNumberListener(); + runTestOnUiThread(new Runnable() { + @Override + public void run() { + new FilteredNumberAsyncQueryHandler(resolver).blockNumber(listener, E164_NUMBER, + NUMBER, COUNTRY_ISO); + } + }); + assertSame(EXPECTED_URI, listener.waitForCallback()); + disabledProvider.verify(); } public void testBlockNumber() throws Throwable { mContentProvider.expectInsert(BLOCKED_NUMBER_URI, newBlockNumberContentValues(), EXPECTED_URI); - final BlockingArgumentCaptorOnBlockNumberListener listener = - new BlockingArgumentCaptorOnBlockNumberListener(); + final BlockNumberListener listener = new BlockNumberListener(); runTestOnUiThread(new Runnable() { @Override public void run() { @@ -132,16 +207,14 @@ public class FilteredNumberAsyncQueryHandlerTest extends InstrumentationTestCase E164_NUMBER, NUMBER, COUNTRY_ISO); } }); - assertTrue(listener.onBlockCompleteCalled.await(5000, TimeUnit.MILLISECONDS)); - assertSame(EXPECTED_URI, listener.uri); + assertSame(EXPECTED_URI, listener.waitForCallback()); mContentProvider.verify(); } public void testBlockNumber_NullNormalizedNumber() throws Throwable { mContentProvider.expectInsert(BLOCKED_NUMBER_URI, newBlockNumberContentValues(), EXPECTED_URI); - final BlockingArgumentCaptorOnBlockNumberListener listener = - new BlockingArgumentCaptorOnBlockNumberListener(); + final BlockNumberListener listener = new BlockNumberListener(); runTestOnUiThread(new Runnable() { @Override public void run() { @@ -149,12 +222,63 @@ public class FilteredNumberAsyncQueryHandlerTest extends InstrumentationTestCase NUMBER, COUNTRY_ISO); } }); - assertTrue(listener.onBlockCompleteCalled.await(5000, TimeUnit.MILLISECONDS)); - assertSame(EXPECTED_URI, listener.uri); + assertSame(EXPECTED_URI, listener.waitForCallback()); mContentProvider.verify(); } + private Query newIsBlockedNumberExpectedQuery() { + if (CompatUtils.isNCompatible()) { + return newIsBlockedNumberExpectedQueryN(); + } + return newIsBlockedNumberExpectedQueryM(); + } + + private Query newIsBlockedNumberExpectedQueryN() { + return mContentProvider.expectQuery(BLOCKED_NUMBER_URI) + .withProjection(BlockedNumbers.COLUMN_ID) + .withSelection(BlockedNumbers.COLUMN_E164_NUMBER + " = ?", E164_NUMBER); + } + + private Query newIsBlockedNumberExpectedQueryM() { + return mContentProvider.expectQuery(BLOCKED_NUMBER_URI) + .withProjection(FilteredNumberColumns._ID, FilteredNumberColumns.TYPE) + .withSelection(FilteredNumberColumns.NORMALIZED_NUMBER + " = ?", E164_NUMBER); + } + + private Query newHasBlockedNumbersExpectedQuery() { + if (CompatUtils.isNCompatible()) { + return newHasBlockedNumbersExpectedQueryN(); + } + return newHasBlockedNumbersExpectedQueryM(); + } + + private Query newHasBlockedNumbersExpectedQueryN() { + return mContentProvider.expectQuery(BLOCKED_NUMBER_URI) + .withProjection(BlockedNumbers.COLUMN_ID) + .withSelection(null, null); + } + + private Query newHasBlockedNumbersExpectedQueryM() { + return mContentProvider.expectQuery(BLOCKED_NUMBER_URI).withProjection( + FilteredNumberColumns._ID) + .withSelection(FilteredNumberColumns.TYPE + "=" + + FilteredNumberTypes.BLOCKED_NUMBER, null); + } + private ContentValues newBlockNumberContentValues() { + if (CompatUtils.isNCompatible()) { + return newBlockNumberContentValuesN(); + } + return newBlockNumberContentValuesM(); + } + + private ContentValues newBlockNumberContentValuesN() { + ContentValues contentValues = new ContentValues(); + contentValues.put(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, NUMBER); + return contentValues; + } + + private ContentValues newBlockNumberContentValuesM() { ContentValues contentValues = new ContentValues(); contentValues.put(FilteredNumberColumns.NORMALIZED_NUMBER, E164_NUMBER); contentValues.put(FilteredNumberColumns.NUMBER, NUMBER); @@ -208,11 +332,11 @@ public class FilteredNumberAsyncQueryHandlerTest extends InstrumentationTestCase } } - private class BlockingArgumentCaptorOnBlockNumberListener implements OnBlockNumberListener { + private class BlockNumberListener implements OnBlockNumberListener { public final CountDownLatch onBlockCompleteCalled; public Uri uri; - public BlockingArgumentCaptorOnBlockNumberListener() { + public BlockNumberListener() { onBlockCompleteCalled = new CountDownLatch(1); } @@ -221,5 +345,12 @@ public class FilteredNumberAsyncQueryHandlerTest extends InstrumentationTestCase this.uri = uri; onBlockCompleteCalled.countDown(); } + + public Uri waitForCallback() throws InterruptedException { + if (!onBlockCompleteCalled.await(5000, TimeUnit.MILLISECONDS)) { + throw new IllegalStateException("Waiting on callback timed out."); + } + return uri; + } } } -- cgit v1.2.3