diff options
Diffstat (limited to 'src/com/android/providers/contacts/CallLogProvider.java')
-rw-r--r-- | src/com/android/providers/contacts/CallLogProvider.java | 122 |
1 files changed, 112 insertions, 10 deletions
diff --git a/src/com/android/providers/contacts/CallLogProvider.java b/src/com/android/providers/contacts/CallLogProvider.java index 59e9b147..f71a7503 100644 --- a/src/com/android/providers/contacts/CallLogProvider.java +++ b/src/com/android/providers/contacts/CallLogProvider.java @@ -22,10 +22,13 @@ import static com.android.providers.contacts.util.DbQueryUtils.getInequalityClau import android.app.AppOpsManager; import android.content.ContentProvider; +import android.content.ContentProviderOperation; +import android.content.ContentProviderResult; import android.content.ContentResolver; import android.content.ContentUris; import android.content.ContentValues; import android.content.Context; +import android.content.OperationApplicationException; import android.content.UriMatcher; import android.database.Cursor; import android.database.DatabaseUtils; @@ -45,11 +48,15 @@ import android.util.ArrayMap; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.util.ProviderAccessStats; import com.android.providers.contacts.CallLogDatabaseHelper.DbProperties; import com.android.providers.contacts.CallLogDatabaseHelper.Tables; import com.android.providers.contacts.util.SelectionBuilder; import com.android.providers.contacts.util.UserUtils; +import java.io.FileDescriptor; +import java.io.PrintWriter; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.concurrent.CountDownLatch; @@ -175,6 +182,10 @@ public class CallLogProvider extends ContentProvider { private VoicemailPermissions mVoicemailPermissions; private CallLogInsertionHelper mCallLogInsertionHelper; + private final ThreadLocal<Boolean> mApplyingBatch = new ThreadLocal<>(); + private final ThreadLocal<Integer> mCallingUid = new ThreadLocal<>(); + private final ProviderAccessStats mStats = new ProviderAccessStats(); + protected boolean isShadow() { return false; } @@ -228,9 +239,58 @@ public class CallLogProvider extends ContentProvider { return CallLogDatabaseHelper.getInstance(context); } + protected boolean applyingBatch() { + final Boolean applying = mApplyingBatch.get(); + return applying != null && applying; + } + + @Override + public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations) + throws OperationApplicationException { + final int callingUid = Binder.getCallingUid(); + mCallingUid.set(callingUid); + + mStats.incrementBatchStats(callingUid); + mApplyingBatch.set(true); + try { + return super.applyBatch(operations); + } finally { + mApplyingBatch.set(false); + mStats.finishOperation(callingUid); + } + } + + @Override + public int bulkInsert(Uri uri, ContentValues[] values) { + final int callingUid = Binder.getCallingUid(); + mCallingUid.set(callingUid); + + mStats.incrementBatchStats(callingUid); + mApplyingBatch.set(true); + try { + return super.bulkInsert(uri, values); + } finally { + mApplyingBatch.set(false); + mStats.finishOperation(callingUid); + } + } + @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { + // Note don't use mCallingUid here. That's only used by mutation functions. + final int callingUid = Binder.getCallingUid(); + + mStats.incrementQueryStats(callingUid); + try { + return queryInternal(uri, projection, selection, selectionArgs, sortOrder); + } finally { + mStats.finishOperation(callingUid); + } + } + + private Cursor queryInternal(Uri uri, String[] projection, String selection, + String[] selectionArgs, String sortOrder) { if (VERBOSE_LOGGING) { Log.v(TAG, "query: uri=" + uri + " projection=" + Arrays.toString(projection) + " selection=[" + selection + "] args=" + Arrays.toString(selectionArgs) + @@ -361,6 +421,44 @@ public class CallLogProvider extends ContentProvider { @Override public Uri insert(Uri uri, ContentValues values) { + final int callingUid = + applyingBatch() ? mCallingUid.get() : Binder.getCallingUid(); + + mStats.incrementInsertStats(callingUid, applyingBatch()); + try { + return insertInternal(uri, values); + } finally { + mStats.finishOperation(callingUid); + } + } + + @Override + public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { + final int callingUid = + applyingBatch() ? mCallingUid.get() : Binder.getCallingUid(); + + mStats.incrementInsertStats(callingUid, applyingBatch()); + try { + return updateInternal(uri, values, selection, selectionArgs); + } finally { + mStats.finishOperation(callingUid); + } + } + + @Override + public int delete(Uri uri, String selection, String[] selectionArgs) { + final int callingUid = + applyingBatch() ? mCallingUid.get() : Binder.getCallingUid(); + + mStats.incrementInsertStats(callingUid, applyingBatch()); + try { + return deleteInternal(uri, selection, selectionArgs); + } finally { + mStats.finishOperation(callingUid); + } + } + + private Uri insertInternal(Uri uri, ContentValues values) { if (VERBOSE_LOGGING) { Log.v(TAG, "insert: uri=" + uri + " values=[" + values + "]" + " CPID=" + Binder.getCallingPid()); @@ -383,15 +481,15 @@ 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); } return null; } - @Override - public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { + private int updateInternal(Uri uri, ContentValues values, + String selection, String[] selectionArgs) { if (VERBOSE_LOGGING) { Log.v(TAG, "update: uri=" + uri + " selection=[" + selection + "] args=" + Arrays.toString(selectionArgs) + @@ -423,12 +521,11 @@ 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); } - @Override - public int delete(Uri uri, String selection, String[] selectionArgs) { + private int deleteInternal(Uri uri, String selection, String[] selectionArgs) { if (VERBOSE_LOGGING) { Log.v(TAG, "delete: uri=" + uri + " selection=[" + selection + "] args=" + Arrays.toString(selectionArgs) + @@ -445,7 +542,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 +557,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()); } @@ -753,4 +850,9 @@ public class CallLogProvider extends ContentProvider { public void shutdown() { mTaskScheduler.shutdownForTest(); } + + @Override + public void dump(FileDescriptor fd, PrintWriter writer, String[] args) { + mStats.dump(writer, " "); + } } |