aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorXin Li <delphij@google.com>2020-09-01 20:03:59 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2020-09-01 20:03:59 +0000
commitca343420fe23f74ef8ac94b2991cf49ce0d157c0 (patch)
tree0800aa922f7c115d2d3b6f2ed753d2181e699ae4 /src
parente98011c6064fd0b3ed62ca1f09369e5cd98618e0 (diff)
parentfe7ff0defba5f0e3e5235584c2a53d26f02fe161 (diff)
downloadContactsProvider-ca343420fe23f74ef8ac94b2991cf49ce0d157c0.tar.gz
Merge "Merge Android R (rvc-dev-plus-aosp-without-vendor@6692709)" into stage-aosp-master
Diffstat (limited to 'src')
-rw-r--r--src/com/android/providers/contacts/CallLogProvider.java6
-rw-r--r--src/com/android/providers/contacts/ContactsProvider2.java296
-rw-r--r--src/com/android/providers/contacts/MetadataEntryParser.java20
-rw-r--r--src/com/android/providers/contacts/VoicemailContentProvider.java20
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()));
}
}