summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShuo Qian <shuoq@google.com>2021-12-13 21:24:54 -0800
committerGrace Jia <xiaotonj@google.com>2022-03-23 09:50:03 -0700
commit8c20ec381b92558dfe8d8b6366dc5db74fa2e6f0 (patch)
tree18a5c6b62d53e4ec696216b62ffd23f71d51f97d
parent32c9fe43639d5dc30225a93b7ecce2c0005e4596 (diff)
downloadCallLogProvider-8c20ec381b92558dfe8d8b6366dc5db74fa2e6f0.tar.gz
Call log Backup and Restore for PhoneAccountHandle without IccId in T
In >=T Android, Telephony PhoneAccountHandle must use SubId as the ID (the unique identifier). Any version of Telephony call logs that are restored in >=T Android should set pending migration status as true and migrate to the subId later because different devices have different mappings between SubId and IccId. In <T Android, call log PhoneAccountHandle ID uses IccId, and backup with IccId; in >=T Android, call log PhoneAccountHandle ID uses SubId, and IccId is decided to use for backup for the reason mentioned above. Every time a call log is restored, the on-devie sub Id can be determined based on its IccId. The pending migration from IccId to SubId will be complete after the PhoneAccountHandle is registrated by Telecom and before CallLogProvider unhides it. Bug: 185235527 Test: atest CallLogBackupAgentTest Change-Id: I81b5fd215045c520d3ead4257678a38c12a2f344
-rw-r--r--src/com/android/calllogbackup/CallLogBackupAgent.java105
-rw-r--r--tests/Android.bp6
-rw-r--r--tests/AndroidManifest.xml2
-rw-r--r--tests/src/com/android/calllogbackup/CallLogBackupAgentTest.java175
4 files changed, 276 insertions, 12 deletions
diff --git a/src/com/android/calllogbackup/CallLogBackupAgent.java b/src/com/android/calllogbackup/CallLogBackupAgent.java
index 02b7839..a64a373 100644
--- a/src/com/android/calllogbackup/CallLogBackupAgent.java
+++ b/src/com/android/calllogbackup/CallLogBackupAgent.java
@@ -23,13 +23,13 @@ import android.app.backup.BackupDataInput;
import android.app.backup.BackupDataOutput;
import android.content.ComponentName;
import android.content.ContentResolver;
-import android.content.Context;
import android.database.Cursor;
import android.os.ParcelFileDescriptor;
import android.provider.CallLog;
import android.provider.CallLog.Calls;
-import android.provider.Settings;
import android.telecom.PhoneAccountHandle;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
@@ -47,6 +47,8 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
+import java.util.HashMap;
+import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;
@@ -81,6 +83,7 @@ public class CallLogBackupAgent extends BackupAgent {
String callScreeningAppName = null;
String callScreeningComponentName = null;
long missedReason = MISSED_REASON_NOT_MISSED;
+ int isPhoneAccountMigrationPending;
@Override
public String toString() {
@@ -107,7 +110,7 @@ public class CallLogBackupAgent extends BackupAgent {
/** Current version of CallLogBackup. Used to track the backup format. */
@VisibleForTesting
- static final int VERSION = 1008;
+ static final int VERSION = 1009;
/** Version indicating that there exists no previous backup entry. */
@VisibleForTesting
static final int VERSION_NO_PREVIOUS_STATE = 0;
@@ -118,6 +121,11 @@ public class CallLogBackupAgent extends BackupAgent {
static final int END_OEM_DATA_MARKER = 0x60061E;
+ static final String TELEPHONY_PHONE_ACCOUNT_HANDLE_COMPONENT_NAME =
+ "com.android.phone/com.android.services.telephony.TelephonyConnectionService";
+
+ @VisibleForTesting
+ protected Map<Integer, String> mSubscriptionInfoMap;
private static final String[] CALL_LOG_PROJECTION = new String[] {
CallLog.Calls._ID,
@@ -139,7 +147,8 @@ public class CallLogBackupAgent extends BackupAgent {
CallLog.Calls.BLOCK_REASON,
CallLog.Calls.CALL_SCREENING_APP_NAME,
CallLog.Calls.CALL_SCREENING_COMPONENT_NAME,
- CallLog.Calls.MISSED_REASON
+ CallLog.Calls.MISSED_REASON,
+ CallLog.Calls.IS_PHONE_ACCOUNT_MIGRATION_PENDING
};
/** ${inheritDoc} */
@@ -156,6 +165,20 @@ public class CallLogBackupAgent extends BackupAgent {
dataInput.close();
}
+ SubscriptionManager subscriptionManager = getBaseContext().getSystemService(
+ SubscriptionManager.class);
+ if (subscriptionManager != null) {
+ mSubscriptionInfoMap = new HashMap<>();
+ // Use getAllSubscirptionInfoList() to get the mapping between iccId and subId
+ // from the subscription database
+ List<SubscriptionInfo> subscriptionInfos = subscriptionManager
+ .getAllSubscriptionInfoList();
+ for (SubscriptionInfo subscriptionInfo : subscriptionInfos) {
+ mSubscriptionInfoMap.put(
+ subscriptionInfo.getSubscriptionId(), subscriptionInfo.getIccId());
+ }
+ }
+
// Run the actual backup of data
runBackup(state, data, getAllCallLogEntries());
@@ -224,7 +247,8 @@ public class CallLogBackupAgent extends BackupAgent {
}
}
- private Iterable<Call> getAllCallLogEntries() {
+ @VisibleForTesting
+ Iterable<Call> getAllCallLogEntries() {
List<Call> calls = new LinkedList<>();
// We use the API here instead of querying ContactsDatabaseHelper directly because
@@ -258,6 +282,7 @@ public class CallLogBackupAgent extends BackupAgent {
ComponentName.unflattenFromString(call.accountComponentName), call.accountId);
}
boolean addForAllUsers = call.addForAllUsers == 1;
+
// We backup the calllog in the user running this backup agent, so write calls to this user.
Calls.addCall(null /* CallerInfo */, this, call.number, call.postDialDigits, call.viaNumber,
call.numberPresentation, call.type, call.features, handle, call.date,
@@ -265,7 +290,8 @@ public class CallLogBackupAgent extends BackupAgent {
call.callBlockReason /*callBlockReason*/,
call.callScreeningAppName /*callScreeningAppName*/,
call.callScreeningComponentName /*callScreeningComponentName*/,
- call.missedReason);
+ call.missedReason,
+ call.isPhoneAccountMigrationPending);
}
@VisibleForTesting
@@ -384,6 +410,26 @@ public class CallLogBackupAgent extends BackupAgent {
if (version >= 1008) {
call.missedReason = dataInput.readLong();
}
+ if (version >= 1009) {
+ call.isPhoneAccountMigrationPending = dataInput.readInt();
+ }
+ /**
+ * In >=T Android, Telephony PhoneAccountHandle must use SubId as the ID (the unique
+ * identifier). Any version of Telephony call logs that are restored in >=T Android
+ * should set pending migration status as true and migrate to the subId later because
+ * different devices have different mappings between SubId and IccId.
+ *
+ * In <T Android, call log PhoneAccountHandle ID uses IccId, and backup with IccId;
+ * in >=T Android, call log PhoneAccountHandle ID uses SubId, and IccId is decided to
+ * use for backup for the reason mentioned above. Every time a call log is restored,
+ * the on-devie sub Id can be determined based on its IccId. The pending migration
+ * from IccId to SubId will be complete after the PhoneAccountHandle is registrated by
+ * Telecom and before CallLogProvider unhides it.
+ */
+ if (call.accountComponentName != null && call.accountComponentName.equals(
+ TELEPHONY_PHONE_ACCOUNT_HANDLE_COMPONENT_NAME)) {
+ call.isPhoneAccountMigrationPending = 1;
+ }
return call;
} catch (IOException e) {
Log.e(TAG, "Error reading call data for " + callId, e);
@@ -391,7 +437,26 @@ public class CallLogBackupAgent extends BackupAgent {
}
}
- private Call readCallFromCursor(Cursor cursor) {
+ /**
+ * We need to use IccId for the PHONE_ACCOUNT_ID and set it as pending in backup when:
+ * 1) the phone account component name is telephony; AND
+ * 2) IS_PHONE_ACCOUNT_MIGRATION_PENDING status is not 1 ("1" means the ID is already IccId).
+ */
+ private boolean shouldConvertSubIdToIccIdForBackup(
+ String accountComponentName, int isPhoneAccountMigrationPending) {
+ if (mSubscriptionInfoMap == null) {
+ Log.e(TAG, "Subscription database is not available.");
+ return false;
+ }
+ if (accountComponentName.equals(TELEPHONY_PHONE_ACCOUNT_HANDLE_COMPONENT_NAME)
+ && isPhoneAccountMigrationPending != 1) {
+ return true;
+ }
+ return false;
+ }
+
+ @VisibleForTesting
+ Call readCallFromCursor(Cursor cursor) {
Call call = new Call();
call.id = cursor.getInt(cursor.getColumnIndex(CallLog.Calls._ID));
call.date = cursor.getLong(cursor.getColumnIndex(CallLog.Calls.DATE));
@@ -419,6 +484,31 @@ public class CallLogBackupAgent extends BackupAgent {
.getString(cursor.getColumnIndex(CallLog.Calls.CALL_SCREENING_COMPONENT_NAME));
call.missedReason = cursor
.getInt(cursor.getColumnIndex(CallLog.Calls.MISSED_REASON));
+ call.isPhoneAccountMigrationPending = cursor.getInt(
+ cursor.getColumnIndex(CallLog.Calls.IS_PHONE_ACCOUNT_MIGRATION_PENDING));
+ /*
+ * Starting Android T, the ID of Telephony PhoneAccountHandle need to migrate from IccId
+ * to SubId. Because the mapping between IccId and SubId in different devices is different,
+ * the Backup need to use IccId for the ID and set it as pending migration, and when the
+ * ID is restored, ID need migrated to SubId after the corresponding PhoneAccountHandle
+ * is registrated by Telecom and before CallLogProvider unhides them.
+ */
+ if (shouldConvertSubIdToIccIdForBackup(call.accountComponentName,
+ call.isPhoneAccountMigrationPending)) {
+ Log.i(TAG, "Processing PhoneAccountMigration Backup accountId: " + call.accountId);
+ String iccId = null;
+ try {
+ iccId = mSubscriptionInfoMap.get(Integer.parseInt(call.accountId));
+ } catch (NullPointerException e) {
+ // Ignore, iccId will be null;
+ }
+ if (iccId != null) {
+ Log.i(TAG, "processing PhoneAccountMigration Found Subid during Backup: "
+ + call.accountId);
+ call.accountId = iccId;
+ call.isPhoneAccountMigrationPending = 1;
+ }
+ }
return call;
}
@@ -465,6 +555,7 @@ public class CallLogBackupAgent extends BackupAgent {
writeInteger(data, null);
data.writeLong(call.missedReason);
+ data.writeInt(call.isPhoneAccountMigrationPending);
data.flush();
diff --git a/tests/Android.bp b/tests/Android.bp
index e54ecc0..db5ac87 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -5,7 +5,6 @@ package {
android_test {
name: "CallLogBackupTests",
- static_libs: ["mockito-target"],
libs: [
"android.test.runner",
"android.test.base",
@@ -18,4 +17,9 @@ android_test {
optimize: {
enabled: false,
},
+
+ static_libs: [
+ "mockito-target",
+ "androidx.test.rules",
+ ],
}
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index 357df4f..c6fb765 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -29,7 +29,7 @@
tests on their own then use the command:
"adb shell am instrument -w com.android.calllogbackup.tests/android.test.InstrumentationTestRunner"
-->
- <instrumentation android:name="android.test.InstrumentationTestRunner"
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="com.android.calllogbackup"
android:label="CallLog Backup Tests">
</instrumentation>
diff --git a/tests/src/com/android/calllogbackup/CallLogBackupAgentTest.java b/tests/src/com/android/calllogbackup/CallLogBackupAgentTest.java
index 4564195..9172330 100644
--- a/tests/src/com/android/calllogbackup/CallLogBackupAgentTest.java
+++ b/tests/src/com/android/calllogbackup/CallLogBackupAgentTest.java
@@ -16,15 +16,19 @@
package com.android.calllogbackup;
-import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.eq;
import android.app.backup.BackupDataOutput;
+import android.content.Context;
+import android.database.Cursor;
+import android.provider.CallLog;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
+import androidx.test.InstrumentationRegistry;
+
import com.android.calllogbackup.CallLogBackupAgent.Call;
import com.android.calllogbackup.CallLogBackupAgent.CallLogBackupState;
@@ -37,8 +41,10 @@ import org.mockito.MockitoAnnotations;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.EOFException;
+import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
import java.util.TreeSet;
/**
@@ -46,10 +52,15 @@ import java.util.TreeSet;
*/
@SmallTest
public class CallLogBackupAgentTest extends AndroidTestCase {
-
+ static final String TELEPHONY_COMPONENT
+ = "com.android.phone/com.android.services.telephony.TelephonyConnectionService";
+ static final String TEST_PHONE_ACCOUNT_HANDLE_SUB_ID = "666";
+ static final int TEST_PHONE_ACCOUNT_HANDLE_SUB_ID_INT = 666;
+ static final String TEST_PHONE_ACCOUNT_HANDLE_ICC_ID = "891004234814455936F";
@Mock DataInput mDataInput;
@Mock DataOutput mDataOutput;
@Mock BackupDataOutput mBackupDataOutput;
+ @Mock Cursor mCursor;
CallLogBackupAgent mCallLogBackupAgent;
@@ -63,7 +74,6 @@ public class CallLogBackupAgentTest extends AndroidTestCase {
// Since we're testing a system app, AppDataDirGuesser doesn't find our
// cache dir, so set it explicitly.
System.setProperty("dexmaker.dexcache", getContext().getCacheDir().toString());
-
MockitoAnnotations.initMocks(this);
mCallLogBackupAgent = new CallLogBackupAgent();
@@ -74,6 +84,11 @@ public class CallLogBackupAgentTest extends AndroidTestCase {
mMockitoHelper.tearDown();
}
+ @Override
+ public Context getTestContext() {
+ return InstrumentationRegistry.getContext();
+ }
+
public void testReadState_NoCall() throws Exception {
when(mDataInput.readInt()).thenThrow(new EOFException());
@@ -178,6 +193,30 @@ public class CallLogBackupAgentTest extends AndroidTestCase {
verify(mBackupDataOutput).writeEntityData((byte[]) Matchers.any(), Matchers.anyInt());
}
+ /*
+ Test PhoneAccountHandle Migration process during back up
+ */
+ public void testReadCallFromCursorForPhoneAccountMigrationBackup() throws Exception {
+ Map<Integer, String> subscriptionInfoMap = new HashMap<>();
+ subscriptionInfoMap.put(TEST_PHONE_ACCOUNT_HANDLE_SUB_ID_INT,
+ TEST_PHONE_ACCOUNT_HANDLE_ICC_ID);
+ mCallLogBackupAgent.mSubscriptionInfoMap = subscriptionInfoMap;
+
+ // Mock telephony component name and expect the Sub ID is converted to Icc ID
+ // and the pending status is 1 when backup
+ mockCursor(mCursor, true);
+ Call call = mCallLogBackupAgent.readCallFromCursor(mCursor);
+ assertEquals(TEST_PHONE_ACCOUNT_HANDLE_ICC_ID, call.accountId);
+ assertEquals(1, call.isPhoneAccountMigrationPending);
+
+ // Mock non-telephony component name and expect the Sub ID not converted to Icc ID
+ // and pending status is 0 when backup.
+ mockCursor(mCursor, false);
+ call = mCallLogBackupAgent.readCallFromCursor(mCursor);
+ assertEquals(TEST_PHONE_ACCOUNT_HANDLE_SUB_ID, call.accountId);
+ assertEquals(0, call.isPhoneAccountMigrationPending);
+ }
+
public void testRunBackup_MultipleCall() throws Exception {
CallLogBackupState state = new CallLogBackupState();
state.version = CallLogBackupAgent.VERSION;
@@ -216,6 +255,136 @@ public class CallLogBackupAgentTest extends AndroidTestCase {
writeEntityData((byte[]) Matchers.any(), Matchers.anyInt());
}
+ private static void mockCursor(Cursor cursor, boolean isTelephonyComponentName) {
+ when(cursor.moveToNext()).thenReturn(true).thenReturn(false);
+
+ int CALLS_ID_COLUMN_INDEX = 1;
+ int CALL_ID = 9;
+ when(cursor.getColumnIndex(CallLog.Calls._ID)).thenReturn(CALLS_ID_COLUMN_INDEX);
+ when(cursor.getInt(CALLS_ID_COLUMN_INDEX)).thenReturn(CALL_ID);
+
+ int CALLS_DATE_COLUMN_INDEX = 2;
+ long CALL_DATE = 20991231;
+ when(cursor.getColumnIndex(CallLog.Calls.DATE)).thenReturn(CALLS_DATE_COLUMN_INDEX);
+ when(cursor.getLong(CALLS_DATE_COLUMN_INDEX)).thenReturn(CALL_DATE);
+
+ int CALLS_DURATION_COLUMN_INDEX = 3;
+ long CALL_DURATION = 987654321;
+ when(cursor.getColumnIndex(CallLog.Calls.DURATION)).thenReturn(
+ CALLS_DURATION_COLUMN_INDEX);
+ when(cursor.getLong(CALLS_DURATION_COLUMN_INDEX)).thenReturn(CALL_DURATION);
+
+ int CALLS_NUMBER_COLUMN_INDEX = 4;
+ String CALL_NUMBER = "6316056461";
+ when(cursor.getColumnIndex(CallLog.Calls.NUMBER)).thenReturn(
+ CALLS_NUMBER_COLUMN_INDEX);
+ when(cursor.getString(CALLS_NUMBER_COLUMN_INDEX)).thenReturn(CALL_NUMBER);
+
+ int CALLS_POST_DIAL_DIGITS_COLUMN_INDEX = 5;
+ String CALL_POST_DIAL_DIGITS = "54321";
+ when(cursor.getColumnIndex(CallLog.Calls.POST_DIAL_DIGITS)).thenReturn(
+ CALLS_POST_DIAL_DIGITS_COLUMN_INDEX);
+ when(cursor.getString(CALLS_POST_DIAL_DIGITS_COLUMN_INDEX)).thenReturn(
+ CALL_POST_DIAL_DIGITS);
+
+ int CALLS_VIA_NUMBER_COLUMN_INDEX = 6;
+ String CALL_VIA_NUMBER = "via_number";
+ when(cursor.getColumnIndex(CallLog.Calls.VIA_NUMBER)).thenReturn(
+ CALLS_VIA_NUMBER_COLUMN_INDEX);
+ when(cursor.getString(CALLS_VIA_NUMBER_COLUMN_INDEX)).thenReturn(
+ CALL_VIA_NUMBER);
+
+ int CALLS_TYPE_COLUMN_INDEX = 7;
+ int CALL_TYPE = CallLog.Calls.OUTGOING_TYPE;
+ when(cursor.getColumnIndex(CallLog.Calls.TYPE)).thenReturn(CALLS_TYPE_COLUMN_INDEX);
+ when(cursor.getInt(CALLS_TYPE_COLUMN_INDEX)).thenReturn(CALL_TYPE);
+
+ int CALLS_NUMBER_PRESENTATION_COLUMN_INDEX = 8;
+ int CALL_NUMBER_PRESENTATION = CallLog.Calls.PRESENTATION_ALLOWED;
+ when(cursor.getColumnIndex(CallLog.Calls.NUMBER_PRESENTATION)).thenReturn(
+ CALLS_NUMBER_PRESENTATION_COLUMN_INDEX);
+ when(cursor.getInt(CALLS_NUMBER_PRESENTATION_COLUMN_INDEX)).thenReturn(
+ CALL_NUMBER_PRESENTATION);
+
+ int CALLS_ACCOUNT_COMPONENT_NAME_COLUMN_INDEX = 9;
+ String CALL_ACCOUNT_COMPONENT_NAME = "NON_TELEPHONY_COMPONENT_NAME";
+ if (isTelephonyComponentName) {
+ CALL_ACCOUNT_COMPONENT_NAME = TELEPHONY_COMPONENT;
+ }
+ when(cursor.getColumnIndex(CallLog.Calls.PHONE_ACCOUNT_COMPONENT_NAME)).thenReturn(
+ CALLS_ACCOUNT_COMPONENT_NAME_COLUMN_INDEX);
+ when(cursor.getString(CALLS_ACCOUNT_COMPONENT_NAME_COLUMN_INDEX)).thenReturn(
+ CALL_ACCOUNT_COMPONENT_NAME);
+
+ int CALLS_ACCOUNT_ID_COLUMN_INDEX = 10;
+ String CALL_ACCOUNT_ID = TEST_PHONE_ACCOUNT_HANDLE_SUB_ID;
+ when(cursor.getColumnIndex(CallLog.Calls.PHONE_ACCOUNT_ID)).thenReturn(
+ CALLS_ACCOUNT_ID_COLUMN_INDEX);
+ when(cursor.getString(CALLS_ACCOUNT_ID_COLUMN_INDEX)).thenReturn(
+ CALL_ACCOUNT_ID);
+
+ int CALLS_ACCOUNT_ADDRESS_COLUMN_INDEX = 11;
+ String CALL_ACCOUNT_ADDRESS = "CALL_ACCOUNT_ADDRESS";
+ when(cursor.getColumnIndex(CallLog.Calls.PHONE_ACCOUNT_ADDRESS)).thenReturn(
+ CALLS_ACCOUNT_ADDRESS_COLUMN_INDEX);
+ when(cursor.getString(CALLS_ACCOUNT_ADDRESS_COLUMN_INDEX)).thenReturn(
+ CALL_ACCOUNT_ADDRESS);
+
+ int CALLS_DATA_USAGE_COLUMN_INDEX = 12;
+ long CALL_DATA_USAGE = 987654321;
+ when(cursor.getColumnIndex(CallLog.Calls.DATA_USAGE)).thenReturn(
+ CALLS_DATA_USAGE_COLUMN_INDEX);
+ when(cursor.getLong(CALLS_DATA_USAGE_COLUMN_INDEX)).thenReturn(CALL_DATA_USAGE);
+
+ int CALLS_FEATURES_COLUMN_INDEX = 13;
+ int CALL_FEATURES = 777;
+ when(cursor.getColumnIndex(CallLog.Calls.FEATURES)).thenReturn(
+ CALLS_FEATURES_COLUMN_INDEX);
+ when(cursor.getInt(CALLS_FEATURES_COLUMN_INDEX)).thenReturn(CALL_FEATURES);
+
+ int CALLS_ADD_FOR_ALL_USERS_COLUMN_INDEX = 14;
+ int CALL_ADD_FOR_ALL_USERS = 1;
+ when(cursor.getColumnIndex(CallLog.Calls.ADD_FOR_ALL_USERS)).thenReturn(
+ CALLS_ADD_FOR_ALL_USERS_COLUMN_INDEX);
+ when(cursor.getInt(CALLS_ADD_FOR_ALL_USERS_COLUMN_INDEX)).thenReturn(
+ CALL_ADD_FOR_ALL_USERS);
+
+ int CALLS_BLOCK_REASON_COLUMN_INDEX = 15;
+ int CALL_BLOCK_REASON = CallLog.Calls.BLOCK_REASON_NOT_BLOCKED;
+ when(cursor.getColumnIndex(CallLog.Calls.BLOCK_REASON)).thenReturn(
+ CALLS_BLOCK_REASON_COLUMN_INDEX);
+ when(cursor.getInt(CALLS_BLOCK_REASON_COLUMN_INDEX)).thenReturn(
+ CALL_BLOCK_REASON);
+
+ int CALLS_CALL_SCREENING_APP_NAME_COLUMN_INDEX = 16;
+ String CALL_CALL_SCREENING_APP_NAME = "CALL_CALL_SCREENING_APP_NAME";
+ when(cursor.getColumnIndex(CallLog.Calls.CALL_SCREENING_APP_NAME)).thenReturn(
+ CALLS_CALL_SCREENING_APP_NAME_COLUMN_INDEX);
+ when(cursor.getString(CALLS_CALL_SCREENING_APP_NAME_COLUMN_INDEX)).thenReturn(
+ CALL_CALL_SCREENING_APP_NAME);
+
+ int CALLS_CALL_SCREENING_COMPONENT_NAME_COLUMN_INDEX = 17;
+ String CALL_CALL_SCREENING_COMPONENT_NAME = "CALL_CALL_SCREENING_COMPONENT_NAME";
+ when(cursor.getColumnIndex(CallLog.Calls.CALL_SCREENING_COMPONENT_NAME)).thenReturn(
+ CALLS_CALL_SCREENING_COMPONENT_NAME_COLUMN_INDEX);
+ when(cursor.getString(CALLS_CALL_SCREENING_COMPONENT_NAME_COLUMN_INDEX)).thenReturn(
+ CALL_CALL_SCREENING_COMPONENT_NAME);
+
+ int CALLS_MISSED_REASON_COLUMN_INDEX = 18;
+ String CALL_MISSED_REASON = "CALL_MISSED_REASON";
+ when(cursor.getColumnIndex(CallLog.Calls.MISSED_REASON)).thenReturn(
+ CALLS_MISSED_REASON_COLUMN_INDEX);
+ when(cursor.getString(CALLS_MISSED_REASON_COLUMN_INDEX)).thenReturn(
+ CALL_MISSED_REASON);
+
+ int CALLS_IS_PHONE_ACCOUNT_MIGRATION_PENDING_COLUMN_INDEX = 19;
+ int CALL_IS_PHONE_ACCOUNT_MIGRATION_PENDING = 0;
+ when(cursor.getColumnIndex(CallLog.Calls.IS_PHONE_ACCOUNT_MIGRATION_PENDING)).thenReturn(
+ CALLS_IS_PHONE_ACCOUNT_MIGRATION_PENDING_COLUMN_INDEX);
+ when(cursor.getInt(CALLS_IS_PHONE_ACCOUNT_MIGRATION_PENDING_COLUMN_INDEX)).thenReturn(
+ CALL_IS_PHONE_ACCOUNT_MIGRATION_PENDING);
+ }
+
private static Call makeCall(int id, long date, long duration, String number) {
Call c = new Call();
c.id = id;