Merge "Fix long lines (>100) in ContactsProvider"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index ea70f64..85fa07c 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -54,6 +54,15 @@
android:writePermission="android.permission.WRITE_CALL_LOG">
</provider>
+ <provider android:name="ShadowCallLogProvider"
+ android:authorities="call_log_shadow"
+ android:syncable="false" android:multiprocess="false"
+ android:exported="true"
+ android:encryptionAware="true"
+ android:readPermission="android.permission.MANAGE_USERS"
+ android:writePermission="android.permission.MANAGE_USERS">
+ </provider>
+
<provider android:name="VoicemailContentProvider"
android:authorities="com.android.voicemail"
android:syncable="false" android:multiprocess="false"
diff --git a/src/com/android/providers/contacts/CallLogDatabaseHelper.java b/src/com/android/providers/contacts/CallLogDatabaseHelper.java
index 726d99c..2c03a79 100644
--- a/src/com/android/providers/contacts/CallLogDatabaseHelper.java
+++ b/src/com/android/providers/contacts/CallLogDatabaseHelper.java
@@ -42,8 +42,13 @@
private static final String DATABASE_NAME = "calllog.db";
+ private static final String SHADOW_DATABASE_NAME = "calllog_shadow.db";
+
private static CallLogDatabaseHelper sInstance;
+ /** Instance for the "shadow" provider. */
+ private static CallLogDatabaseHelper sInstanceForShadow;
+
private final Context mContext;
private final OpenHelper mOpenHelper;
@@ -55,6 +60,7 @@
public interface DbProperties {
String CALL_LOG_LAST_SYNCED = "call_log_last_synced";
+ String CALL_LOG_LAST_SYNCED_FOR_SHADOW = "call_log_last_synced_for_shadow";
String DATA_MIGRATED = "migrated";
}
@@ -186,6 +192,15 @@
return sInstance;
}
+ public static synchronized CallLogDatabaseHelper getInstanceForShadow(Context context) {
+ if (sInstanceForShadow == null) {
+ // Shadow provider is always encryption-aware.
+ sInstanceForShadow = new CallLogDatabaseHelper(
+ context.createDeviceEncryptedStorageContext(), SHADOW_DATABASE_NAME);
+ }
+ return sInstanceForShadow;
+ }
+
public SQLiteDatabase getReadableDatabase() {
return mOpenHelper.getReadableDatabase();
}
diff --git a/src/com/android/providers/contacts/CallLogProvider.java b/src/com/android/providers/contacts/CallLogProvider.java
index ce86cf7..d364dd3 100644
--- a/src/com/android/providers/contacts/CallLogProvider.java
+++ b/src/com/android/providers/contacts/CallLogProvider.java
@@ -24,6 +24,7 @@
import android.app.AppOpsManager;
import android.content.ContentProvider;
+import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
@@ -33,6 +34,7 @@
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
+import android.os.Binder;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
@@ -52,6 +54,7 @@
import com.android.providers.contacts.util.SelectionBuilder;
import com.android.providers.contacts.util.UserUtils;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.CountDownLatch;
@@ -62,6 +65,8 @@
public class CallLogProvider extends ContentProvider {
private static final String TAG = CallLogProvider.class.getSimpleName();
+ public static final boolean VERBOSE_LOGGING = false; // DO NOT SUBMIT WITH TRUE
+
private static final int BACKGROUND_TASK_INITIALIZE = 0;
private static final int BACKGROUND_TASK_ADJUST_PHONE_ACCOUNT = 1;
@@ -109,6 +114,9 @@
sURIMatcher.addURI(CallLog.AUTHORITY, "calls", CALLS);
sURIMatcher.addURI(CallLog.AUTHORITY, "calls/#", CALLS_ID);
sURIMatcher.addURI(CallLog.AUTHORITY, "calls/filter/*", CALLS_FILTER);
+
+ // Shadow provider only supports "/calls".
+ sURIMatcher.addURI(CallLog.SHADOW_AUTHORITY, "calls", CALLS);
}
private static final HashMap<String, String> sCallsProjectionMap;
@@ -157,11 +165,19 @@
private VoicemailPermissions mVoicemailPermissions;
private CallLogInsertionHelper mCallLogInsertionHelper;
+ protected boolean isShadow() {
+ return false;
+ }
+
+ protected final String getProviderName() {
+ return this.getClass().getSimpleName();
+ }
+
@Override
public boolean onCreate() {
setAppOps(AppOpsManager.OP_READ_CALL_LOG, AppOpsManager.OP_WRITE_CALL_LOG);
if (Log.isLoggable(Constants.PERFORMANCE_TAG, Log.DEBUG)) {
- Log.d(Constants.PERFORMANCE_TAG, "CallLogProvider.onCreate start");
+ Log.d(Constants.PERFORMANCE_TAG, getProviderName() + ".onCreate start");
}
final Context context = getContext();
mDbHelper = getDatabaseHelper(context);
@@ -171,7 +187,7 @@
mVoicemailPermissions = new VoicemailPermissions(context);
mCallLogInsertionHelper = createCallLogInsertionHelper(context);
- mBackgroundThread = new HandlerThread("CallLogProviderWorker",
+ mBackgroundThread = new HandlerThread(getProviderName() + "Worker",
Process.THREAD_PRIORITY_BACKGROUND);
mBackgroundThread.start();
mBackgroundHandler = new Handler(mBackgroundThread.getLooper()) {
@@ -186,7 +202,7 @@
scheduleBackgroundTask(BACKGROUND_TASK_INITIALIZE, null);
if (Log.isLoggable(Constants.PERFORMANCE_TAG, Log.DEBUG)) {
- Log.d(Constants.PERFORMANCE_TAG, "CallLogProvider.onCreate finish");
+ Log.d(Constants.PERFORMANCE_TAG, getProviderName() + ".onCreate finish");
}
return true;
}
@@ -196,7 +212,6 @@
return DefaultCallLogInsertionHelper.getInstance(context);
}
- @VisibleForTesting
protected CallLogDatabaseHelper getDatabaseHelper(final Context context) {
return CallLogDatabaseHelper.getInstance(context);
}
@@ -204,6 +219,12 @@
@Override
public Cursor query(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) +
+ " order=[" + sortOrder + "] CPID=" + Binder.getCallingPid() +
+ " User=" + UserUtils.getCurrentUserHandle(getContext()));
+ }
waitForAccess(mReadAccessLatch);
final SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setTables(Tables.CALLS);
@@ -301,6 +322,10 @@
@Override
public Uri insert(Uri uri, ContentValues values) {
+ if (VERBOSE_LOGGING) {
+ Log.v(TAG, "insert: uri=" + uri + " values=[" + values + "]" +
+ " CPID=" + Binder.getCallingPid());
+ }
waitForAccess(mReadAccessLatch);
checkForSupportedColumns(sCallsProjectionMap, values);
// Inserting a voicemail record through call_log requires the voicemail
@@ -328,6 +353,12 @@
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+ if (VERBOSE_LOGGING) {
+ Log.v(TAG, "update: uri=" + uri +
+ " selection=[" + selection + "] args=" + Arrays.toString(selectionArgs) +
+ " values=[" + values + "] CPID=" + Binder.getCallingPid() +
+ " User=" + UserUtils.getCurrentUserHandle(getContext()));
+ }
waitForAccess(mReadAccessLatch);
checkForSupportedColumns(sCallsProjectionMap, values);
// Request that involves changing record type to voicemail requires the
@@ -359,6 +390,12 @@
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
+ if (VERBOSE_LOGGING) {
+ Log.v(TAG, "delete: uri=" + uri +
+ " selection=[" + selection + "] args=" + Arrays.toString(selectionArgs) +
+ " CPID=" + Binder.getCallingPid() +
+ " User=" + UserUtils.getCurrentUserHandle(getContext()));
+ }
waitForAccess(mReadAccessLatch);
SelectionBuilder selectionBuilder = new SelectionBuilder(selection);
checkVoicemailPermissionAndAddRestriction(uri, selectionBuilder, false /*isQuery*/);
@@ -367,6 +404,8 @@
final int matchedUriId = sURIMatcher.match(uri);
switch (matchedUriId) {
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,
selectionBuilder.build(), selectionArgs);
default:
@@ -455,37 +494,76 @@
}
/**
- * Syncs any unique call log entries that have been inserted into the primary user's call log
- * since the last time the last sync occurred.
+ * Sync all calllog entries that were inserted
*/
- private void syncEntriesFromPrimaryUser(UserManager userManager) {
- final int userHandle = userManager.getUserHandle();
+ private void syncEntries() {
+ if (isShadow()) {
+ return; // It's the shadow provider itself. No copying.
+ }
+
+ final UserManager userManager = UserUtils.getUserManager(getContext());
+
// TODO: http://b/24944959
- if (userHandle == UserHandle.USER_SYSTEM
- || userManager.getUserInfo(userHandle).isManagedProfile()) {
+ if (!Calls.shouldHaveSharedCallLogEntries(getContext(), userManager,
+ userManager.getUserHandle())) {
return;
}
- final long lastSyncTime = getLastSyncTime();
- final Uri uri = ContentProvider.maybeAddUserId(CallLog.Calls.CONTENT_URI,
- UserHandle.USER_SYSTEM);
- final Cursor cursor = getContext().getContentResolver().query(
+ final int myUserId = userManager.getUserHandle();
+
+ // See the comment in Calls.addCall() for the logic.
+
+ if (userManager.isSystemUser()) {
+ // If it's the system user, just copy from shadow.
+ syncEntriesFrom(UserHandle.USER_SYSTEM, /* sourceIsShadow = */ true,
+ /* forAllUsersOnly =*/ false);
+ } else {
+ // Otherwise, copy from system's real provider, as well as self's shadow.
+ syncEntriesFrom(UserHandle.USER_SYSTEM, /* sourceIsShadow = */ false,
+ /* forAllUsersOnly =*/ true);
+ syncEntriesFrom(myUserId, /* sourceIsShadow = */ true,
+ /* forAllUsersOnly =*/ false);
+ }
+ }
+
+ private void syncEntriesFrom(int sourceUserId, boolean sourceIsShadow,
+ boolean forAllUsersOnly) {
+
+ final Uri sourceUri = sourceIsShadow ? Calls.SHADOW_CONTENT_URI : Calls.CONTENT_URI;
+
+ final long lastSyncTime = getLastSyncTime(sourceIsShadow);
+
+ final Uri uri = ContentProvider.maybeAddUserId(sourceUri, sourceUserId);
+ final long newestTimeStamp;
+ final ContentResolver cr = getContext().getContentResolver();
+
+ final StringBuilder selection = new StringBuilder();
+
+ selection.append(
+ "(" + EXCLUDE_VOICEMAIL_SELECTION + ") AND (" + MORE_RECENT_THAN_SELECTION + ")");
+
+ if (forAllUsersOnly) {
+ selection.append(" AND (" + Calls.ADD_FOR_ALL_USERS + "=1)");
+ }
+
+ final Cursor cursor = cr.query(
uri,
CALL_LOG_SYNC_PROJECTION,
- EXCLUDE_VOICEMAIL_SELECTION + " AND " + MORE_RECENT_THAN_SELECTION,
+ selection.toString(),
new String[] {String.valueOf(lastSyncTime)},
- Calls.DATE + " DESC");
+ Calls.DATE + " ASC");
if (cursor == null) {
return;
}
try {
- final long lastSyncedEntryTime = copyEntriesFromCursor(cursor);
- if (lastSyncedEntryTime > lastSyncTime) {
- setLastTimeSynced(lastSyncedEntryTime);
- }
+ newestTimeStamp = copyEntriesFromCursor(cursor, lastSyncTime, sourceIsShadow);
} finally {
cursor.close();
}
+ if (sourceIsShadow) {
+ // delete all entries in shadow.
+ cr.delete(uri, Calls.DATE + "<= ?", new String[] {String.valueOf(newestTimeStamp)});
+ }
}
/**
@@ -532,12 +610,10 @@
/**
* @param cursor to copy call log entries from
- *
- * @return the timestamp of the last synced entry.
*/
@VisibleForTesting
- long copyEntriesFromCursor(Cursor cursor) {
- long lastSynced = 0;
+ long copyEntriesFromCursor(Cursor cursor, long lastSyncTime, boolean forShadow) {
+ long latestTimestamp = 0;
final ContentValues values = new ContentValues();
final SQLiteDatabase db = mDbHelper.getWritableDatabase();
db.beginTransaction();
@@ -548,11 +624,6 @@
values.clear();
DatabaseUtils.cursorRowToContentValues(cursor, values);
- final boolean addForAllUsers = values.getAsInteger(Calls.ADD_FOR_ALL_USERS) == 1;
- if (!addForAllUsers) {
- continue;
- }
-
final String startTime = values.getAsString(Calls.DATE);
final String number = values.getAsString(Calls.NUMBER);
@@ -562,7 +633,7 @@
if (cursor.isLast()) {
try {
- lastSynced = Long.valueOf(startTime);
+ latestTimestamp = Long.valueOf(startTime);
} catch (NumberFormatException e) {
Log.e(TAG, "Call log entry does not contain valid start time: "
+ startTime);
@@ -580,23 +651,35 @@
db.insert(Tables.CALLS, null, values);
}
+
+ if (latestTimestamp > lastSyncTime) {
+ setLastTimeSynced(latestTimestamp, forShadow);
+ }
+
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
- return lastSynced;
+ return latestTimestamp;
}
- private long getLastSyncTime() {
+ private static String getLastSyncTimePropertyName(boolean forShadow) {
+ return forShadow
+ ? DbProperties.CALL_LOG_LAST_SYNCED_FOR_SHADOW
+ : DbProperties.CALL_LOG_LAST_SYNCED;
+ }
+
+ @VisibleForTesting
+ long getLastSyncTime(boolean forShadow) {
try {
- return Long.valueOf(mDbHelper.getProperty(DbProperties.CALL_LOG_LAST_SYNCED, "0"));
+ return Long.valueOf(mDbHelper.getProperty(getLastSyncTimePropertyName(forShadow), "0"));
} catch (NumberFormatException e) {
return 0;
}
}
- private void setLastTimeSynced(long time) {
- mDbHelper.setProperty(DbProperties.CALL_LOG_LAST_SYNCED, String.valueOf(time));
+ private void setLastTimeSynced(long time, boolean forShadow) {
+ mDbHelper.setProperty(getLastSyncTimePropertyName(forShadow), String.valueOf(time));
}
private static void waitForAccess(CountDownLatch latch) {
@@ -621,14 +704,7 @@
private void performBackgroundTask(int task, Object arg) {
if (task == BACKGROUND_TASK_INITIALIZE) {
try {
- final Context context = getContext();
- if (context != null) {
- final UserManager userManager = UserUtils.getUserManager(context);
- if (userManager != null &&
- !userManager.hasUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS)) {
- syncEntriesFromPrimaryUser(userManager);
- }
- }
+ syncEntries();
} finally {
mReadAccessLatch.countDown();
mReadAccessLatch = null;
@@ -636,6 +712,5 @@
} else if (task == BACKGROUND_TASK_ADJUST_PHONE_ACCOUNT) {
adjustForNewPhoneAccountInternal((PhoneAccountHandle) arg);
}
-
}
}
diff --git a/src/com/android/providers/contacts/ContactDirectoryManager.java b/src/com/android/providers/contacts/ContactDirectoryManager.java
index b7039a2..447ab28 100644
--- a/src/com/android/providers/contacts/ContactDirectoryManager.java
+++ b/src/com/android/providers/contacts/ContactDirectoryManager.java
@@ -175,7 +175,7 @@
*/
public void scanAllPackages(boolean rescan) {
if (rescan || !areTypeResourceIdsValid()) {
- getDbHelper().setProperty(DbProperties.DIRECTORY_SCAN_COMPLETE, "0");
+ getDbHelper().clearDirectoryScanComplete();
}
scanAllPackagesIfNeeded();
diff --git a/src/com/android/providers/contacts/ContactsDatabaseHelper.java b/src/com/android/providers/contacts/ContactsDatabaseHelper.java
index 6bc42a4..dc301f8 100644
--- a/src/com/android/providers/contacts/ContactsDatabaseHelper.java
+++ b/src/com/android/providers/contacts/ContactsDatabaseHelper.java
@@ -5629,6 +5629,10 @@
PropertyUtils.setProperty(getWritableDatabase(), key, value);
}
+ public void clearDirectoryScanComplete() {
+ setProperty(DbProperties.DIRECTORY_SCAN_COMPLETE, "0");
+ }
+
/**
* Test if the given column appears in the given projection.
*/
diff --git a/src/com/android/providers/contacts/ContactsProvider2.java b/src/com/android/providers/contacts/ContactsProvider2.java
index 1519a83..7f219eb 100644
--- a/src/com/android/providers/contacts/ContactsProvider2.java
+++ b/src/com/android/providers/contacts/ContactsProvider2.java
@@ -1770,7 +1770,6 @@
initForDefaultLocale();
mReadAccessLatch.countDown();
mReadAccessLatch = null;
- updateDirectoriesInBackground(true);
break;
}
@@ -6946,6 +6945,9 @@
return new MatrixCursor(outputProjection);
}
final Uri remoteUri = maybeAddUserId(RawContactsEntity.CONTENT_URI, corpUserId);
+ // This method is used by Bluetooth Contacts Sharing only, it uses enterprise
+ // contact id to get work contacts info, so work profile should be available at this
+ // moment.
return getContext().getContentResolver().query(remoteUri, projection, selection,
selectionArgs, sortOrder);
}
@@ -7012,6 +7014,12 @@
corpUserId);
final Cursor cursor = getContext().getContentResolver().query(remoteUri,
projection, selection, selectionArgs, sortOrder);
+ if (cursor == null) {
+ // Work profile is not available yet
+ final String[] outputProjection = (projection != null) ? projection
+ : sDirectoryProjectionMap.getColumnNames();
+ return new MatrixCursor(outputProjection);
+ }
return rewriteCorpDirectories(cursor);
} else {
// As it is not an enterprise directory id, fall back to original API
@@ -8957,6 +8965,7 @@
String.valueOf(directoryId - Directory.ENTERPRISE_DIRECTORY_ID_BASE));
addQueryParametersFromUri(builder, uri, MODIFIED_KEY_SET_FOR_ENTERPRISE_FILTER);
+ // If work profile is not available, it will throw FileNotFoundException
remoteUri = maybeAddUserId(builder.build(), corpUserId);
} else {
final DirectoryInfo directoryInfo = getDirectoryAuthority(directory);
@@ -9009,6 +9018,7 @@
}
// Convert the URI into:
// content://USER@com.android.contacts/contacts_corp/ID/{photo,display_photo}
+ // If work profile is not available, it will throw FileNotFoundException
final Uri corpUri = maybeAddUserId(
ContentUris.appendId(Contacts.CONTENT_URI.buildUpon(), contactId)
.appendPath(displayPhoto ?
diff --git a/src/com/android/providers/contacts/ContactsUpgradeReceiver.java b/src/com/android/providers/contacts/ContactsUpgradeReceiver.java
index 99727bc..57c0cd0 100644
--- a/src/com/android/providers/contacts/ContactsUpgradeReceiver.java
+++ b/src/com/android/providers/contacts/ContactsUpgradeReceiver.java
@@ -23,6 +23,7 @@
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
+import android.os.Build;
import android.os.RemoteException;
import android.util.Log;
@@ -42,6 +43,7 @@
static final String TAG = "ContactsUpgradeReceiver";
static final String PREF_DB_VERSION = "db_version";
static final String PREF_ICU_VERSION = "icu_version";
+ static final String PREF_OS_VERSION = "os_version";
@Override
public void onReceive(Context context, Intent intent) {
@@ -52,14 +54,19 @@
long startTime = System.currentTimeMillis();
// Lookup the last known database version
- SharedPreferences prefs = context.getSharedPreferences(TAG, Context.MODE_PRIVATE);
- int prefDbVersion = prefs.getInt(PREF_DB_VERSION, 0);
+ final SharedPreferences prefs = context.getSharedPreferences(TAG, Context.MODE_PRIVATE);
+ final int prefDbVersion = prefs.getInt(PREF_DB_VERSION, 0);
+
final String curIcuVersion = ICU.getIcuVersion();
+ final String curOsVersion = getOsVersionString();
+
final String prefIcuVersion = prefs.getString(PREF_ICU_VERSION, "");
+ final String prefOsVersion = prefs.getString(PREF_OS_VERSION, "");
// If the version is old go ahead and attempt to create or upgrade the database.
if (prefDbVersion != ContactsDatabaseHelper.DATABASE_VERSION ||
- !prefIcuVersion.equals(curIcuVersion)) {
+ !prefIcuVersion.equals(curIcuVersion) ||
+ !prefOsVersion.equals(curOsVersion)) {
// Store the current version so this receiver isn't run again until the database
// version number changes. This is intentionally done even before the upgrade path
// is attempted to be conservative. If the upgrade fails for some reason and we
@@ -67,6 +74,7 @@
SharedPreferences.Editor editor = prefs.edit();
editor.putInt(PREF_DB_VERSION, ContactsDatabaseHelper.DATABASE_VERSION);
editor.putString(PREF_ICU_VERSION, curIcuVersion);
+ editor.putString(PREF_OS_VERSION, curOsVersion);
editor.commit();
// Ask for a reference to the database to force the helper to either
@@ -79,8 +87,11 @@
Log.i(TAG, "Creating or opening contacts database");
helper.getWritableDatabase();
+ helper.clearDirectoryScanComplete();
+
profileHelper.getWritableDatabase();
calllogHelper.getWritableDatabase();
+
ContactsProvider2.updateLocaleOffline(context, helper, profileHelper);
// Log the total time taken for the receiver to perform the operation
@@ -96,4 +107,8 @@
PackageManager.DONT_KILL_APP);
}
}
+
+ private static String getOsVersionString() {
+ return Build.ID;
+ }
}
diff --git a/src/com/android/providers/contacts/ShadowCallLogProvider.java b/src/com/android/providers/contacts/ShadowCallLogProvider.java
new file mode 100644
index 0000000..2cacdc2
--- /dev/null
+++ b/src/com/android/providers/contacts/ShadowCallLogProvider.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.providers.contacts;
+
+import android.content.Context;
+
+public class ShadowCallLogProvider extends CallLogProvider {
+ protected CallLogDatabaseHelper getDatabaseHelper(final Context context) {
+ return CallLogDatabaseHelper.getInstanceForShadow(context);
+ }
+
+ @Override
+ protected boolean isShadow() {
+ return true;
+ }
+}
diff --git a/tests/src/com/android/providers/contacts/CallLogProviderTest.java b/tests/src/com/android/providers/contacts/CallLogProviderTest.java
index fb771a3..590a0a3 100644
--- a/tests/src/com/android/providers/contacts/CallLogProviderTest.java
+++ b/tests/src/com/android/providers/contacts/CallLogProviderTest.java
@@ -18,6 +18,7 @@
import com.android.internal.telephony.CallerInfo;
import com.android.internal.telephony.PhoneConstants;
+import com.android.providers.contacts.CallLogDatabaseHelper.DbProperties;
import com.android.providers.contacts.testutil.CommonDatabaseUtils;
import android.content.ComponentName;
@@ -187,6 +188,8 @@
Uri uri = Calls.addCall(ci, getMockContext(), "1-800-263-7643",
PhoneConstants.PRESENTATION_ALLOWED, Calls.OUTGOING_TYPE, 0, subscription, 2000,
40, null);
+ assertNotNull(uri);
+ assertEquals("0@" + CallLog.AUTHORITY, uri.getAuthority());
ContentValues values = new ContentValues();
values.put(Calls.TYPE, Calls.OUTGOING_TYPE);
@@ -398,27 +401,33 @@
mResolver.delete(Calls.CONTENT_URI_WITH_VOICEMAIL, null, null);
}
- public void testCopyEntriesFromCursor_ReturnsMostRecentEntryTimestamp() {
- assertEquals(10, mCallLogProvider.copyEntriesFromCursor(getTestCallLogCursor()));
- }
-
public void testCopyEntriesFromCursor_AllEntriesSyncedWithoutDuplicatesPresent() {
assertStoredValues(Calls.CONTENT_URI);
- mCallLogProvider.copyEntriesFromCursor(getTestCallLogCursor());
+
+ assertEquals(10, mCallLogProvider.copyEntriesFromCursor(
+ getTestCallLogCursor(), 5, /* forShadow =*/ true));
+
assertStoredValues(Calls.CONTENT_URI,
getTestCallLogValues(2),
getTestCallLogValues(1),
getTestCallLogValues(0));
+ assertEquals(10, mCallLogProvider.getLastSyncTime(/* forShadow =*/ true));
+ assertEquals(0, mCallLogProvider.getLastSyncTime(/* forShadow =*/ false));
}
public void testCopyEntriesFromCursor_DuplicatesIgnoredCorrectly() {
mResolver.insert(Calls.CONTENT_URI, getTestCallLogValues(1));
assertStoredValues(Calls.CONTENT_URI, getTestCallLogValues(1));
- mCallLogProvider.copyEntriesFromCursor(getTestCallLogCursor());
+
+ assertEquals(10, mCallLogProvider.copyEntriesFromCursor(
+ getTestCallLogCursor(), 5, /* forShadow =*/ false));
+
assertStoredValues(Calls.CONTENT_URI,
getTestCallLogValues(2),
getTestCallLogValues(1),
getTestCallLogValues(0));
+ assertEquals(0, mCallLogProvider.getLastSyncTime(/* forShadow =*/ true));
+ assertEquals(10, mCallLogProvider.getLastSyncTime(/* forShadow =*/ false));
}
private ContentValues getDefaultValues(int callType) {
diff --git a/tests/src/com/android/providers/contacts/ContactDirectoryManagerTest.java b/tests/src/com/android/providers/contacts/ContactDirectoryManagerTest.java
index c5bc6f6..8ad5ca1 100644
--- a/tests/src/com/android/providers/contacts/ContactDirectoryManagerTest.java
+++ b/tests/src/com/android/providers/contacts/ContactDirectoryManagerTest.java
@@ -37,6 +37,7 @@
import android.util.Log;
import com.android.providers.contacts.ContactsDatabaseHelper.AggregationExceptionColumns;
+
import com.google.android.collect.Lists;
/**
@@ -173,24 +174,38 @@
mDirectoryManager.scanAllPackages();
- Cursor cursor = mResolver.query(Directory.CONTENT_URI, null, null, null, null);
+ Cursor cursor = mResolver.query(Directory.CONTENT_URI, null, null, null,
+ /* order by=*/ Directory.DIRECTORY_AUTHORITY + "," + Directory.ACCOUNT_NAME +
+ "," + Directory._ID );
+
+ TestUtils.dumpCursor(cursor);
assertEquals(5, cursor.getCount());
- cursor.moveToPosition(2);
+ assertTrue(cursor.moveToPosition(0));
assertDirectoryRow(cursor, "test.package1", "authority1", "account-name1", "account-type1",
"display-name1", 1, Directory.EXPORT_SUPPORT_NONE, Directory.SHORTCUT_SUPPORT_NONE,
Directory.PHOTO_SUPPORT_FULL_SIZE_ONLY);
- cursor.moveToNext();
+ assertTrue(cursor.moveToPosition(1));
assertDirectoryRow(cursor, "test.package1", "authority1", "account-name2", "account-type2",
"display-name2", 2, Directory.EXPORT_SUPPORT_ANY_ACCOUNT,
Directory.SHORTCUT_SUPPORT_DATA_ITEMS_ONLY, Directory.PHOTO_SUPPORT_THUMBNAIL_ONLY);
- cursor.moveToNext();
+ assertTrue(cursor.moveToPosition(2));
assertDirectoryRow(cursor, "test.package2", "authority2", "account-name3", "account-type3",
"display-name3", 3, Directory.EXPORT_SUPPORT_SAME_ACCOUNT_ONLY,
Directory.SHORTCUT_SUPPORT_FULL, Directory.PHOTO_SUPPORT_FULL);
+ assertTrue(cursor.moveToPosition(3));
+ assertDirectoryRow(cursor, "contactsTestPackage", "com.android.contacts", null, null,
+ null, -1 /* =any */, Directory.EXPORT_SUPPORT_NONE,
+ Directory.SHORTCUT_SUPPORT_FULL, Directory.PHOTO_SUPPORT_FULL);
+
+ assertTrue(cursor.moveToPosition(4));
+ assertDirectoryRow(cursor, "contactsTestPackage", "com.android.contacts", null, null,
+ null, -1 /* =any */, Directory.EXPORT_SUPPORT_NONE,
+ Directory.SHORTCUT_SUPPORT_FULL, Directory.PHOTO_SUPPORT_FULL);
+
cursor.close();
}
@@ -623,7 +638,9 @@
values.put(Directory.ACCOUNT_NAME, accountName);
values.put(Directory.ACCOUNT_TYPE, accountType);
values.put(Directory.DISPLAY_NAME, displayName);
- values.put(Directory.TYPE_RESOURCE_ID, typeResourceId);
+ if (typeResourceId >= 0) {
+ values.put(Directory.TYPE_RESOURCE_ID, typeResourceId);
+ }
values.put(Directory.EXPORT_SUPPORT, exportSupport);
values.put(Directory.SHORTCUT_SUPPORT, shortcutSupport);
values.put(Directory.PHOTO_SUPPORT, photoSupport);
diff --git a/tests/src/com/android/providers/contacts/ContactsActor.java b/tests/src/com/android/providers/contacts/ContactsActor.java
index 1d7931e..fd75e45 100644
--- a/tests/src/com/android/providers/contacts/ContactsActor.java
+++ b/tests/src/com/android/providers/contacts/ContactsActor.java
@@ -275,7 +275,28 @@
resolver = new MockContentResolver();
context = new RestrictionMockContext(overallContext, packageName, resolver,
- mGrantedPermissions, mGrantedUriPermissions);
+ mGrantedPermissions, mGrantedUriPermissions) {
+ @Override
+ public Object getSystemService(String name) {
+ if (Context.COUNTRY_DETECTOR.equals(name)) {
+ return mMockCountryDetector;
+ }
+ if (Context.ACCOUNT_SERVICE.equals(name)) {
+ return mMockAccountManager;
+ }
+ if (Context.USER_SERVICE.equals(name)) {
+ return mockUserManager;
+ }
+ // Use overallContext here; super.getSystemService() somehow won't return
+ // DevicePolicyManager.
+ return overallContext.getSystemService(name);
+ }
+
+ @Override
+ public String getSystemServiceName(Class<?> serviceClass) {
+ return overallContext.getSystemServiceName(serviceClass);
+ }
+ };
this.packageName = packageName;
// Let the Secure class initialize the settings provider, which is done when we first
@@ -357,12 +378,12 @@
// info shouldn't have it.
info.authority = stripOutUserIdFromAuthority(authority);
provider.attachInfoForTesting(providerContext, info);
- resolver.addProvider(authority, provider);
// In case of LegacyTest, "authority" here is actually multiple authorities.
// Register all authority here.
for (String a : authority.split(";")) {
resolver.addProvider(a, provider);
+ resolver.addProvider("0@" + a, provider);
}
return provider;
}
diff --git a/tests/src/com/android/providers/contacts/ContactsProvider2Test.java b/tests/src/com/android/providers/contacts/ContactsProvider2Test.java
index 2f09c1f..d14af72 100644
--- a/tests/src/com/android/providers/contacts/ContactsProvider2Test.java
+++ b/tests/src/com/android/providers/contacts/ContactsProvider2Test.java
@@ -2200,153 +2200,44 @@
c.close();
}
- public void testRewriteCorpLookup() {
- // 19 columns
+ public void testRewriteCorpDirectories() {
+ // 6 columns
final MatrixCursor c = new MatrixCursor(new String[] {
- PhoneLookup._ID,
- PhoneLookup.LOOKUP_KEY,
- PhoneLookup.DISPLAY_NAME,
- PhoneLookup.LAST_TIME_CONTACTED,
- PhoneLookup.TIMES_CONTACTED,
- PhoneLookup.STARRED,
- PhoneLookup.IN_DEFAULT_DIRECTORY,
- PhoneLookup.IN_VISIBLE_GROUP,
- PhoneLookup.PHOTO_FILE_ID,
- PhoneLookup.PHOTO_ID,
- PhoneLookup.PHOTO_URI,
- PhoneLookup.PHOTO_THUMBNAIL_URI,
- PhoneLookup.CUSTOM_RINGTONE,
- PhoneLookup.HAS_PHONE_NUMBER,
- PhoneLookup.SEND_TO_VOICEMAIL,
- PhoneLookup.NUMBER,
- PhoneLookup.TYPE,
- PhoneLookup.LABEL,
- PhoneLookup.NORMALIZED_NUMBER
+ Directory._ID,
+ Directory.PACKAGE_NAME,
+ Directory.TYPE_RESOURCE_ID,
+ Directory.DISPLAY_NAME,
+ Directory.ACCOUNT_TYPE,
+ Directory.ACCOUNT_NAME,
});
// First, convert and make sure it returns an empty cursor.
- // TODO: Use EnterpriseContactsCursorWrapper instead of rewriteCorpLookup.
- Cursor rewritten = null;
+ Cursor rewritten = ContactsProvider2.rewriteCorpDirectories(c);
assertEquals(0, rewritten.getCount());
- assertEquals(19, rewritten.getColumnCount());
+ assertEquals(6, rewritten.getColumnCount());
c.addRow(new Object[] {
- 1L, // PhoneLookup._ID,
- null, // PhoneLookup.LOOKUP_KEY,
- null, // PhoneLookup.DISPLAY_NAME,
- null, // PhoneLookup.LAST_TIME_CONTACTED,
- null, // PhoneLookup.TIMES_CONTACTED,
- null, // PhoneLookup.STARRED,
- null, // PhoneLookup.IN_DEFAULT_DIRECTORY,
- null, // PhoneLookup.IN_VISIBLE_GROUP,
- null, // PhoneLookup.PHOTO_FILE_ID,
- null, // PhoneLookup.PHOTO_ID,
- null, // PhoneLookup.PHOTO_URI,
- null, // PhoneLookup.PHOTO_THUMBNAIL_URI,
- null, // PhoneLookup.CUSTOM_RINGTONE,
- null, // PhoneLookup.HAS_PHONE_NUMBER,
- null, // PhoneLookup.SEND_TO_VOICEMAIL,
- null, // PhoneLookup.NUMBER,
- null, // PhoneLookup.TYPE,
- null, // PhoneLookup.LABEL,
- null, // PhoneLookup.NORMALIZED_NUMBER
+ 5L, // Directory._ID
+ "name", // Directory.PACKAGE_NAME
+ 123, // Directory.TYPE_RESOURCE_ID
+ "display", // Directory.DISPLAY_NAME
+ "atype", // Directory.ACCOUNT_TYPE
+ "aname", // Directory.ACCOUNT_NAME
});
- c.addRow(new Object[] {
- 10L, // PhoneLookup._ID,
- "key", // PhoneLookup.LOOKUP_KEY,
- "name", // PhoneLookup.DISPLAY_NAME,
- 123, // PhoneLookup.LAST_TIME_CONTACTED,
- 456, // PhoneLookup.TIMES_CONTACTED,
- 1, // PhoneLookup.STARRED,
- 1, // PhoneLookup.IN_DEFAULT_DIRECTORY,
- 1, // PhoneLookup.IN_VISIBLE_GROUP,
- 1001, // PhoneLookup.PHOTO_FILE_ID,
- 1002, // PhoneLookup.PHOTO_ID,
- "content://a/a", // PhoneLookup.PHOTO_URI,
- "content://a/b", // PhoneLookup.PHOTO_THUMBNAIL_URI,
- "content://a/c", // PhoneLookup.CUSTOM_RINGTONE,
- 1, // PhoneLookup.HAS_PHONE_NUMBER,
- 1, // PhoneLookup.SEND_TO_VOICEMAIL,
- "1234", // PhoneLookup.NUMBER,
- 1, // PhoneLookup.TYPE,
- "label", // PhoneLookup.LABEL,
- "+1234", // PhoneLookup.NORMALIZED_NUMBER
- });
- // TODO: Use EnterpriseContactsCursorWrapper instead of rewriteCorpLookup
- // rewritten = ContactsProvider2.rewriteCorpLookup(c.getColumnNames(), c,
- // PhoneLookup._ID);
- assertEquals(2, rewritten.getCount());
- assertEquals(19, rewritten.getColumnCount());
+ rewritten = ContactsProvider2.rewriteCorpDirectories(c);
+ assertEquals(1, rewritten.getCount());
+ assertEquals(6, rewritten.getColumnCount());
rewritten.moveToPosition(0);
int column = 0;
- assertEquals(1000000001L, rewritten.getLong(column++)); // We offset ID for corp contacts.
- assertEquals(null, rewritten.getString(column++));
- assertEquals(null, rewritten.getString(column++));
- assertEquals(null, rewritten.getString(column++));
- assertEquals(null, rewritten.getString(column++));
- assertEquals(null, rewritten.getString(column++));
- assertEquals(null, rewritten.getString(column++));
- assertEquals(null, rewritten.getString(column++));
- assertEquals(null, rewritten.getString(column++));
- assertEquals(null, rewritten.getString(column++));
- assertEquals(null, rewritten.getString(column++));
- assertEquals(null, rewritten.getString(column++));
- assertEquals(null, rewritten.getString(column++));
- assertEquals(null, rewritten.getString(column++));
- assertEquals(null, rewritten.getString(column++));
- assertEquals(null, rewritten.getString(column++));
- assertEquals(null, rewritten.getString(column++));
- assertEquals(null, rewritten.getString(column++));
- assertEquals(null, rewritten.getString(column++));
-
-
- rewritten.moveToNext();
- column = 0;
- assertEquals(1000000010L, rewritten.getLong(column++)); // With offset.
- assertEquals("c-key", rewritten.getString(column++));
+ assertEquals(1000000005L, rewritten.getLong(column++));
assertEquals("name", rewritten.getString(column++));
assertEquals(123, rewritten.getInt(column++));
- assertEquals(456, rewritten.getInt(column++));
- assertEquals(1, rewritten.getInt(column++));
- assertEquals(1, rewritten.getInt(column++));
- assertEquals(1, rewritten.getInt(column++));
- assertEquals(null, rewritten.getString(column++)); // photo file id
- assertEquals(null, rewritten.getString(column++)); // photo id
- assertEquals("content://com.android.contacts/contacts_corp/10/display_photo",
- rewritten.getString(column++));
- assertEquals("content://com.android.contacts/contacts_corp/10/photo",
- rewritten.getString(column++));
- assertEquals(null, rewritten.getString(column++)); // ringtone
- assertEquals(1, rewritten.getInt(column++));
- assertEquals(1, rewritten.getInt(column++));
- assertEquals("1234", rewritten.getString(column++));
- assertEquals(1, rewritten.getInt(column++));
- assertEquals("label", rewritten.getString(column++));
- assertEquals("+1234", rewritten.getString(column++));
-
- // Use a narower projection.
- // TODO: Use EnterpriseContactsCursorWrapper instead of rewriteCorpLookup
- // rewritten = ContactsProvider2.rewriteCorpLookup(
- // new String[] {PhoneLookup.PHOTO_URI, PhoneLookup.PHOTO_THUMBNAIL_URI}, c,
- // PhoneLookup._ID);
- assertEquals(2, rewritten.getCount());
- assertEquals(2, rewritten.getColumnCount());
-
- rewritten.moveToPosition(0);
- column = 0;
- assertEquals(null, rewritten.getString(column++));
- assertEquals(null, rewritten.getString(column++));
-
-
- rewritten.moveToNext();
- column = 0;
- assertEquals("content://com.android.contacts/contacts_corp/10/display_photo",
- rewritten.getString(column++));
- assertEquals("content://com.android.contacts/contacts_corp/10/photo",
- rewritten.getString(column++));
+ assertEquals("display", rewritten.getString(column++));
+ assertEquals("atype", rewritten.getString(column++));
+ assertEquals("aname", rewritten.getString(column++));
}
public void testPhoneUpdate() {
diff --git a/tests/src/com/android/providers/contacts/EnterpriseContactsCursorWrapperTest.java b/tests/src/com/android/providers/contacts/EnterpriseContactsCursorWrapperTest.java
new file mode 100644
index 0000000..74a74a3
--- /dev/null
+++ b/tests/src/com/android/providers/contacts/EnterpriseContactsCursorWrapperTest.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.providers.contacts;
+
+import android.database.Cursor;
+import android.database.MatrixCursor;
+import android.provider.ContactsContract.PhoneLookup;
+import android.test.AndroidTestCase;
+import android.test.MoreAsserts;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.providers.contacts.enterprise.EnterpriseContactsCursorWrapper;
+
+
+@SmallTest
+public class EnterpriseContactsCursorWrapperTest extends AndroidTestCase {
+
+ public void testWrappedResults() {
+ // 19 columns
+ final String[] projection = new String[] {
+ /* column 0 */ PhoneLookup._ID,
+ /* column 1 */ PhoneLookup.LOOKUP_KEY,
+ /* column 2 */ PhoneLookup.DISPLAY_NAME,
+ /* column 3 */ PhoneLookup.LAST_TIME_CONTACTED,
+ /* column 4 */ PhoneLookup.TIMES_CONTACTED,
+ /* column 5 */ PhoneLookup.STARRED,
+ /* column 6 */ PhoneLookup.IN_DEFAULT_DIRECTORY,
+ /* column 7 */ PhoneLookup.IN_VISIBLE_GROUP,
+ /* column 8 */ PhoneLookup.PHOTO_FILE_ID,
+ /* column 9 */ PhoneLookup.PHOTO_ID,
+ /* column 10 */ PhoneLookup.PHOTO_URI,
+ /* column 11 */ PhoneLookup.PHOTO_THUMBNAIL_URI,
+ /* column 12 */ PhoneLookup.CUSTOM_RINGTONE,
+ /* column 13 */ PhoneLookup.HAS_PHONE_NUMBER,
+ /* column 14 */ PhoneLookup.SEND_TO_VOICEMAIL,
+ /* column 15 */ PhoneLookup.NUMBER,
+ /* column 16 */ PhoneLookup.TYPE,
+ /* column 17 */ PhoneLookup.LABEL,
+ /* column 18 */ PhoneLookup.NORMALIZED_NUMBER
+ };
+ final MatrixCursor c = new MatrixCursor(projection);
+
+ // First, convert and make sure it returns an empty cursor.
+ Cursor rewritten = new EnterpriseContactsCursorWrapper(c, projection, 0, false, null);
+
+ assertEquals(0, rewritten.getCount());
+ assertEquals(19, rewritten.getColumnCount());
+
+ c.addRow(new Object[] {
+ 1L, // PhoneLookup._ID,
+ null, // PhoneLookup.LOOKUP_KEY,
+ null, // PhoneLookup.DISPLAY_NAME,
+ null, // PhoneLookup.LAST_TIME_CONTACTED,
+ null, // PhoneLookup.TIMES_CONTACTED,
+ null, // PhoneLookup.STARRED,
+ null, // PhoneLookup.IN_DEFAULT_DIRECTORY,
+ null, // PhoneLookup.IN_VISIBLE_GROUP,
+ null, // PhoneLookup.PHOTO_FILE_ID,
+ null, // PhoneLookup.PHOTO_ID,
+ null, // PhoneLookup.PHOTO_URI,
+ null, // PhoneLookup.PHOTO_THUMBNAIL_URI,
+ null, // PhoneLookup.CUSTOM_RINGTONE,
+ null, // PhoneLookup.HAS_PHONE_NUMBER,
+ null, // PhoneLookup.SEND_TO_VOICEMAIL,
+ null, // PhoneLookup.NUMBER,
+ null, // PhoneLookup.TYPE,
+ null, // PhoneLookup.LABEL,
+ null, // PhoneLookup.NORMALIZED_NUMBER
+ });
+
+ c.addRow(new Object[] {
+ 10L, // PhoneLookup._ID,
+ "key", // PhoneLookup.LOOKUP_KEY,
+ "name", // PhoneLookup.DISPLAY_NAME,
+ 123, // PhoneLookup.LAST_TIME_CONTACTED,
+ 456, // PhoneLookup.TIMES_CONTACTED,
+ 1, // PhoneLookup.STARRED,
+ 1, // PhoneLookup.IN_DEFAULT_DIRECTORY,
+ 1, // PhoneLookup.IN_VISIBLE_GROUP,
+ 1001, // PhoneLookup.PHOTO_FILE_ID,
+ 1002, // PhoneLookup.PHOTO_ID,
+ "content://a/a", // PhoneLookup.PHOTO_URI,
+ "content://a/b", // PhoneLookup.PHOTO_THUMBNAIL_URI,
+ "content://a/c", // PhoneLookup.CUSTOM_RINGTONE,
+ 1, // PhoneLookup.HAS_PHONE_NUMBER,
+ 1, // PhoneLookup.SEND_TO_VOICEMAIL,
+ "1234", // PhoneLookup.NUMBER,
+ 1, // PhoneLookup.TYPE,
+ "label", // PhoneLookup.LABEL,
+ "+1234", // PhoneLookup.NORMALIZED_NUMBER
+ });
+ rewritten = new EnterpriseContactsCursorWrapper(c, projection, 0, false, null);
+ assertEquals(2, rewritten.getCount());
+ assertEquals(19, rewritten.getColumnCount());
+
+ rewritten.moveToPosition(0);
+ int column = 0;
+ assertEquals(1000000001L, rewritten.getLong(column++)); // We offset ID for corp contacts.
+ assertEquals(null, rewritten.getString(column++));
+ assertEquals(null, rewritten.getString(column++));
+ assertEquals(null, rewritten.getString(column++));
+ assertEquals(null, rewritten.getString(column++));
+ assertEquals(null, rewritten.getString(column++));
+ assertEquals(null, rewritten.getString(column++));
+ assertEquals(null, rewritten.getString(column++));
+ assertEquals(null, rewritten.getString(column++));
+ assertEquals(null, rewritten.getString(column++));
+ assertEquals(null, rewritten.getString(column++));
+ assertEquals(null, rewritten.getString(column++));
+ assertEquals(null, rewritten.getString(column++));
+ assertEquals(null, rewritten.getString(column++));
+ assertEquals(null, rewritten.getString(column++));
+ assertEquals(null, rewritten.getString(column++));
+ assertEquals(null, rewritten.getString(column++));
+ assertEquals(null, rewritten.getString(column++));
+ assertEquals(null, rewritten.getString(column++));
+
+
+ rewritten.moveToNext();
+ column = 0;
+ assertEquals(1000000010L, rewritten.getLong(column++)); // With offset.
+ assertEquals("c-key", rewritten.getString(column++));
+ assertEquals("name", rewritten.getString(column++));
+ assertEquals(123, rewritten.getInt(column++));
+ assertEquals(456, rewritten.getInt(column++));
+ assertEquals(1, rewritten.getInt(column++));
+ assertEquals(1, rewritten.getInt(column++));
+ assertEquals(1, rewritten.getInt(column++));
+ assertEquals(null, rewritten.getString(column++)); // photo file id
+ assertEquals(null, rewritten.getString(column++)); // photo id
+ assertEquals("content://com.android.contacts/contacts_corp/10/display_photo",
+ rewritten.getString(column++));
+ assertEquals("content://com.android.contacts/contacts_corp/10/photo",
+ rewritten.getString(column++));
+ assertEquals(null, rewritten.getString(column++)); // ringtone
+ assertEquals(1, rewritten.getInt(column++));
+ assertEquals(1, rewritten.getInt(column++));
+ assertEquals("1234", rewritten.getString(column++));
+ assertEquals(1, rewritten.getInt(column++));
+ assertEquals("label", rewritten.getString(column++));
+ assertEquals("+1234", rewritten.getString(column++));
+
+
+ rewritten = new EnterpriseContactsCursorWrapper(c, projection, 0, false, null);
+
+ assertEquals(2, rewritten.getCount());
+ assertEquals(19, rewritten.getColumnCount());
+
+ rewritten.moveToPosition(0);
+
+ assertEquals(null, rewritten.getString(10));
+ assertEquals(null, rewritten.getString(11));
+
+
+ rewritten.moveToNext();
+ column = 0;
+ assertEquals("content://com.android.contacts/contacts_corp/10/display_photo",
+ rewritten.getString(10));
+ assertEquals("content://com.android.contacts/contacts_corp/10/photo",
+ rewritten.getString(11));
+ }
+}
+