diff options
author | Xin Li <delphij@google.com> | 2020-09-01 20:03:59 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2020-09-01 20:03:59 +0000 |
commit | ca343420fe23f74ef8ac94b2991cf49ce0d157c0 (patch) | |
tree | 0800aa922f7c115d2d3b6f2ed753d2181e699ae4 /src | |
parent | e98011c6064fd0b3ed62ca1f09369e5cd98618e0 (diff) | |
parent | fe7ff0defba5f0e3e5235584c2a53d26f02fe161 (diff) | |
download | ContactsProvider-ca343420fe23f74ef8ac94b2991cf49ce0d157c0.tar.gz |
Merge "Merge Android R (rvc-dev-plus-aosp-without-vendor@6692709)" into stage-aosp-master
Diffstat (limited to 'src')
4 files changed, 155 insertions, 187 deletions
diff --git a/src/com/android/providers/contacts/CallLogProvider.java b/src/com/android/providers/contacts/CallLogProvider.java index f9aa4843..ebe111f1 100644 --- a/src/com/android/providers/contacts/CallLogProvider.java +++ b/src/com/android/providers/contacts/CallLogProvider.java @@ -314,6 +314,7 @@ public class CallLogProvider extends ContentProvider { Log.v(TAG, "query: uri=" + uri + " projection=" + Arrays.toString(projection) + " selection=[" + selection + "] args=" + Arrays.toString(selectionArgs) + " order=[" + sortOrder + "] CPID=" + Binder.getCallingPid() + + " CUID=" + Binder.getCallingUid() + " User=" + UserUtils.getCurrentUserHandle(getContext())); } @@ -488,7 +489,8 @@ public class CallLogProvider extends ContentProvider { private Uri insertInternal(Uri uri, ContentValues values) { if (VERBOSE_LOGGING) { Log.v(TAG, "insert: uri=" + uri + " values=[" + values + "]" + - " CPID=" + Binder.getCallingPid()); + " CPID=" + Binder.getCallingPid() + + " CUID=" + Binder.getCallingUid()); } waitForAccess(mReadAccessLatch); checkForSupportedColumns(sCallsProjectionMap, values); @@ -521,6 +523,7 @@ public class CallLogProvider extends ContentProvider { Log.v(TAG, "update: uri=" + uri + " selection=[" + selection + "] args=" + Arrays.toString(selectionArgs) + " values=[" + values + "] CPID=" + Binder.getCallingPid() + + " CUID=" + Binder.getCallingUid() + " User=" + UserUtils.getCurrentUserHandle(getContext())); } waitForAccess(mReadAccessLatch); @@ -568,6 +571,7 @@ public class CallLogProvider extends ContentProvider { Log.v(TAG, "delete: uri=" + uri + " selection=[" + selection + "] args=" + Arrays.toString(selectionArgs) + " CPID=" + Binder.getCallingPid() + + " CUID=" + Binder.getCallingUid() + " User=" + UserUtils.getCurrentUserHandle(getContext())); } waitForAccess(mReadAccessLatch); diff --git a/src/com/android/providers/contacts/ContactsProvider2.java b/src/com/android/providers/contacts/ContactsProvider2.java index b92a9178..5159fb94 100644 --- a/src/com/android/providers/contacts/ContactsProvider2.java +++ b/src/com/android/providers/contacts/ContactsProvider2.java @@ -16,6 +16,10 @@ package com.android.providers.contacts; +import static android.content.pm.PackageManager.PERMISSION_GRANTED; +import static android.Manifest.permission.INTERACT_ACROSS_USERS; +import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; + import android.accounts.Account; import android.accounts.AccountManager; import android.accounts.OnAccountsUpdateListener; @@ -214,7 +218,6 @@ public class ContactsProvider2 extends AbstractContactsProvider private static final String READ_PERMISSION = "android.permission.READ_CONTACTS"; private static final String WRITE_PERMISSION = "android.permission.WRITE_CONTACTS"; - private static final String INTERACT_ACROSS_USERS = "android.permission.INTERACT_ACROSS_USERS"; /* package */ static final String PHONEBOOK_COLLATOR_NAME = "PHONEBOOK"; @@ -532,23 +535,6 @@ public class ContactsProvider2 extends AbstractContactsProvider " SET " + RawContacts.DIRTY + "=1" + " WHERE " + RawContacts._ID + " IN ("; - /** Sql for updating METADATA_DIRTY flag on multiple raw contacts */ - private static final String UPDATE_RAW_CONTACT_SET_METADATA_DIRTY_SQL = - "UPDATE " + Tables.RAW_CONTACTS + - " SET " + RawContacts.METADATA_DIRTY + "=1" + - " WHERE " + RawContacts._ID + " IN ("; - - // Sql for updating MetadataSync.DELETED flag on multiple raw contacts. - // When using this sql, add comma separated raw contacts ids and "))". - private static final String UPDATE_METADATASYNC_SET_DELETED_SQL = - "UPDATE " + Tables.METADATA_SYNC - + " SET " + MetadataSync.DELETED + "=1" - + " WHERE " + MetadataSync._ID + " IN " - + "(SELECT " + MetadataSyncColumns.CONCRETE_ID - + " FROM " + Tables.RAW_CONTACTS_JOIN_METADATA_SYNC - + " WHERE " + RawContactsColumns.CONCRETE_DELETED + "=1 AND " - + RawContactsColumns.CONCRETE_ID + " IN ("; - /** Sql for updating VERSION on multiple raw contacts */ private static final String UPDATE_RAW_CONTACT_SET_VERSION_SQL = "UPDATE " + Tables.RAW_CONTACTS + @@ -2433,14 +2419,6 @@ public class ContactsProvider2 extends AbstractContactsProvider for (long rawContactId : mTransactionContext.get().getInsertedRawContactIds()) { mDbHelper.get().updateRawContactDisplayName(db, rawContactId); mAggregator.get().onRawContactInsert(mTransactionContext.get(), db, rawContactId); - if (mMetadataSyncEnabled) { - updateMetadataOnRawContactInsert(db, rawContactId); - } - } - if (mMetadataSyncEnabled) { - for (long rawContactId : mTransactionContext.get().getBackupIdChangedRawContacts()) { - updateMetadataOnRawContactInsert(db, rawContactId); - } } final Set<Long> dirtyRawContacts = mTransactionContext.get().getDirtyRawContactIds(); @@ -2461,29 +2439,8 @@ public class ContactsProvider2 extends AbstractContactsProvider db.execSQL(mSb.toString()); } - final Set<Long> metadataDirtyRawContacts = - mTransactionContext.get().getMetadataDirtyRawContactIds(); - if (!metadataDirtyRawContacts.isEmpty() && mMetadataSyncEnabled) { - mSb.setLength(0); - mSb.append(UPDATE_RAW_CONTACT_SET_METADATA_DIRTY_SQL); - appendIds(mSb, metadataDirtyRawContacts); - mSb.append(")"); - db.execSQL(mSb.toString()); - mSyncToMetadataNetWork = true; - } - final Set<Long> changedRawContacts = mTransactionContext.get().getChangedRawContactIds(); ContactsTableUtil.updateContactLastUpdateByRawContactId(db, changedRawContacts); - if (!changedRawContacts.isEmpty() && mMetadataSyncEnabled) { - // For the deleted raw contact, set related metadata as deleted - // if metadata flag is enabled. - mSb.setLength(0); - mSb.append(UPDATE_METADATASYNC_SET_DELETED_SQL); - appendIds(mSb, changedRawContacts); - mSb.append("))"); - db.execSQL(mSb.toString()); - mSyncToMetadataNetWork = true; - } // Update sync states. for (Map.Entry<Long, Object> entry : mTransactionContext.get().getUpdatedSyncStates()) { @@ -2502,49 +2459,6 @@ public class ContactsProvider2 extends AbstractContactsProvider mMetadataSyncEnabled = enabled; } - interface MetadataSyncQuery { - String TABLE = Tables.RAW_CONTACTS_JOIN_METADATA_SYNC; - String[] COLUMNS = new String[] { - MetadataSyncColumns.CONCRETE_ID, - MetadataSync.DATA - }; - int METADATA_SYNC_ID = 0; - int METADATA_SYNC_DATA = 1; - String SELECTION = MetadataSyncColumns.CONCRETE_DELETED + "=0 AND " + - RawContactsColumns.CONCRETE_ID + "=?"; - } - - /** - * Fetch the related metadataSync data column for the raw contact id. - * Returns null if there's no metadata for the raw contact. - */ - private String queryMetadataSyncData(SQLiteDatabase db, long rawContactId) { - String metadataSyncData = null; - mSelectionArgs1[0] = String.valueOf(rawContactId); - final Cursor cursor = db.query(MetadataSyncQuery.TABLE, - MetadataSyncQuery.COLUMNS, MetadataSyncQuery.SELECTION, - mSelectionArgs1, null, null, null); - try { - if (cursor.moveToFirst()) { - metadataSyncData = cursor.getString(MetadataSyncQuery.METADATA_SYNC_DATA); - } - } finally { - cursor.close(); - } - return metadataSyncData; - } - - private void updateMetadataOnRawContactInsert(SQLiteDatabase db, long rawContactId) { - // Read metadata from MetadataSync table for the raw contact, and update. - final String metadataSyncData = queryMetadataSyncData(db, rawContactId); - if (TextUtils.isEmpty(metadataSyncData)) { - return; - } - final MetadataEntry metadataEntry = MetadataEntryParser.parseDataToMetaDataEntry( - metadataSyncData); - updateFromMetaDataEntry(db, metadataEntry); - } - /** * Appends comma separated IDs. * @param ids Should not be empty @@ -2566,10 +2480,7 @@ public class ContactsProvider2 extends AbstractContactsProvider protected void notifyChange(boolean syncToNetwork, boolean syncToMetadataNetwork) { getContext().getContentResolver().notifyChange(ContactsContract.AUTHORITY_URI, null, - syncToNetwork || syncToMetadataNetwork); - - getContext().getContentResolver().notifyChange(MetadataSync.METADATA_AUTHORITY_URI, - null, syncToMetadataNetwork); + syncToNetwork); } protected void setProviderStatus(int status) { @@ -2606,7 +2517,8 @@ public class ContactsProvider2 extends AbstractContactsProvider protected Uri insertInTransaction(Uri uri, ContentValues values) { if (VERBOSE_LOGGING) { Log.v(TAG, "insertInTransaction: uri=" + uri + " values=[" + values + "]" + - " CPID=" + Binder.getCallingPid()); + " CPID=" + Binder.getCallingPid() + + " CUID=" + Binder.getCallingUid()); } final SQLiteDatabase db = mDbHelper.get().getWritableDatabase(); @@ -2836,7 +2748,6 @@ public class ContactsProvider2 extends AbstractContactsProvider values.put(RawContacts.AGGREGATION_MODE, RawContacts.AGGREGATION_MODE_DISABLED); } - final boolean needToUpdateMetadata = shouldMarkMetadataDirtyForRawContact(values); // Databases that were created prior to the 906 upgrade have a default of Int.MAX_VALUE // for RawContacts.PINNED. Manually set the value to the correct default (0) if it is not // set. @@ -2848,14 +2759,6 @@ public class ContactsProvider2 extends AbstractContactsProvider final SQLiteDatabase db = mDbHelper.get().getWritableDatabase(); final long rawContactId = db.insert(Tables.RAW_CONTACTS, RawContacts.CONTACT_ID, values); - if (needToUpdateMetadata) { - mTransactionContext.get().markRawContactMetadataDirty(rawContactId, - /* isMetadataSyncAdapter =*/false); - } - // If the new raw contact is inserted by a sync adapter, mark mSyncToMetadataNetWork as true - // so that it can trigger the metadata syncing from the server. - mSyncToMetadataNetWork |= callerIsSyncAdapter; - final int aggregationMode = getIntValue(values, RawContacts.AGGREGATION_MODE, RawContacts.AGGREGATION_MODE_DEFAULT); mAggregator.get().markNewForAggregation(rawContactId, aggregationMode); @@ -3550,6 +3453,7 @@ public class ContactsProvider2 extends AbstractContactsProvider Log.v(TAG, "deleteInTransaction: uri=" + uri + " selection=[" + selection + "] args=" + Arrays.toString(selectionArgs) + " CPID=" + Binder.getCallingPid() + + " CUID=" + Binder.getCallingUid() + " User=" + UserUtils.getCurrentUserHandle(getContext())); } @@ -3802,15 +3706,25 @@ public class ContactsProvider2 extends AbstractContactsProvider } private int deleteContact(long contactId, boolean callerIsSyncAdapter) { + ArrayList<Long> localRawContactIds = new ArrayList(); + final SQLiteDatabase db = mDbHelper.get().getWritableDatabase(); mSelectionArgs1[0] = Long.toString(contactId); Cursor c = db.query(Tables.RAW_CONTACTS, new String[] {RawContacts._ID}, RawContacts.CONTACT_ID + "=?", mSelectionArgs1, null, null, null); + + // Raw contacts need to be deleted after the contact so just loop through and mark + // non-local raw contacts as deleted and collect the local raw contacts that will be + // deleted after the contact is deleted. try { while (c.moveToNext()) { long rawContactId = c.getLong(0); - markRawContactAsDeleted(db, rawContactId, callerIsSyncAdapter); + if (rawContactIsLocal(rawContactId)) { + localRawContactIds.add(rawContactId); + } else { + markRawContactAsDeleted(db, rawContactId, callerIsSyncAdapter); + } } } finally { c.close(); @@ -3819,6 +3733,10 @@ public class ContactsProvider2 extends AbstractContactsProvider mProviderStatusUpdateNeeded = true; int result = ContactsTableUtil.deleteContact(db, contactId); + + // Now purge the local raw contacts + deleteRawContactsImmediately(db, localRawContactIds); + scheduleBackgroundTask(BACKGROUND_TASK_CLEAN_DELETE_LOG); return result; } @@ -3842,19 +3760,19 @@ public class ContactsProvider2 extends AbstractContactsProvider c.close(); } + // When a raw contact is deleted, a sqlite trigger deletes the parent contact. + // TODO: all contact deletes was consolidated into ContactTableUtil but this one can't + // because it's in a trigger. Consider removing trigger and replacing with java code. + // This has to happen before the raw contact is deleted since it relies on the number + // of raw contacts. final boolean contactIsSingleton = ContactsTableUtil.deleteContactIfSingleton(db, rawContactId) == 1; final int count; if (callerIsSyncAdapter || rawContactIsLocal(rawContactId)) { - // When a raw contact is deleted, a SQLite trigger deletes the parent contact. - // TODO: all contact deletes was consolidated into ContactTableUtil but this one can't - // because it's in a trigger. Consider removing trigger and replacing with java code. - // This has to happen before the raw contact is deleted since it relies on the number - // of raw contacts. - db.delete(Tables.PRESENCE, PresenceColumns.RAW_CONTACT_ID + "=" + rawContactId, null); - count = db.delete(Tables.RAW_CONTACTS, RawContacts._ID + "=" + rawContactId, null); - mTransactionContext.get().markRawContactChangedOrDeletedOrInserted(rawContactId); + ArrayList<Long> rawContactsIds = new ArrayList<>(); + rawContactsIds.add(rawContactId); + count = deleteRawContactsImmediately(db, rawContactsIds); } else { count = markRawContactAsDeleted(db, rawContactId, callerIsSyncAdapter); } @@ -3865,6 +3783,43 @@ public class ContactsProvider2 extends AbstractContactsProvider } /** + * Returns the number of raw contacts that were deleted immediately -- we don't merely set + * the DELETED column to 1, the entire raw contact row is deleted straightaway. + */ + private int deleteRawContactsImmediately(SQLiteDatabase db, List<Long> rawContactIds) { + if (rawContactIds == null || rawContactIds.isEmpty()) { + return 0; + } + + // Build the where clause for the raw contacts to be deleted + ArrayList<String> whereArgs = new ArrayList<>(); + StringBuilder whereClause = new StringBuilder(rawContactIds.size() * 2 - 1); + whereClause.append(" IN (?"); + whereArgs.add(String.valueOf(rawContactIds.get(0))); + for (int i = 1; i < rawContactIds.size(); i++) { + whereClause.append(",?"); + whereArgs.add(String.valueOf(rawContactIds.get(i))); + } + whereClause.append(")"); + + // Remove presence rows + db.delete(Tables.PRESENCE, PresenceColumns.RAW_CONTACT_ID + whereClause.toString(), + whereArgs.toArray(new String[0])); + + // Remove raw contact rows + int result = db.delete(Tables.RAW_CONTACTS, RawContacts._ID + whereClause.toString(), + whereArgs.toArray(new String[0])); + + if (result > 0) { + for (Long rawContactId : rawContactIds) { + mTransactionContext.get().markRawContactChangedOrDeletedOrInserted(rawContactId); + } + } + + return result; + } + + /** * Returns whether the given raw contact ID is local (i.e. has no account associated with it). */ private boolean rawContactIsLocal(long rawContactId) { @@ -3964,6 +3919,7 @@ public class ContactsProvider2 extends AbstractContactsProvider Log.v(TAG, "updateInTransaction: uri=" + uri + " selection=[" + selection + "] args=" + Arrays.toString(selectionArgs) + " values=[" + values + "] CPID=" + Binder.getCallingPid() + + " CUID=" + Binder.getCallingUid() + " User=" + UserUtils.getCurrentUserHandle(getContext())); } @@ -4498,7 +4454,6 @@ public class ContactsProvider2 extends AbstractContactsProvider final boolean isDataSetChanging = values.containsKey(RawContacts.DATA_SET); final boolean isAccountChanging = isAccountNameChanging || isAccountTypeChanging || isDataSetChanging; - final boolean isBackupIdChanging = values.containsKey(RawContacts.BACKUP_ID); int previousDeleted = 0; long accountId = 0; @@ -4561,32 +4516,6 @@ public class ContactsProvider2 extends AbstractContactsProvider if (aggregationMode != RawContacts.AGGREGATION_MODE_DEFAULT) { aggregator.markForAggregation(rawContactId, aggregationMode, false); } - if (shouldMarkMetadataDirtyForRawContact(values)) { - mTransactionContext.get().markRawContactMetadataDirty( - rawContactId, callerIsMetadataSyncAdapter); - } - if (isBackupIdChanging) { - Cursor cursor = db.query(Tables.RAW_CONTACTS, - new String[] {RawContactsColumns.CONCRETE_METADATA_DIRTY}, - selection, mSelectionArgs1, null, null, null); - int metadataDirty = 0; - try { - if (cursor.moveToFirst()) { - metadataDirty = cursor.getInt(0); - } - } finally { - cursor.close(); - } - - if (metadataDirty == 1) { - // Re-notify metadata network if backup_id is updated and metadata is dirty. - mTransactionContext.get().markRawContactMetadataDirty( - rawContactId, callerIsMetadataSyncAdapter); - } else { - // Merge from metadata sync table if backup_id is updated and no dirty change. - mTransactionContext.get().markBackupIdChangedRawContact(rawContactId); - } - } if (flagExists(values, RawContacts.STARRED)) { if (!callerIsSyncAdapter) { updateFavoritesMembership(rawContactId, flagIsSet(values, RawContacts.STARRED)); @@ -4760,10 +4689,6 @@ public class ContactsProvider2 extends AbstractContactsProvider // Mark dirty when changing starred to trigger sync. values.put(RawContacts.DIRTY, 1); } - if (mMetadataSyncEnabled && (hasStarredValue || hasPinnedValue || hasVoiceMailValue)) { - // Mark dirty to trigger metadata syncing. - values.put(RawContacts.METADATA_DIRTY, 1); - } mSelectionArgs1[0] = String.valueOf(contactId); db.update(Tables.RAW_CONTACTS, values, RawContacts.CONTACT_ID + "=?" @@ -4781,11 +4706,6 @@ public class ContactsProvider2 extends AbstractContactsProvider flagIsSet(values, RawContacts.STARRED)); mSyncToNetwork |= !callerIsSyncAdapter; } - - if (hasStarredValue || hasPinnedValue || hasVoiceMailValue) { - mTransactionContext.get().markRawContactMetadataDirty(rawContactId, - false /*callerIsMetadataSyncAdapter*/); - } } } finally { cursor.close(); @@ -4863,21 +4783,12 @@ public class ContactsProvider2 extends AbstractContactsProvider aggregator.aggregateContact(mTransactionContext.get(), db, rawContactId1); aggregator.aggregateContact(mTransactionContext.get(), db, rawContactId2); - mTransactionContext.get().markRawContactMetadataDirty(rawContactId1, - callerIsMetadataSyncAdapter); - mTransactionContext.get().markRawContactMetadataDirty(rawContactId2, - callerIsMetadataSyncAdapter); // The return value is fake - we just confirm that we made a change, not count actual // rows changed. return 1; } - private boolean shouldMarkMetadataDirtyForRawContact(ContentValues values) { - return (flagExists(values, RawContacts.STARRED) || flagExists(values, RawContacts.PINNED) - || flagExists(values, RawContacts.SEND_TO_VOICEMAIL)); - } - @Override public void onAccountsUpdated(Account[] accounts) { scheduleBackgroundTask(BACKGROUND_TASK_UPDATE_ACCOUNTS); @@ -5441,6 +5352,7 @@ public class ContactsProvider2 extends AbstractContactsProvider Log.v(TAG, "query: uri=" + uri + " projection=" + Arrays.toString(projection) + " selection=[" + selection + "] args=" + Arrays.toString(selectionArgs) + " order=[" + sortOrder + "] CPID=" + Binder.getCallingPid() + + " CUID=" + Binder.getCallingUid() + " User=" + UserUtils.getCurrentUserHandle(getContext())); } @@ -5454,10 +5366,12 @@ public class ContactsProvider2 extends AbstractContactsProvider return null; } - // Check enterprise policy if caller does not come from same profile - if (!(isCallerFromSameUser() || mEnterprisePolicyGuard.isCrossProfileAllowed(uri))) { - return createEmptyCursor(uri, projection); + // If caller does not come from same profile, Check if it's privileged or allowed by + // enterprise policy + if (!queryAllowedByEnterprisePolicy(uri)) { + return null; } + // Query the profile DB if appropriate. if (mapsToProfileDb(uri)) { switchToProfileMode(); @@ -5477,9 +5391,46 @@ public class ContactsProvider2 extends AbstractContactsProvider } } + private boolean queryAllowedByEnterprisePolicy(Uri uri) { + if (isCallerFromSameUser()) { + // Caller is on the same user; query allowed. + return true; + } + if (!doesCallerHoldInteractAcrossUserPermission()) { + // Cross-user and the caller has no INTERACT_ACROSS_USERS; don't allow query. + // Technically, in a cross-profile sharing case, this would be a valid query. + // But for now we don't allow it. (We never allowe it and no one complained about it.) + return false; + } + if (isCallerAnotherSelf()) { + // The caller is the other CP2 (which has INTERACT_ACROSS_USERS), meaning the reuest + // is on behalf of a "real" client app. + // Consult the enterprise policy. + return mEnterprisePolicyGuard.isCrossProfileAllowed(uri); + } + return true; + } + private boolean isCallerFromSameUser() { - return Binder.getCallingUserHandle().getIdentifier() == UserUtils - .getCurrentUserHandle(getContext()); + return UserHandle.getUserId(Binder.getCallingUid()) == UserHandle.myUserId(); + } + + /** + * Returns true if called by a different user's CP2. + */ + private boolean isCallerAnotherSelf() { + // Note normally myUid is always different from the callerUid in the code path where + // this method is used, except during unit tests, where the caller is always the same + // process. + final int myUid = android.os.Process.myUid(); + final int callingUid = Binder.getCallingUid(); + return (myUid != callingUid) && UserHandle.isSameApp(myUid, callingUid); + } + + private boolean doesCallerHoldInteractAcrossUserPermission() { + final Context context = getContext(); + return context.checkCallingPermission(INTERACT_ACROSS_USERS_FULL) == PERMISSION_GRANTED + || context.checkCallingPermission(INTERACT_ACROSS_USERS) == PERMISSION_GRANTED; } private Cursor queryDirectoryIfNecessary(Uri uri, String[] projection, String selection, @@ -5526,7 +5477,7 @@ public class ContactsProvider2 extends AbstractContactsProvider private String getRealCallerPackageName(Uri queryUri) { // If called by another CP2, then the URI should contain the original package name. - if (calledByAnotherSelf()) { + if (isCallerAnotherSelf()) { final String passedPackage = queryUri.getQueryParameter( Directory.CALLER_PACKAGE_PARAM_KEY); if (TextUtils.isEmpty(passedPackage)) { @@ -5541,18 +5492,6 @@ public class ContactsProvider2 extends AbstractContactsProvider } } - /** - * Returns true if called by a different user's CP2. - */ - private boolean calledByAnotherSelf() { - // Note normally myUid is always different from the callerUid in the code path where - // this method is used, except during unit tests, where the caller is always the same - // process. - final int myUid = android.os.Process.myUid(); - final int callerUid = Binder.getCallingUid(); - return (myUid != callerUid) && UserHandle.isSameApp(myUid, callerUid); - } - private Cursor queryDirectoryAuthority(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder, String directory, final CancellationSignal cancellationSignal) { @@ -8525,9 +8464,7 @@ public class ContactsProvider2 extends AbstractContactsProvider if (!isDirectoryParamValid(uri)){ return null; } - if (!isCallerFromSameUser() /* From differnt user */ - && !mEnterprisePolicyGuard.isCrossProfileAllowed(uri) - /* Policy not allowed */){ + if (!queryAllowedByEnterprisePolicy(uri)) { return null; } waitForAccess(mode.equals("r") ? mReadAccessLatch : mWriteAccessLatch); @@ -8545,6 +8482,7 @@ public class ContactsProvider2 extends AbstractContactsProvider if (VERBOSE_LOGGING) { Log.v(TAG, "openAssetFile uri=" + uri + " mode=" + mode + " success=" + success + " CPID=" + Binder.getCallingPid() + + " CUID=" + Binder.getCallingUid() + " User=" + UserUtils.getCurrentUserHandle(getContext())); } } diff --git a/src/com/android/providers/contacts/MetadataEntryParser.java b/src/com/android/providers/contacts/MetadataEntryParser.java index 1a630a33..2fe423a8 100644 --- a/src/com/android/providers/contacts/MetadataEntryParser.java +++ b/src/com/android/providers/contacts/MetadataEntryParser.java @@ -60,8 +60,11 @@ public class MetadataEntryParser { @NeededForTesting public static class UsageStats { + @NeededForTesting final String mUsageType; + @NeededForTesting final long mLastTimeUsed; + @NeededForTesting final int mTimesUsed; @NeededForTesting @@ -74,9 +77,13 @@ public class MetadataEntryParser { @NeededForTesting public static class FieldData { + @NeededForTesting final String mDataHashId; + @NeededForTesting final boolean mIsPrimary; + @NeededForTesting final boolean mIsSuperPrimary; + @NeededForTesting final ArrayList<UsageStats> mUsageStatsList; @NeededForTesting @@ -91,9 +98,13 @@ public class MetadataEntryParser { @NeededForTesting public static class RawContactInfo { + @NeededForTesting final String mBackupId; + @NeededForTesting final String mAccountType; + @NeededForTesting final String mAccountName; + @NeededForTesting final String mDataSet; @NeededForTesting @@ -108,8 +119,11 @@ public class MetadataEntryParser { @NeededForTesting public static class AggregationData { + @NeededForTesting final RawContactInfo mRawContactInfo1; + @NeededForTesting final RawContactInfo mRawContactInfo2; + @NeededForTesting final String mType; @NeededForTesting @@ -123,11 +137,17 @@ public class MetadataEntryParser { @NeededForTesting public static class MetadataEntry { + @NeededForTesting final RawContactInfo mRawContactInfo; + @NeededForTesting final int mSendToVoicemail; + @NeededForTesting final int mStarred; + @NeededForTesting final int mPinned; + @NeededForTesting final ArrayList<FieldData> mFieldDatas; + @NeededForTesting final ArrayList<AggregationData> mAggregationDatas; @NeededForTesting diff --git a/src/com/android/providers/contacts/VoicemailContentProvider.java b/src/com/android/providers/contacts/VoicemailContentProvider.java index 1ced1be6..daecd973 100644 --- a/src/com/android/providers/contacts/VoicemailContentProvider.java +++ b/src/com/android/providers/contacts/VoicemailContentProvider.java @@ -22,6 +22,7 @@ import static com.android.providers.contacts.util.DbQueryUtils.concatenateClause import static com.android.providers.contacts.util.DbQueryUtils.getEqualityClause; import android.annotation.NonNull; +import android.annotation.Nullable; import android.app.AppOpsManager; import android.content.ContentProvider; import android.content.ContentValues; @@ -118,24 +119,24 @@ public class VoicemailContentProvider extends ContentProvider } @Override - protected int enforceReadPermissionInner(Uri uri, String callingPkg, IBinder callerToken) - throws SecurityException { + protected int enforceReadPermissionInner(Uri uri, String callingPkg, + @Nullable String featureId, IBinder callerToken) throws SecurityException { // Permit carrier-privileged apps regardless of ADD_VOICEMAIL permission state. if (mVoicemailPermissions.callerHasCarrierPrivileges()) { return MODE_ALLOWED; } - return super.enforceReadPermissionInner(uri, callingPkg, callerToken); + return super.enforceReadPermissionInner(uri, callingPkg, featureId, callerToken); } @Override - protected int enforceWritePermissionInner(Uri uri, String callingPkg, IBinder callerToken) - throws SecurityException { + protected int enforceWritePermissionInner(Uri uri, String callingPkg, + @Nullable String featureId, IBinder callerToken) throws SecurityException { // Permit carrier-privileged apps regardless of ADD_VOICEMAIL permission state. if (mVoicemailPermissions.callerHasCarrierPrivileges()) { return MODE_ALLOWED; } - return super.enforceWritePermissionInner(uri, callingPkg, callerToken); + return super.enforceWritePermissionInner(uri, callingPkg, featureId, callerToken); } @VisibleForTesting @@ -179,7 +180,8 @@ public class VoicemailContentProvider extends ContentProvider public Uri insert(Uri uri, ContentValues values) { if (VERBOSE_LOGGING) { Log.v(TAG, "insert: uri=" + uri + " values=[" + values + "]" + - " CPID=" + Binder.getCallingPid()); + " CPID=" + Binder.getCallingPid() + + " CUID=" + Binder.getCallingUid()); } UriData uriData = checkPermissionsAndCreateUriDataForWrite(uri, values); return getTableDelegate(uriData).insert(uriData, values); @@ -198,6 +200,7 @@ public class VoicemailContentProvider extends ContentProvider Log.v(TAG, "query: uri=" + uri + " projection=" + Arrays.toString(projection) + " selection=[" + selection + "] args=" + Arrays.toString(selectionArgs) + " order=[" + sortOrder + "] CPID=" + Binder.getCallingPid() + + " CUID=" + Binder.getCallingUid() + " User=" + UserUtils.getCurrentUserHandle(getContext())); } UriData uriData = checkPermissionsAndCreateUriDataForRead(uri); @@ -213,6 +216,7 @@ public class VoicemailContentProvider extends ContentProvider Log.v(TAG, "update: uri=" + uri + " selection=[" + selection + "] args=" + Arrays.toString(selectionArgs) + " values=[" + values + "] CPID=" + Binder.getCallingPid() + + " CUID=" + Binder.getCallingUid() + " User=" + UserUtils.getCurrentUserHandle(getContext())); } UriData uriData = checkPermissionsAndCreateUriDataForWrite(uri, values); @@ -228,6 +232,7 @@ public class VoicemailContentProvider extends ContentProvider Log.v(TAG, "delete: uri=" + uri + " selection=[" + selection + "] args=" + Arrays.toString(selectionArgs) + " CPID=" + Binder.getCallingPid() + + " CUID=" + Binder.getCallingUid() + " User=" + UserUtils.getCurrentUserHandle(getContext())); } UriData uriData = checkPermissionsAndCreateUriDataForWrite(uri); @@ -254,6 +259,7 @@ public class VoicemailContentProvider extends ContentProvider if (VERBOSE_LOGGING) { Log.v(TAG, "openFile uri=" + uri + " mode=" + mode + " success=" + success + " CPID=" + Binder.getCallingPid() + + " CUID=" + Binder.getCallingUid() + " User=" + UserUtils.getCurrentUserHandle(getContext())); } } |