summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSantos Cordon <santoscordon@google.com>2015-02-26 19:51:59 -0800
committerSantos Cordon <santoscordon@google.com>2015-02-26 19:51:59 -0800
commit52a1f4d4882c1e1db7a597f1bddb1cbeaf7af5de (patch)
treefc603c147c85138d83b5c9141737ea10ce2420f3
parent153281e5a15c9fa4db08dace265eb6556216066f (diff)
downloadpackages_providers_ContactsProvider-52a1f4d4882c1e1db7a597f1bddb1cbeaf7af5de.zip
packages_providers_ContactsProvider-52a1f4d4882c1e1db7a597f1bddb1cbeaf7af5de.tar.gz
packages_providers_ContactsProvider-52a1f4d4882c1e1db7a597f1bddb1cbeaf7af5de.tar.bz2
More tests for CallLogBackupAgent
Change-Id: I5f8ff641bbd3b9c186cb6e2e230ae70d02055fe4
-rw-r--r--src/com/android/providers/contacts/CallLogBackupAgent.java125
-rw-r--r--tests/src/com/android/providers/contacts/CallLogBackupAgentTest.java98
2 files changed, 166 insertions, 57 deletions
diff --git a/src/com/android/providers/contacts/CallLogBackupAgent.java b/src/com/android/providers/contacts/CallLogBackupAgent.java
index e5c77e6..8e160c8 100644
--- a/src/com/android/providers/contacts/CallLogBackupAgent.java
+++ b/src/com/android/providers/contacts/CallLogBackupAgent.java
@@ -26,6 +26,7 @@ import android.os.ParcelFileDescriptor;
import android.provider.CallLog;
import android.provider.CallLog.Calls;
import android.telecom.PhoneAccountHandle;
+import android.text.TextUtils;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
@@ -41,6 +42,8 @@ import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.util.LinkedList;
+import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
@@ -55,7 +58,8 @@ public class CallLogBackupAgent extends BackupAgent {
SortedSet<Integer> callIds;
}
- private static class Call {
+ @VisibleForTesting
+ static class Call {
int id;
long date;
long duration;
@@ -82,7 +86,8 @@ public class CallLogBackupAgent extends BackupAgent {
private static final String TAG = "CallLogBackupAgent";
/** Current version of CallLogBackup. Used to track the backup format. */
- private static final int VERSION = 1;
+ @VisibleForTesting
+ static final int VERSION = 1002;
/** Version indicating that there exists no previous backup entry. */
@VisibleForTesting
static final int VERSION_NO_PREVIOUS_STATE = 0;
@@ -119,7 +124,7 @@ public class CallLogBackupAgent extends BackupAgent {
}
// Run the actual backup of data
- runBackup(state, data);
+ runBackup(state, data, getAllCallLogEntries());
// Rewrite the backup state.
DataOutputStream dataOutput = new DataOutputStream(new BufferedOutputStream(
@@ -151,59 +156,62 @@ public class CallLogBackupAgent extends BackupAgent {
}
@VisibleForTesting
- void runBackup(CallLogBackupState state, BackupDataOutput data) {
+ void runBackup(CallLogBackupState state, BackupDataOutput data, Iterable<Call> calls) {
SortedSet<Integer> callsToRemove = new TreeSet<>(state.callIds);
- // Get all the existing call log entries.
- Cursor cursor = getAllCallLogEntries();
- if (cursor == null) {
- return;
- }
-
- try {
- // Loop through all the call log entries to identify:
- // (1) new calls
- // (2) calls which have been deleted.
- while (cursor.moveToNext()) {
- Call call = readCallFromCursor(cursor);
-
- if (!state.callIds.contains(call.id)) {
-
- if (isDebug()) {
- Log.d(TAG, "Adding call to backup: " + call);
- }
-
- // This call new (not in our list from the last backup), lets back it up.
- addCallToBackup(data, call);
- state.callIds.add(call.id);
- } else {
- // This call still exists in the current call log so delete it from the
- // "callsToRemove" set since we want to keep it.
- callsToRemove.remove(call.id);
- }
- }
+ // Loop through all the call log entries to identify:
+ // (1) new calls
+ // (2) calls which have been deleted.
+ for (Call call : calls) {
+ if (!state.callIds.contains(call.id)) {
- // Remove calls which no longer exist in the set.
- for (Integer i : callsToRemove) {
if (isDebug()) {
- Log.d(TAG, "Removing call from backup: " + i);
+ Log.d(TAG, "Adding call to backup: " + call);
}
- removeCallFromBackup(data, i);
- state.callIds.remove(i);
+ // This call new (not in our list from the last backup), lets back it up.
+ addCallToBackup(data, call);
+ state.callIds.add(call.id);
+ } else {
+ // This call still exists in the current call log so delete it from the
+ // "callsToRemove" set since we want to keep it.
+ callsToRemove.remove(call.id);
}
+ }
- } finally {
- cursor.close();
+ // Remove calls which no longer exist in the set.
+ for (Integer i : callsToRemove) {
+ if (isDebug()) {
+ Log.d(TAG, "Removing call from backup: " + i);
+ }
+
+ removeCallFromBackup(data, i);
+ state.callIds.remove(i);
}
}
- private Cursor getAllCallLogEntries() {
+ private Iterable<Call> getAllCallLogEntries() {
+ List<Call> calls = new LinkedList<>();
+
// We use the API here instead of querying ContactsDatabaseHelper directly because
// CallLogProvider has special locks in place for sychronizing when to read. Using the APIs
// gives us that for free.
ContentResolver resolver = getContentResolver();
- return resolver.query(CallLog.Calls.CONTENT_URI, CALL_LOG_PROJECTION, null, null, null);
+ Cursor cursor = resolver.query(CallLog.Calls.CONTENT_URI, CALL_LOG_PROJECTION, null, null, null);
+ if (cursor != null) {
+ try {
+ while (cursor.moveToNext()) {
+ Call call = readCallFromCursor(cursor);
+ if (call != null) {
+ calls.add(call);
+ }
+ }
+ } finally {
+ cursor.close();
+ }
+ }
+
+ return calls;
}
private void writeCallToProvider(Call call) {
@@ -277,10 +285,10 @@ public class CallLogBackupAgent extends BackupAgent {
if (version >= 1) {
call.date = dataInput.readLong();
call.duration = dataInput.readLong();
- call.number = dataInput.readUTF();
+ call.number = readString(dataInput, version);
call.type = dataInput.readInt();
call.numberPresentation = dataInput.readInt();
- call.accountComponentName = dataInput.readUTF();
+ call.accountComponentName = readString(dataInput, version);
call.accountId = dataInput.readUTF();
call.accountAddress = dataInput.readUTF();
call.dataUsage = dataInput.readLong();
@@ -322,13 +330,13 @@ public class CallLogBackupAgent extends BackupAgent {
data.writeInt(VERSION);
data.writeLong(call.date);
data.writeLong(call.duration);
- data.writeUTF(call.number);
+ writeString(data, call.number);
data.writeInt(call.type);
data.writeInt(call.numberPresentation);
- data.writeUTF(call.accountComponentName);
- data.writeUTF(call.accountId);
- data.writeUTF(call.accountAddress);
- data.writeLong(call.dataUsage);
+ writeString(data, call.accountComponentName);
+ writeString(data, call.accountId);
+ writeString(data, call.accountAddress);
+ data.writeLong(call.dataUsage == null ? 0 : call.dataUsage);
data.writeInt(call.features);
data.flush();
@@ -343,6 +351,27 @@ public class CallLogBackupAgent extends BackupAgent {
}
}
+ private void writeString(DataOutputStream data, String str) throws IOException {
+ if (str == null) {
+ data.writeBoolean(false);
+ } else {
+ data.writeBoolean(true);
+ data.writeUTF(str);
+ }
+ }
+
+ private String readString(DataInputStream data, int version) throws IOException {
+ if (version == 1) {
+ return data.readUTF();
+ } else {
+ if (data.readBoolean()) {
+ return data.readUTF();
+ } else {
+ return null;
+ }
+ }
+ }
+
private void removeCallFromBackup(BackupDataOutput output, int callId) {
try {
output.writeEntityHeader(Integer.toString(callId), -1);
diff --git a/tests/src/com/android/providers/contacts/CallLogBackupAgentTest.java b/tests/src/com/android/providers/contacts/CallLogBackupAgentTest.java
index 2699f65..ca9af91 100644
--- a/tests/src/com/android/providers/contacts/CallLogBackupAgentTest.java
+++ b/tests/src/com/android/providers/contacts/CallLogBackupAgentTest.java
@@ -16,17 +16,20 @@
package com.android.providers.contacts;
-import static org.mockito.Mockito.when;
-import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.eq;
+import android.app.backup.BackupDataOutput;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
+import com.android.providers.contacts.CallLogBackupAgent.Call;
import com.android.providers.contacts.CallLogBackupAgent.CallLogBackupState;
import org.mockito.InOrder;
+import org.mockito.Matchers;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
@@ -34,6 +37,8 @@ import org.mockito.MockitoAnnotations;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.EOFException;
+import java.util.LinkedList;
+import java.util.List;
import java.util.TreeSet;
/**
@@ -44,6 +49,7 @@ public class CallLogBackupAgentTest extends AndroidTestCase {
@Mock DataInput mDataInput;
@Mock DataOutput mDataOutput;
+ @Mock BackupDataOutput mBackupDataOutput;
CallLogBackupAgent mCallLogBackupAgent;
@@ -107,32 +113,33 @@ public class CallLogBackupAgentTest extends AndroidTestCase {
public void testWriteState_NoCalls() throws Exception {
CallLogBackupState state = new CallLogBackupState();
- state.version = 1;
+ state.version = CallLogBackupAgent.VERSION;
state.callIds = new TreeSet<>();
mCallLogBackupAgent.writeState(mDataOutput, state);
InOrder inOrder = Mockito.inOrder(mDataOutput);
- inOrder.verify(mDataOutput).writeInt(1 /* version */);
+ inOrder.verify(mDataOutput).writeInt(CallLogBackupAgent.VERSION);
inOrder.verify(mDataOutput).writeInt(0 /* size */);
}
public void testWriteState_OneCall() throws Exception {
CallLogBackupState state = new CallLogBackupState();
- state.version = 1;
+ state.version = CallLogBackupAgent.VERSION;
state.callIds = new TreeSet<>();
state.callIds.add(101);
mCallLogBackupAgent.writeState(mDataOutput, state);
InOrder inOrder = Mockito.inOrder(mDataOutput);
- inOrder.verify(mDataOutput, times(2)).writeInt(1);
+ inOrder.verify(mDataOutput).writeInt(CallLogBackupAgent.VERSION);
+ inOrder.verify(mDataOutput).writeInt(1);
inOrder.verify(mDataOutput).writeInt(101 /* call-ID */);
}
public void testWriteState_MultipleCalls() throws Exception {
CallLogBackupState state = new CallLogBackupState();
- state.version = 1;
+ state.version = CallLogBackupAgent.VERSION;
state.callIds = new TreeSet<>();
state.callIds.add(101);
state.callIds.add(102);
@@ -141,10 +148,83 @@ public class CallLogBackupAgentTest extends AndroidTestCase {
mCallLogBackupAgent.writeState(mDataOutput, state);
InOrder inOrder = Mockito.inOrder(mDataOutput);
- inOrder.verify(mDataOutput).writeInt(1 /* version */);
+ inOrder.verify(mDataOutput).writeInt(CallLogBackupAgent.VERSION);
inOrder.verify(mDataOutput).writeInt(3 /* size */);
inOrder.verify(mDataOutput).writeInt(101 /* call-ID */);
inOrder.verify(mDataOutput).writeInt(102 /* call-ID */);
inOrder.verify(mDataOutput).writeInt(103 /* call-ID */);
}
+
+ public void testRunBackup_NoCalls() throws Exception {
+ CallLogBackupState state = new CallLogBackupState();
+ state.version = CallLogBackupAgent.VERSION;
+ state.callIds = new TreeSet<>();
+ List<Call> calls = new LinkedList<>();
+
+ mCallLogBackupAgent.runBackup(state, mBackupDataOutput, calls);
+
+ Mockito.verifyNoMoreInteractions(mBackupDataOutput);
+ }
+
+ public void testRunBackup_OneNewCall() throws Exception {
+ CallLogBackupState state = new CallLogBackupState();
+ state.version = CallLogBackupAgent.VERSION;
+ state.callIds = new TreeSet<>();
+ List<Call> calls = new LinkedList<>();
+ calls.add(makeCall(101, 0L, 0L, "555-5555"));
+ mCallLogBackupAgent.runBackup(state, mBackupDataOutput, calls);
+
+ verify(mBackupDataOutput).writeEntityHeader(eq("101"), Matchers.anyInt());
+ verify(mBackupDataOutput).writeEntityData((byte[]) Matchers.any(), Matchers.anyInt());
+ }
+
+ public void testRunBackup_MultipleCall() throws Exception {
+ CallLogBackupState state = new CallLogBackupState();
+ state.version = CallLogBackupAgent.VERSION;
+ state.callIds = new TreeSet<>();
+ List<Call> calls = new LinkedList<>();
+ calls.add(makeCall(101, 0L, 0L, "555-1234"));
+ calls.add(makeCall(102, 0L, 0L, "555-5555"));
+
+ mCallLogBackupAgent.runBackup(state, mBackupDataOutput, calls);
+
+ InOrder inOrder = Mockito.inOrder(mBackupDataOutput);
+ inOrder.verify(mBackupDataOutput).writeEntityHeader(eq("101"), Matchers.anyInt());
+ inOrder.verify(mBackupDataOutput).
+ writeEntityData((byte[]) Matchers.any(), Matchers.anyInt());
+ inOrder.verify(mBackupDataOutput).writeEntityHeader(eq("102"), Matchers.anyInt());
+ inOrder.verify(mBackupDataOutput).
+ writeEntityData((byte[]) Matchers.any(), Matchers.anyInt());
+ }
+
+ public void testRunBackup_PartialMultipleCall() throws Exception {
+ CallLogBackupState state = new CallLogBackupState();
+
+ state.version = CallLogBackupAgent.VERSION;
+ state.callIds = new TreeSet<>();
+ state.callIds.add(101);
+
+ List<Call> calls = new LinkedList<>();
+ calls.add(makeCall(101, 0L, 0L, "555-1234"));
+ calls.add(makeCall(102, 0L, 0L, "555-5555"));
+
+ mCallLogBackupAgent.runBackup(state, mBackupDataOutput, calls);
+
+ InOrder inOrder = Mockito.inOrder(mBackupDataOutput);
+ inOrder.verify(mBackupDataOutput).writeEntityHeader(eq("102"), Matchers.anyInt());
+ inOrder.verify(mBackupDataOutput).
+ writeEntityData((byte[]) Matchers.any(), Matchers.anyInt());
+ }
+
+ private static Call makeCall(int id, long date, long duration, String number) {
+ Call c = new Call();
+ c.id = id;
+ c.date = date;
+ c.duration = duration;
+ c.number = number;
+ c.accountComponentName = "account-component";
+ c.accountId = "account-id";
+ return c;
+ }
+
}