aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTreeHugger Robot <treehugger-gerrit@google.com>2017-10-17 23:31:38 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2017-10-17 23:31:38 +0000
commit5e097c0c0e687c80ae46006a692dc12393903126 (patch)
treecffd071953c4068cecbf2448dc7e333adc58ab23 /src
parent551d31e5acd9ad772ca5fbde4aa66207b1258fab (diff)
parentc28f7969399fcb667d02de4030fba0fc40ff9130 (diff)
downloadContactsProvider-5e097c0c0e687c80ae46006a692dc12393903126.tar.gz
Merge "Implement bulkInsert for VoicemailProvider"
Diffstat (limited to 'src')
-rw-r--r--src/com/android/providers/contacts/CallLogProvider.java12
-rw-r--r--src/com/android/providers/contacts/DatabaseModifier.java6
-rw-r--r--src/com/android/providers/contacts/DbModifierWithNotification.java120
-rw-r--r--src/com/android/providers/contacts/VoicemailContentProvider.java7
-rw-r--r--src/com/android/providers/contacts/VoicemailContentTable.java41
-rw-r--r--src/com/android/providers/contacts/VoicemailNotifier.java127
-rw-r--r--src/com/android/providers/contacts/VoicemailStatusTable.java24
-rw-r--r--src/com/android/providers/contacts/VoicemailTable.java2
8 files changed, 249 insertions, 90 deletions
diff --git a/src/com/android/providers/contacts/CallLogProvider.java b/src/com/android/providers/contacts/CallLogProvider.java
index 59e9b147..76e207a0 100644
--- a/src/com/android/providers/contacts/CallLogProvider.java
+++ b/src/com/android/providers/contacts/CallLogProvider.java
@@ -383,7 +383,7 @@ public class CallLogProvider extends ContentProvider {
// Add the computed fields to the copied values.
mCallLogInsertionHelper.addComputedValues(copiedValues);
- long rowId = getDatabaseModifier(mCallsInserter).insert(copiedValues);
+ long rowId = createDatabaseModifier(mCallsInserter).insert(copiedValues);
if (rowId > 0) {
return ContentUris.withAppendedId(uri, rowId);
}
@@ -423,7 +423,7 @@ public class CallLogProvider extends ContentProvider {
throw new UnsupportedOperationException("Cannot update URL: " + uri);
}
- return getDatabaseModifier(db).update(uri, Tables.CALLS, values, selectionBuilder.build(),
+ return createDatabaseModifier(db).update(uri, Tables.CALLS, values, selectionBuilder.build(),
selectionArgs);
}
@@ -445,7 +445,7 @@ public class CallLogProvider extends ContentProvider {
case CALLS:
// TODO: Special case - We may want to forward the delete request on user 0 to the
// shadow provider too.
- return getDatabaseModifier(db).delete(Tables.CALLS,
+ return createDatabaseModifier(db).delete(Tables.CALLS,
selectionBuilder.build(), selectionArgs);
default:
throw new UnsupportedOperationException("Cannot delete that URL: " + uri);
@@ -460,15 +460,15 @@ public class CallLogProvider extends ContentProvider {
* Returns a {@link DatabaseModifier} that takes care of sending necessary notifications
* after the operation is performed.
*/
- private DatabaseModifier getDatabaseModifier(SQLiteDatabase db) {
+ private DatabaseModifier createDatabaseModifier(SQLiteDatabase db) {
return new DbModifierWithNotification(Tables.CALLS, db, getContext());
}
/**
- * Same as {@link #getDatabaseModifier(SQLiteDatabase)} but used for insert helper operations
+ * Same as {@link #createDatabaseModifier(SQLiteDatabase)} but used for insert helper operations
* only.
*/
- private DatabaseModifier getDatabaseModifier(DatabaseUtils.InsertHelper insertHelper) {
+ private DatabaseModifier createDatabaseModifier(DatabaseUtils.InsertHelper insertHelper) {
return new DbModifierWithNotification(Tables.CALLS, insertHelper, getContext());
}
diff --git a/src/com/android/providers/contacts/DatabaseModifier.java b/src/com/android/providers/contacts/DatabaseModifier.java
index b11605b4..60f9c7f1 100644
--- a/src/com/android/providers/contacts/DatabaseModifier.java
+++ b/src/com/android/providers/contacts/DatabaseModifier.java
@@ -49,4 +49,10 @@ public interface DatabaseModifier {
* {@link SQLiteDatabase#delete(String, String, String[])} method.
*/
public abstract int delete(String table, String whereClause, String[] whereArgs);
+
+ void startBulkOperation();
+
+ void yieldBulkOperation();
+
+ void finishBulkOperation();
}
diff --git a/src/com/android/providers/contacts/DbModifierWithNotification.java b/src/com/android/providers/contacts/DbModifierWithNotification.java
index 7e7b3e17..36865fa1 100644
--- a/src/com/android/providers/contacts/DbModifierWithNotification.java
+++ b/src/com/android/providers/contacts/DbModifierWithNotification.java
@@ -17,7 +17,6 @@
package com.android.providers.contacts;
-import static android.Manifest.permission.ADD_VOICEMAIL;
import static android.Manifest.permission.READ_VOICEMAIL;
import android.content.ComponentName;
@@ -25,8 +24,6 @@ import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.database.DatabaseUtils.InsertHelper;
import android.database.sqlite.SQLiteDatabase;
@@ -37,17 +34,15 @@ import android.provider.VoicemailContract;
import android.provider.VoicemailContract.Status;
import android.provider.VoicemailContract.Voicemails;
import android.util.ArraySet;
-import android.util.Log;
import com.android.common.io.MoreCloseables;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.providers.contacts.CallLogDatabaseHelper.Tables;
import com.android.providers.contacts.util.DbQueryUtils;
import com.google.android.collect.Lists;
import com.google.common.collect.Iterables;
-import java.util.ArrayList;
import java.util.Collection;
-import java.util.List;
import java.util.Set;
/**
@@ -57,6 +52,7 @@ import java.util.Set;
* of then got affected by the change.
*/
public class DbModifierWithNotification implements DatabaseModifier {
+
private static final String TAG = "DbModifierWithNotify";
private static final String[] PROJECTION = new String[] {
@@ -73,8 +69,11 @@ public class DbModifierWithNotification implements DatabaseModifier {
private final Context mContext;
private final Uri mBaseUri;
private final boolean mIsCallsTable;
- private final VoicemailPermissions mVoicemailPermissions;
+ private final VoicemailNotifier mVoicemailNotifier;
+
+ private boolean mIsBulkOperation = false;
+ private static VoicemailNotifier sVoicemailNotifierForTest;
public DbModifierWithNotification(String tableName, SQLiteDatabase db, Context context) {
this(tableName, db, null, context);
@@ -94,7 +93,8 @@ public class DbModifierWithNotification implements DatabaseModifier {
mBaseUri = mTableName.equals(Tables.VOICEMAIL_STATUS) ?
Status.CONTENT_URI : Voicemails.CONTENT_URI;
mIsCallsTable = mTableName.equals(Tables.CALLS);
- mVoicemailPermissions = new VoicemailPermissions(mContext);
+ mVoicemailNotifier = sVoicemailNotifierForTest != null ? sVoicemailNotifierForTest
+ : new VoicemailNotifier(mContext, mBaseUri);
}
@Override
@@ -143,13 +143,21 @@ public class DbModifierWithNotification implements DatabaseModifier {
}
}
- private void notifyVoicemailChangeOnInsert(Uri notificationUri, Set<String> packagesModified) {
+ private void notifyVoicemailChangeOnInsert(
+ Uri notificationUri, Set<String> packagesModified) {
if (mIsCallsTable) {
- notifyVoicemailChange(notificationUri, packagesModified,
- VoicemailContract.ACTION_NEW_VOICEMAIL, Intent.ACTION_PROVIDER_CHANGED);
- } else {
- notifyVoicemailChange(notificationUri, packagesModified,
- Intent.ACTION_PROVIDER_CHANGED);
+ mVoicemailNotifier.addIntentActions(VoicemailContract.ACTION_NEW_VOICEMAIL);
+ }
+ notifyVoicemailChange(notificationUri, packagesModified);
+ }
+
+ private void notifyVoicemailChange(Uri notificationUri,
+ Set<String> modifiedPackages) {
+ mVoicemailNotifier.addUri(notificationUri);
+ mVoicemailNotifier.addModifiedPackages(modifiedPackages);
+ mVoicemailNotifier.addIntentActions(Intent.ACTION_PROVIDER_CHANGED);
+ if (!mIsBulkOperation) {
+ mVoicemailNotifier.sendNotification();
}
}
@@ -197,7 +205,7 @@ public class DbModifierWithNotification implements DatabaseModifier {
int count = mDb.update(table, values, whereClause, whereArgs);
if (count > 0 && isVoicemail) {
- notifyVoicemailChange(mBaseUri, packagesModified, Intent.ACTION_PROVIDER_CHANGED);
+ notifyVoicemailChange(mBaseUri, packagesModified);
}
if (count > 0 && mIsCallsTable) {
notifyCallLogChange();
@@ -247,7 +255,7 @@ public class DbModifierWithNotification implements DatabaseModifier {
}
if (count > 0 && isVoicemail) {
- notifyVoicemailChange(mBaseUri, packagesModified, Intent.ACTION_PROVIDER_CHANGED);
+ notifyVoicemailChange(mBaseUri, packagesModified);
}
if (count > 0 && mIsCallsTable) {
notifyCallLogChange();
@@ -255,6 +263,25 @@ public class DbModifierWithNotification implements DatabaseModifier {
return count;
}
+ @Override
+ public void startBulkOperation() {
+ mIsBulkOperation = true;
+ mDb.beginTransaction();
+ }
+
+ @Override
+ public void yieldBulkOperation() {
+ mDb.yieldIfContendedSafely();
+ }
+
+ @Override
+ public void finishBulkOperation() {
+ mDb.setTransactionSuccessful();
+ mDb.endTransaction();
+ mIsBulkOperation = false;
+ mVoicemailNotifier.sendNotification();
+ }
+
/**
* Returns the set of packages affected when a modify operation is run for the specified
* where clause. When called from an insert operation an empty set returned by this method
@@ -266,7 +293,7 @@ public class DbModifierWithNotification implements DatabaseModifier {
Cursor cursor = mDb.query(mTableName, PROJECTION,
DbQueryUtils.concatenateClauses(NON_NULL_SOURCE_PACKAGE_SELECTION, whereClause),
whereArgs, null, null, null);
- while(cursor.moveToNext()) {
+ while (cursor.moveToNext()) {
modifiedPackages.add(cursor.getString(SOURCE_PACKAGE_COLUMN_INDEX));
}
MoreCloseables.closeQuietly(cursor);
@@ -281,7 +308,7 @@ public class DbModifierWithNotification implements DatabaseModifier {
*/
private Set<String> getModifiedPackages(ContentValues values) {
Set<String> impactedPackages = new ArraySet<>();
- if(values.containsKey(VoicemailContract.SOURCE_PACKAGE_FIELD)) {
+ if (values.containsKey(VoicemailContract.SOURCE_PACKAGE_FIELD)) {
impactedPackages.add(values.getAsString(VoicemailContract.SOURCE_PACKAGE_FIELD));
}
return impactedPackages;
@@ -304,58 +331,6 @@ public class DbModifierWithNotification implements DatabaseModifier {
|| callingPackages.contains(mContext.getPackageName()));
}
- private void notifyVoicemailChange(Uri notificationUri, Set<String> modifiedPackages,
- String... intentActions) {
- // Notify the observers.
- // Must be done only once, even if there are multiple broadcast intents.
- mContext.getContentResolver().notifyChange(notificationUri, null, true);
- Collection<String> callingPackages = getCallingPackages();
- // Now fire individual intents.
- for (String intentAction : intentActions) {
- // self_change extra should be included only for provider_changed events.
- boolean includeSelfChangeExtra = intentAction.equals(Intent.ACTION_PROVIDER_CHANGED);
- for (ComponentName component :
- getBroadcastReceiverComponents(intentAction, notificationUri)) {
- // Ignore any package that is not affected by the change and don't have full access
- // either.
- if (!modifiedPackages.contains(component.getPackageName()) &&
- !mVoicemailPermissions.packageHasReadAccess(
- component.getPackageName())) {
- continue;
- }
-
- Intent intent = new Intent(intentAction, notificationUri);
- intent.setComponent(component);
- if (includeSelfChangeExtra && callingPackages != null) {
- intent.putExtra(VoicemailContract.EXTRA_SELF_CHANGE,
- callingPackages.contains(component.getPackageName()));
- }
- String permissionNeeded = modifiedPackages.contains(component.getPackageName()) ?
- ADD_VOICEMAIL : READ_VOICEMAIL;
- mContext.sendBroadcast(intent, permissionNeeded);
- Log.v(TAG, String.format("Sent intent. act:%s, url:%s, comp:%s, perm:%s," +
- " self_change:%s", intent.getAction(), intent.getData(),
- component.getClassName(), permissionNeeded,
- intent.hasExtra(VoicemailContract.EXTRA_SELF_CHANGE) ?
- intent.getBooleanExtra(VoicemailContract.EXTRA_SELF_CHANGE, false) :
- null));
- }
- }
- }
-
- /** Determines the components that can possibly receive the specified intent. */
- private List<ComponentName> getBroadcastReceiverComponents(String intentAction, Uri uri) {
- Intent intent = new Intent(intentAction, uri);
- List<ComponentName> receiverComponents = new ArrayList<ComponentName>();
- // For broadcast receivers ResolveInfo.activityInfo is the one that is populated.
- for (ResolveInfo resolveInfo :
- mContext.getPackageManager().queryBroadcastReceivers(intent, 0)) {
- ActivityInfo activityInfo = resolveInfo.activityInfo;
- receiverComponents.add(new ComponentName(activityInfo.packageName, activityInfo.name));
- }
- return receiverComponents;
- }
-
/**
* Returns the package names of the calling process. If the calling process has more than
* one packages, this returns them all
@@ -393,4 +368,9 @@ public class DbModifierWithNotification implements DatabaseModifier {
}
return CallLogProvider.getTimeForTestMillis();
}
+
+ @VisibleForTesting
+ static void setVoicemailNotifierForTest(VoicemailNotifier notifier){
+ sVoicemailNotifierForTest = notifier;
+ }
}
diff --git a/src/com/android/providers/contacts/VoicemailContentProvider.java b/src/com/android/providers/contacts/VoicemailContentProvider.java
index 160a1a99..01c10481 100644
--- a/src/com/android/providers/contacts/VoicemailContentProvider.java
+++ b/src/com/android/providers/contacts/VoicemailContentProvider.java
@@ -20,6 +20,7 @@ import static android.provider.VoicemailContract.SOURCE_PACKAGE_FIELD;
import static com.android.providers.contacts.util.DbQueryUtils.concatenateClauses;
import static com.android.providers.contacts.util.DbQueryUtils.getEqualityClause;
+import android.annotation.NonNull;
import android.app.AppOpsManager;
import android.content.ContentProvider;
import android.content.ContentResolver;
@@ -157,6 +158,12 @@ public class VoicemailContentProvider extends ContentProvider
}
@Override
+ public int bulkInsert(@NonNull Uri uri, @NonNull ContentValues[] values) {
+ UriData uriData = checkPermissionsAndCreateUriDataForWrite(uri, values);
+ return getTableDelegate(uriData).bulkInsert(uriData, values);
+ }
+
+ @Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
if (VERBOSE_LOGGING) {
diff --git a/src/com/android/providers/contacts/VoicemailContentTable.java b/src/com/android/providers/contacts/VoicemailContentTable.java
index 09a8c1f0..b295ac54 100644
--- a/src/com/android/providers/contacts/VoicemailContentTable.java
+++ b/src/com/android/providers/contacts/VoicemailContentTable.java
@@ -39,7 +39,6 @@ import com.android.providers.contacts.VoicemailContentProvider.UriData;
import com.android.providers.contacts.util.CloseUtils;
import com.google.common.collect.ImmutableSet;
-
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
@@ -52,10 +51,12 @@ public class VoicemailContentTable implements VoicemailTable.Delegate {
private static final String TAG = "VmContentProvider";
private final ProjectionMap mVoicemailProjectionMap;
- /** The private directory in which to store the data associated with the voicemail. */
+ /**
+ * The private directory in which to store the data associated with the voicemail.
+ */
private static final String DATA_DIRECTORY = "voicemail-data";
- private static final String[] FILENAME_ONLY_PROJECTION = new String[] { Voicemails._DATA };
+ private static final String[] FILENAME_ONLY_PROJECTION = new String[] {Voicemails._DATA};
private static final ImmutableSet<String> ALLOWED_COLUMNS = new ImmutableSet.Builder<String>()
.add(Voicemails._ID)
@@ -83,6 +84,8 @@ public class VoicemailContentTable implements VoicemailTable.Delegate {
.add(OpenableColumns.SIZE)
.build();
+ private static final int BULK_INSERTS_PER_YIELD_POINT = 50;
+
private final String mTableName;
private final CallLogDatabaseHelper mDbHelper;
private final Context mContext;
@@ -138,6 +141,30 @@ public class VoicemailContentTable implements VoicemailTable.Delegate {
@Override
public Uri insert(UriData uriData, ContentValues values) {
+ DatabaseModifier modifier = createDatabaseModifier(mDbHelper.getWritableDatabase());
+ Uri uri = insertRow(modifier, uriData, values);
+ return uri;
+ }
+
+ @Override
+ public int bulkInsert(UriData uriData, ContentValues[] values) {
+ DatabaseModifier modifier = createDatabaseModifier(mDbHelper.getWritableDatabase());
+ modifier.startBulkOperation();
+ int count = 0;
+ for (ContentValues value : values) {
+ Uri uri = insertRow(modifier, uriData, value);
+ if (uri != null) {
+ count++;
+ }
+ if((count % BULK_INSERTS_PER_YIELD_POINT) == 0){
+ modifier.yieldBulkOperation();
+ }
+ }
+ modifier.finishBulkOperation();
+ return count;
+ }
+
+ private Uri insertRow(DatabaseModifier modifier, UriData uriData, ContentValues values) {
checkForSupportedColumns(mVoicemailProjectionMap, values);
ContentValues copiedValues = new ContentValues(values);
checkInsertSupported(uriData);
@@ -160,7 +187,7 @@ public class VoicemailContentTable implements VoicemailTable.Delegate {
}
SQLiteDatabase db = mDbHelper.getWritableDatabase();
- long rowId = getDatabaseModifier(db).insert(mTableName, null, copiedValues);
+ long rowId = modifier.insert(mTableName, null, copiedValues);
if (rowId > 0) {
Uri newUri = ContentUris.withAppendedId(uriData.getUri(), rowId);
// Populate the 'voicemail_uri' field to be used by the call_log provider.
@@ -228,7 +255,7 @@ public class VoicemailContentTable implements VoicemailTable.Delegate {
}
// Now delete the rows themselves.
- return getDatabaseModifier(db).delete(mTableName, combinedClause,
+ return createDatabaseModifier(db).delete(mTableName, combinedClause,
selectionArgs);
}
@@ -262,7 +289,7 @@ public class VoicemailContentTable implements VoicemailTable.Delegate {
// URI that include message Id. I think we do want to support bulk update.
String combinedClause = concatenateClauses(selection, uriData.getWhereClause(),
getCallTypeClause());
- return getDatabaseModifier(db).update(uriData.getUri(), mTableName, values, combinedClause,
+ return createDatabaseModifier(db).update(uriData.getUri(), mTableName, values, combinedClause,
selectionArgs);
}
@@ -298,7 +325,7 @@ public class VoicemailContentTable implements VoicemailTable.Delegate {
return getEqualityClause(Calls.TYPE, Calls.VOICEMAIL_TYPE);
}
- private DatabaseModifier getDatabaseModifier(SQLiteDatabase db) {
+ private DatabaseModifier createDatabaseModifier(SQLiteDatabase db) {
return new DbModifierWithNotification(mTableName, db, mContext);
}
diff --git a/src/com/android/providers/contacts/VoicemailNotifier.java b/src/com/android/providers/contacts/VoicemailNotifier.java
new file mode 100644
index 00000000..04a9bd64
--- /dev/null
+++ b/src/com/android/providers/contacts/VoicemailNotifier.java
@@ -0,0 +1,127 @@
+package com.android.providers.contacts;
+
+import static android.Manifest.permission.ADD_VOICEMAIL;
+import static android.Manifest.permission.READ_VOICEMAIL;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ResolveInfo;
+import android.net.Uri;
+import android.os.Binder;
+import android.provider.VoicemailContract;
+import android.util.ArraySet;
+import android.util.Log;
+
+import com.google.android.collect.Lists;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Aggregates voicemail broadcasts from multiple operations in to a single one. The URIs will be
+ * {@link VoicemailContract.Voicemails#DIR_TYPE} instead of {@link
+ * VoicemailContract.Voicemails#ITEM_TYPE} if multiple URIs is notified.
+ */
+public class VoicemailNotifier {
+
+ private final String TAG = "VoicemailNotifier";
+
+ private final Context mContext;
+ private final Uri mBaseUri;
+
+ private final VoicemailPermissions mVoicemailPermissions;
+
+ private final Set<String> mIntentActions = new ArraySet<>();
+ private final Set<String> mModifiedPackages = new ArraySet<>();
+ private final Set<Uri> mUris = new ArraySet<>();
+
+ public VoicemailNotifier(Context context, Uri baseUri) {
+ mContext = context;
+ mBaseUri = baseUri;
+ mVoicemailPermissions = new VoicemailPermissions(mContext);
+ }
+
+ public void addIntentActions(String action) {
+ mIntentActions.add(action);
+ }
+
+ public void addModifiedPackages(Collection<String> packages) {
+ mModifiedPackages.addAll(packages);
+ }
+
+ public void addUri(Uri uri) {
+ mUris.add(uri);
+ }
+
+ public void sendNotification() {
+ Uri uri = mUris.size() == 1 ? mUris.iterator().next() : mBaseUri;
+ mContext.getContentResolver().notifyChange(uri, null, true);
+ Collection<String> callingPackages = getCallingPackages();
+ // Now fire individual intents.
+ for (String intentAction : mIntentActions) {
+ // self_change extra should be included only for provider_changed events.
+ boolean includeSelfChangeExtra = intentAction.equals(Intent.ACTION_PROVIDER_CHANGED);
+ Log.i(TAG, "receivers for " + intentAction + " :" + getBroadcastReceiverComponents(
+ intentAction, uri));
+ for (ComponentName component :
+ getBroadcastReceiverComponents(intentAction, uri)) {
+ // Ignore any package that is not affected by the change and don't have full access
+ // either.
+ if (!mModifiedPackages.contains(component.getPackageName()) &&
+ !mVoicemailPermissions.packageHasReadAccess(
+ component.getPackageName())) {
+ continue;
+ }
+
+ Intent intent = new Intent(intentAction, uri);
+ intent.setComponent(component);
+ if (includeSelfChangeExtra && callingPackages != null) {
+ intent.putExtra(VoicemailContract.EXTRA_SELF_CHANGE,
+ callingPackages.contains(component.getPackageName()));
+ }
+ String permissionNeeded = mModifiedPackages.contains(component.getPackageName()) ?
+ ADD_VOICEMAIL : READ_VOICEMAIL;
+ mContext.sendBroadcast(intent, permissionNeeded);
+ Log.v(TAG, String.format("Sent intent. act:%s, url:%s, comp:%s, perm:%s," +
+ " self_change:%s", intent.getAction(), intent.getData(),
+ component.getClassName(), permissionNeeded,
+ intent.hasExtra(VoicemailContract.EXTRA_SELF_CHANGE) ?
+ intent.getBooleanExtra(VoicemailContract.EXTRA_SELF_CHANGE, false) :
+ null));
+ }
+ }
+ mIntentActions.clear();
+ mModifiedPackages.clear();
+ mUris.clear();
+ }
+
+ /**
+ * Returns the package names of the calling process. If the calling process has more than
+ * one packages, this returns them all
+ */
+ private Collection<String> getCallingPackages() {
+ int caller = Binder.getCallingUid();
+ if (caller == 0) {
+ return null;
+ }
+ return Lists.newArrayList(mContext.getPackageManager().getPackagesForUid(caller));
+ }
+
+ /**
+ * Determines the components that can possibly receive the specified intent.
+ */
+ private List<ComponentName> getBroadcastReceiverComponents(String intentAction, Uri uri) {
+ Intent intent = new Intent(intentAction, uri);
+ List<ComponentName> receiverComponents = new ArrayList<ComponentName>();
+ // For broadcast receivers ResolveInfo.activityInfo is the one that is populated.
+ for (ResolveInfo resolveInfo :
+ mContext.getPackageManager().queryBroadcastReceivers(intent, 0)) {
+ ActivityInfo activityInfo = resolveInfo.activityInfo;
+ receiverComponents.add(new ComponentName(activityInfo.packageName, activityInfo.name));
+ }
+ return receiverComponents;
+ }
+}
diff --git a/src/com/android/providers/contacts/VoicemailStatusTable.java b/src/com/android/providers/contacts/VoicemailStatusTable.java
index f3008c0e..5b03c8a6 100644
--- a/src/com/android/providers/contacts/VoicemailStatusTable.java
+++ b/src/com/android/providers/contacts/VoicemailStatusTable.java
@@ -32,8 +32,6 @@ import android.util.ArraySet;
import com.android.common.content.ProjectionMap;
import com.android.providers.contacts.VoicemailContentProvider.UriData;
-import java.util.Set;
-
/**
* Implementation of {@link VoicemailTable.Delegate} for the voicemail status table.
*
@@ -78,7 +76,7 @@ public class VoicemailStatusTable implements VoicemailTable.Delegate {
SQLiteDatabase db = mDbHelper.getWritableDatabase();
// Try to update before insert.
String combinedClause = uriData.getWhereClause();
- int rowsChanged = getDatabaseModifier(db)
+ int rowsChanged = createDatabaseModifier(db)
.update(uriData.getUri(), mTableName, values, combinedClause, null);
if (rowsChanged != 0) {
final String[] selection = new String[] {Status._ID};
@@ -90,7 +88,7 @@ public class VoicemailStatusTable implements VoicemailTable.Delegate {
}
ContentValues copiedValues = new ContentValues(values);
mDelegateHelper.checkAndAddSourcePackageIntoValues(uriData, copiedValues);
- long rowId = getDatabaseModifier(db).insert(mTableName, null, copiedValues);
+ long rowId = createDatabaseModifier(db).insert(mTableName, null, copiedValues);
if (rowId > 0) {
return ContentUris.withAppendedId(uriData.getUri(), rowId);
} else {
@@ -100,11 +98,23 @@ public class VoicemailStatusTable implements VoicemailTable.Delegate {
}
@Override
+ public int bulkInsert(UriData uriData, ContentValues[] values) {
+ int count = 0;
+ for (ContentValues value : values) {
+ Uri uri = insert(uriData, value);
+ if (uri != null) {
+ count++;
+ }
+ }
+ return count;
+ }
+
+ @Override
public int delete(UriData uriData, String selection, String[] selectionArgs) {
synchronized (DATABASE_LOCK) {
SQLiteDatabase db = mDbHelper.getWritableDatabase();
String combinedClause = concatenateClauses(selection, uriData.getWhereClause());
- return getDatabaseModifier(db).delete(mTableName, combinedClause,
+ return createDatabaseModifier(db).delete(mTableName, combinedClause,
selectionArgs);
}
}
@@ -135,7 +145,7 @@ public class VoicemailStatusTable implements VoicemailTable.Delegate {
synchronized (DATABASE_LOCK) {
SQLiteDatabase db = mDbHelper.getWritableDatabase();
String combinedClause = concatenateClauses(selection, uriData.getWhereClause());
- return getDatabaseModifier(db)
+ return createDatabaseModifier(db)
.update(uriData.getUri(), mTableName, values, combinedClause, selectionArgs);
}
}
@@ -154,7 +164,7 @@ public class VoicemailStatusTable implements VoicemailTable.Delegate {
throw new UnsupportedOperationException("File operation is not supported for status table");
}
- private DatabaseModifier getDatabaseModifier(SQLiteDatabase db) {
+ private DatabaseModifier createDatabaseModifier(SQLiteDatabase db) {
return new DbModifierWithNotification(mTableName, db, mContext);
}
diff --git a/src/com/android/providers/contacts/VoicemailTable.java b/src/com/android/providers/contacts/VoicemailTable.java
index fcb653ce..f71b50de 100644
--- a/src/com/android/providers/contacts/VoicemailTable.java
+++ b/src/com/android/providers/contacts/VoicemailTable.java
@@ -46,6 +46,8 @@ public interface VoicemailTable {
public ParcelFileDescriptor openFile(UriData uriData, String mode)
throws FileNotFoundException;
public ArraySet<String> getSourcePackages();
+
+ int bulkInsert(UriData uriData, ContentValues[] values);
}
/**