diff options
author | TreeHugger Robot <treehugger-gerrit@google.com> | 2017-10-17 23:31:38 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2017-10-17 23:31:38 +0000 |
commit | 5e097c0c0e687c80ae46006a692dc12393903126 (patch) | |
tree | cffd071953c4068cecbf2448dc7e333adc58ab23 /src | |
parent | 551d31e5acd9ad772ca5fbde4aa66207b1258fab (diff) | |
parent | c28f7969399fcb667d02de4030fba0fc40ff9130 (diff) | |
download | ContactsProvider-5e097c0c0e687c80ae46006a692dc12393903126.tar.gz |
Merge "Implement bulkInsert for VoicemailProvider"
Diffstat (limited to 'src')
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); } /** |