summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAbhijith Shastry <ashastry@google.com>2016-01-23 22:16:39 -0800
committerAbhijith Shastry <ashastry@google.com>2016-01-25 12:54:45 -0800
commit35676f9095853d4a5ac15875a9ddb1aea6b0b809 (patch)
tree647c7e55747ba17226766250a1fe095890cf4e26
parent9f7cfe71be8d9b844b0423c283a923a090bc5d7c (diff)
downloadBlockedNumberProvider-35676f9095853d4a5ac15875a9ddb1aea6b0b809.tar.gz
Changes to BlockedNumberProvider:
1. Remove STRIPPED_PHONE_NUMBER column. 2. Temporarily permit system apps to access provider. 3. Notify changes to content so that ListViews work well with the provider. 4. Use DE storage. BUG: 26232372 Change-Id: Ib7fad2c3971a7b7b74c86c46fe3514330c22334c
-rw-r--r--AndroidManifest.xml11
-rw-r--r--src/com/android/providers/blockednumber/BlockedNumberDatabaseHelper.java23
-rw-r--r--src/com/android/providers/blockednumber/BlockedNumberProvider.java68
-rw-r--r--src/com/android/providers/blockednumber/Utils.java19
-rw-r--r--tests/src/com/android/providers/blockednumber/BlockedNumberProviderTest.java42
5 files changed, 100 insertions, 63 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index d9bd2c9..dd8522c 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -18,17 +18,12 @@
package="com.android.providers.blockednumber"
android:sharedUserId="android.uid.shared">
-<!--
- TODO: Make it DE. Add the following to <application>. See go/android-fbe-apis
- android:encryptionAware=”true”
- android:forceDeviceEncrypted=”true”
--->
-
<application
android:process="android.process.acore"
android:label="@string/app_label"
- android:allowBackup="false"
- android:usesCleartextTraffic="false">
+ android:usesCleartextTraffic="false"
+ android:encryptionAware="true"
+ android:forceDeviceEncrypted="true">
<provider android:name="BlockedNumberProvider"
android:authorities="com.android.blockednumber"
diff --git a/src/com/android/providers/blockednumber/BlockedNumberDatabaseHelper.java b/src/com/android/providers/blockednumber/BlockedNumberDatabaseHelper.java
index 005c918..ac3e94d 100644
--- a/src/com/android/providers/blockednumber/BlockedNumberDatabaseHelper.java
+++ b/src/com/android/providers/blockednumber/BlockedNumberDatabaseHelper.java
@@ -24,7 +24,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.Preconditions;
public class BlockedNumberDatabaseHelper {
- private static final int DATABASE_VERSION = 1;
+ private static final int DATABASE_VERSION = 2;
private static final String DATABASE_NAME = "blockednumbers.db";
@@ -46,23 +46,30 @@ public class BlockedNumberDatabaseHelper {
@Override
public void onCreate(SQLiteDatabase db) {
+ createTables(db);
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ if (oldVersion < 2) {
+ db.execSQL("DROP TABLE IF EXISTS blocked");
+ createTables(db);
+ }
+ }
+
+ private void createTables(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + Tables.BLOCKED_NUMBERS + " (" +
BlockedNumbers.COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
BlockedNumbers.COLUMN_ORIGINAL_NUMBER + " TEXT NOT NULL UNIQUE," +
- BlockedNumbers.COLUMN_STRIPPED_NUMBER + " TEXT NOT NULL," +
BlockedNumbers.COLUMN_E164_NUMBER + " TEXT" +
")");
- db.execSQL("CREATE INDEX blocked_number_idx_stripped ON " + Tables.BLOCKED_NUMBERS +
- " (" + BlockedNumbers.COLUMN_STRIPPED_NUMBER + ");");
+ db.execSQL("CREATE INDEX blocked_number_idx_original ON " + Tables.BLOCKED_NUMBERS +
+ " (" + BlockedNumbers.COLUMN_ORIGINAL_NUMBER + ");");
db.execSQL("CREATE INDEX blocked_number_idx_e164 ON " + Tables.BLOCKED_NUMBERS + " (" +
BlockedNumbers.COLUMN_E164_NUMBER +
");");
}
-
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- }
}
@VisibleForTesting
diff --git a/src/com/android/providers/blockednumber/BlockedNumberProvider.java b/src/com/android/providers/blockednumber/BlockedNumberProvider.java
index 72a0c93..2c8cffe 100644
--- a/src/com/android/providers/blockednumber/BlockedNumberProvider.java
+++ b/src/com/android/providers/blockednumber/BlockedNumberProvider.java
@@ -19,6 +19,8 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AppOpsManager;
import android.content.*;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
@@ -58,7 +60,6 @@ public class BlockedNumberProvider extends ContentProvider {
private static final ProjectionMap sBlockedNumberColumns = ProjectionMap.builder()
.add(BlockedNumberContract.BlockedNumbers.COLUMN_ID)
.add(BlockedNumberContract.BlockedNumbers.COLUMN_ORIGINAL_NUMBER)
- .add(BlockedNumberContract.BlockedNumbers.COLUMN_STRIPPED_NUMBER)
.add(BlockedNumberContract.BlockedNumbers.COLUMN_E164_NUMBER)
.build();
@@ -112,7 +113,9 @@ public class BlockedNumberProvider extends ContentProvider {
final int match = sUriMatcher.match(uri);
switch (match) {
case BLOCKED_LIST:
- return insertBlockedNumber(values);
+ Uri blockedUri = insertBlockedNumber(values);
+ getContext().getContentResolver().notifyChange(blockedUri, null);
+ return blockedUri;
default:
throw new IllegalArgumentException("Unsupported URI: " + uri);
}
@@ -123,7 +126,6 @@ public class BlockedNumberProvider extends ContentProvider {
*/
private Uri insertBlockedNumber(ContentValues cv) {
throwIfSpecified(cv, BlockedNumberContract.BlockedNumbers.COLUMN_ID);
- throwIfSpecified(cv, BlockedNumberContract.BlockedNumbers.COLUMN_STRIPPED_NUMBER);
final String phoneNumber = cv.getAsString(
BlockedNumberContract.BlockedNumbers.COLUMN_ORIGINAL_NUMBER);
@@ -133,14 +135,15 @@ public class BlockedNumberProvider extends ContentProvider {
BlockedNumberContract.BlockedNumbers.COLUMN_ORIGINAL_NUMBER);
}
- // Sanitize the input and fill in with autogenerated columns.
- final String strippedNumber = Utils.stripPhoneNumber(phoneNumber);
- final String e164Number = Utils.getE164Number(getContext(), strippedNumber,
+ // Fill in with autogenerated columns.
+ final String e164Number = Utils.getE164Number(getContext(), phoneNumber,
cv.getAsString(BlockedNumberContract.BlockedNumbers.COLUMN_E164_NUMBER));
-
- cv.put(BlockedNumberContract.BlockedNumbers.COLUMN_STRIPPED_NUMBER, strippedNumber);
cv.put(BlockedNumberContract.BlockedNumbers.COLUMN_E164_NUMBER, e164Number);
+ if (DEBUG) {
+ Log.d(TAG, String.format("inserted blocked number: %s", cv));
+ }
+
// Then insert.
final long id = mDbHelper.getWritableDatabase().insertOrThrow(
BlockedNumberDatabaseHelper.Tables.BLOCKED_NUMBERS, null, cv);
@@ -176,14 +179,19 @@ public class BlockedNumberProvider extends ContentProvider {
enforceWritePermission();
final int match = sUriMatcher.match(uri);
+ int numRows;
switch (match) {
case BLOCKED_LIST:
- return deleteBlockedNumber(selection, selectionArgs);
+ numRows = deleteBlockedNumber(selection, selectionArgs);
+ break;
case BLOCKED_ID:
- return deleteBlockedNumberWithId(ContentUris.parseId(uri), selection);
+ numRows = deleteBlockedNumberWithId(ContentUris.parseId(uri), selection);
+ break;
default:
throw new IllegalArgumentException("Unsupported URI: " + uri);
}
+ getContext().getContentResolver().notifyChange(uri, null);
+ return numRows;
}
/**
@@ -228,16 +236,22 @@ public class BlockedNumberProvider extends ContentProvider {
enforceReadPermission();
final int match = sUriMatcher.match(uri);
+ Cursor cursor;
switch (match) {
case BLOCKED_LIST:
- return queryBlockedList(projection, selection, selectionArgs, sortOrder,
+ cursor = queryBlockedList(projection, selection, selectionArgs, sortOrder,
cancellationSignal);
+ break;
case BLOCKED_ID:
- return queryBlockedListWithId(ContentUris.parseId(uri), projection, selection,
+ cursor = queryBlockedListWithId(ContentUris.parseId(uri), projection, selection,
cancellationSignal);
+ break;
default:
throw new IllegalArgumentException("Unsupported URI: " + uri);
}
+ // Tell the cursor what uri to watch, so it knows when its source data changes
+ cursor.setNotificationUri(getContext().getContentResolver(), uri);
+ return cursor;
}
/**
@@ -295,38 +309,33 @@ public class BlockedNumberProvider extends ContentProvider {
}
private boolean isBlocked(String phoneNumber) {
- final String inStripped = Utils.stripPhoneNumber(phoneNumber);
- if (TextUtils.isEmpty(inStripped)) {
+ if (TextUtils.isEmpty(phoneNumber)) {
return false;
}
- final String inE164 = Utils.getE164Number(getContext(), inStripped, null); // may be empty.
+ final String inE164 = Utils.getE164Number(getContext(), phoneNumber, null); // may be empty.
if (DEBUG) {
- Log.d(TAG, String.format("isBlocked: in=%s, stripped=%s, e164=%s", phoneNumber,
- inStripped, inE164));
+ Log.d(TAG, String.format("isBlocked: in=%s, e164=%s", phoneNumber, inE164));
}
final Cursor c = mDbHelper.getReadableDatabase().rawQuery(
"SELECT " +
BlockedNumberContract.BlockedNumbers.COLUMN_ORIGINAL_NUMBER + "," +
- BlockedNumberContract.BlockedNumbers.COLUMN_STRIPPED_NUMBER + "," +
BlockedNumberContract.BlockedNumbers.COLUMN_E164_NUMBER +
" FROM " + BlockedNumberDatabaseHelper.Tables.BLOCKED_NUMBERS +
- " WHERE " + BlockedNumberContract.BlockedNumbers.COLUMN_STRIPPED_NUMBER + "=?1" +
+ " WHERE " + BlockedNumberContract.BlockedNumbers.COLUMN_ORIGINAL_NUMBER + "=?1" +
" OR (?2 != '' AND " +
BlockedNumberContract.BlockedNumbers.COLUMN_E164_NUMBER + "=?2)",
- new String[] {inStripped, inE164}
+ new String[] {phoneNumber, inE164}
);
try {
while (c.moveToNext()) {
if (DEBUG) {
final String original = c.getString(0);
- final String stripped = c.getString(1);
- final String e164 = c.getString(2);
+ final String e164 = c.getString(1);
- Log.d(TAG, String.format(" match found: original=%s, stripped=%s, e164=%s",
- original, stripped, e164));
+ Log.d(TAG, String.format("match found: original=%s, e164=%s", original, e164));
}
return true;
}
@@ -378,6 +387,17 @@ public class BlockedNumberProvider extends ContentProvider {
Binder.getCallingUid(), callingPackage) == AppOpsManager.MODE_ALLOWED) {
return;
}
+
+ // TODO: Add an explicit permission instead.
+ try {
+ ApplicationInfo applicationInfo = getContext().
+ getPackageManager().getPackageInfo(callingPackage, 0).applicationInfo;
+ if (applicationInfo.isPrivilegedApp() || applicationInfo.isSystemApp()) {
+ return;
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.w(TAG, "package not found: " + e);
+ }
}
throw new SecurityException("Caller must be system, default dialer or default SMS app");
}
diff --git a/src/com/android/providers/blockednumber/Utils.java b/src/com/android/providers/blockednumber/Utils.java
index e890634..6aaf178 100644
--- a/src/com/android/providers/blockednumber/Utils.java
+++ b/src/com/android/providers/blockednumber/Utils.java
@@ -48,23 +48,6 @@ public class Utils {
}
/**
- * Strip formatting characters and the non-phone number portion from a phone number. e.g.
- * "+1-408-123-4444;123" to "+14081234444".
- *
- * <p>Special case: if a number contains '@', it's considered as an email address and returned
- * unmodified.
- */
- public static @NonNull String stripPhoneNumber(@Nullable String phoneNumber) {
- if (TextUtils.isEmpty(phoneNumber)) {
- return "";
- }
- if (phoneNumber.contains("@")) {
- return phoneNumber;
- }
- return PhoneNumberUtils.extractNetworkPortion(phoneNumber);
- }
-
- /**
* Converts a phone number to an E164 number, assuming the current country. If {@code
* incomingE16Number} is provided, it'll just strip it and returns. If the number is not valid,
* it'll return "".
@@ -78,7 +61,7 @@ public class Utils {
return rawNumber;
}
if (!TextUtils.isEmpty(incomingE16Number)) {
- return stripPhoneNumber(incomingE16Number);
+ return incomingE16Number;
}
if (TextUtils.isEmpty(rawNumber)) {
return "";
diff --git a/tests/src/com/android/providers/blockednumber/BlockedNumberProviderTest.java b/tests/src/com/android/providers/blockednumber/BlockedNumberProviderTest.java
index fb9a81a..0ceb684 100644
--- a/tests/src/com/android/providers/blockednumber/BlockedNumberProviderTest.java
+++ b/tests/src/com/android/providers/blockednumber/BlockedNumberProviderTest.java
@@ -19,6 +19,7 @@ import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
+import android.database.ContentObserver;
import android.database.Cursor;
import android.database.sqlite.SQLiteConstraintException;
import android.database.sqlite.SQLiteException;
@@ -29,6 +30,9 @@ import android.test.AndroidTestCase;
import android.test.MoreAsserts;
import junit.framework.Assert;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
/**
* m BlockedNumberProviderTest && adb install -r
* ${ANDROID_PRODUCT_OUT}/data/app/BlockedNumberProviderTest/BlockedNumberProviderTest.apk && adb
@@ -40,7 +44,9 @@ public class BlockedNumberProviderTest extends AndroidTestCase {
private MyMockContext mMockContext;
private ContentResolver mResolver;
- /** Whether the country detector thinks the device is in USA. */
+ /**
+ * Whether the country detector thinks the device is in USA.
+ */
private boolean mInUSA;
@Override
@@ -66,7 +72,7 @@ public class BlockedNumberProviderTest extends AndroidTestCase {
final ContentValues ret = new ContentValues();
for (int i = 1; i < namesAndValues.length; i += 2) {
final String name = namesAndValues[i - 1].toString();
- final Object value = namesAndValues[i];
+ final Object value = namesAndValues[i];
if (value == null) {
ret.putNull(name);
} else if (value instanceof String) {
@@ -104,7 +110,6 @@ public class BlockedNumberProviderTest extends AndroidTestCase {
insertExpectingFailure(cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, null));
insertExpectingFailure(cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, ""));
insertExpectingFailure(cv(BlockedNumbers.COLUMN_ID, 1));
- insertExpectingFailure(cv(BlockedNumbers.COLUMN_STRIPPED_NUMBER, 1));
insertExpectingFailure(cv(BlockedNumbers.COLUMN_E164_NUMBER, "1"));
insert(cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "123"));
@@ -128,6 +133,30 @@ public class BlockedNumberProviderTest extends AndroidTestCase {
// TODO Check the table content.
}
+ public void testChangesNotified() throws Exception {
+ Cursor c = mResolver.query(BlockedNumbers.CONTENT_URI, null, null, null, null);
+
+ final CountDownLatch latch = new CountDownLatch(2);
+ ContentObserver contentObserver = new ContentObserver(null) {
+ @Override
+ public void onChange(boolean selfChange) {
+ Assert.assertFalse(selfChange);
+ latch.notify();
+ }
+ };
+ c.registerContentObserver(contentObserver);
+
+ try {
+ Uri uri = insert(cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "14506507000"));
+ mResolver.delete(uri, null, null);
+ latch.await(10, TimeUnit.SECONDS);
+ } catch (Exception e) {
+ fail(e.toString());
+ } finally {
+ c.unregisterContentObserver(contentObserver);
+ }
+ }
+
private Uri insert(ContentValues cv) {
final Uri uri = mResolver.insert(BlockedNumbers.CONTENT_URI, cv);
assertNotNull(uri);
@@ -210,16 +239,19 @@ public class BlockedNumberProviderTest extends AndroidTestCase {
insert(cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "1-500-454-2222"));
insert(cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "045-111-2222",
- BlockedNumbers.COLUMN_E164_NUMBER, "+81-45-111-2222"));
+ BlockedNumbers.COLUMN_E164_NUMBER, "+81451112222"));
insert(cv(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "abc.def@gmail.com"));
// Check
+ assertIsBlocked(false, "");
+ assertIsBlocked(false, null);
assertIsBlocked(true, "123");
assertIsBlocked(false, "1234");
assertIsBlocked(true, "+81451112222");
assertIsBlocked(true, "+81 45 111 2222");
- assertIsBlocked(true, "045 111 2222");
+ assertIsBlocked(true, "045-111-2222");
+ assertIsBlocked(false, "045 111 2222");
if (mInUSA) {
// Probably won't work outside of the +1 region.