summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-07-07 05:20:27 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-07-07 05:20:27 +0000
commit838e2a288a94166123bef4df2effe103c0abe3dd (patch)
treebd7ea01673df3ee3660759e7e385aab52777f9d8
parent5ecb443a10875a86baf1bbad15bcc332351ea924 (diff)
parente225f918a40322f7f16f007987d965dbcab56bee (diff)
downloadCallLogProvider-android14-mainline-sdkext-release.tar.gz
Snap for 10453563 from e225f918a40322f7f16f007987d965dbcab56bee to mainline-sdkext-releaseaml_sdk_341510000aml_sdk_341410000aml_sdk_341110080aml_sdk_341110000aml_sdk_341010000aml_sdk_340912010android14-mainline-sdkext-release
Change-Id: I246bd251970a033f74e5b8d969780ffa25751e54
-rw-r--r--src/com/android/calllogbackup/CallLogBackupAgent.java82
-rw-r--r--tests/src/com/android/calllogbackup/CallLogBackupAgentTest.java79
2 files changed, 160 insertions, 1 deletions
diff --git a/src/com/android/calllogbackup/CallLogBackupAgent.java b/src/com/android/calllogbackup/CallLogBackupAgent.java
index 8b58f99..4bb55b0 100644
--- a/src/com/android/calllogbackup/CallLogBackupAgent.java
+++ b/src/com/android/calllogbackup/CallLogBackupAgent.java
@@ -21,6 +21,8 @@ import static android.provider.CallLog.Calls.MISSED_REASON_NOT_MISSED;
import android.app.backup.BackupAgent;
import android.app.backup.BackupDataInput;
import android.app.backup.BackupDataOutput;
+import android.app.backup.BackupManager;
+import android.app.backup.BackupRestoreEventLogger;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.database.Cursor;
@@ -108,6 +110,22 @@ public class CallLogBackupAgent extends BackupAgent {
private static final String TAG = "CallLogBackupAgent";
+ /** Data types and errors used when reporting B&R success rate and errors. */
+ @BackupRestoreEventLogger.BackupRestoreDataType
+ @VisibleForTesting
+ static final String CALLLOGS = "telecom_call_logs";
+
+ @BackupRestoreEventLogger.BackupRestoreError
+ static final String ERROR_UNEXPECTED_KEY = "unexpected_key";
+ @BackupRestoreEventLogger.BackupRestoreError
+ static final String ERROR_END_OEM_MARKER_NOT_FOUND = "end_oem_marker_not_found";
+ @BackupRestoreEventLogger.BackupRestoreError
+ static final String ERROR_READING_CALL_DATA = "error_reading_call_data";
+ @BackupRestoreEventLogger.BackupRestoreError
+ static final String ERROR_BACKUP_CALL_FAILED = "backup_call_failed";
+
+ private BackupRestoreEventLogger mLogger;
+
/** Current version of CallLogBackup. Used to track the backup format. */
@VisibleForTesting
static final int VERSION = 1009;
@@ -151,6 +169,56 @@ public class CallLogBackupAgent extends BackupAgent {
CallLog.Calls.IS_PHONE_ACCOUNT_MIGRATION_PENDING
};
+ /**
+ * BackupRestoreEventLogger Dependencies for testing.
+ */
+ @VisibleForTesting
+ public interface BackupRestoreEventLoggerProxy {
+ void logItemsBackedUp(String dataType, int count);
+ void logItemsBackupFailed(String dataType, int count, String error);
+ void logItemsRestored(String dataType, int count);
+ void logItemsRestoreFailed(String dataType, int count, String error);
+ }
+
+ private BackupRestoreEventLoggerProxy mBackupRestoreEventLoggerProxy =
+ new BackupRestoreEventLoggerProxy() {
+ @Override
+ public void logItemsBackedUp(String dataType, int count) {
+ mLogger.logItemsBackedUp(dataType, count);
+ }
+
+ @Override
+ public void logItemsBackupFailed(String dataType, int count, String error) {
+ mLogger.logItemsBackupFailed(dataType, count, error);
+ }
+
+ @Override
+ public void logItemsRestored(String dataType, int count) {
+ mLogger.logItemsRestored(dataType, count);
+ }
+
+ @Override
+ public void logItemsRestoreFailed(String dataType, int count, String error) {
+ mLogger.logItemsRestoreFailed(dataType, count, error);
+ }
+ };
+
+ /**
+ * Overrides BackupRestoreEventLogger dependencies for testing.
+ */
+ @VisibleForTesting
+ public void setBackupRestoreEventLoggerProxy(BackupRestoreEventLoggerProxy proxy) {
+ mBackupRestoreEventLoggerProxy = proxy;
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ Log.d(TAG, "onCreate");
+ BackupManager backupManager = new BackupManager(getApplicationContext());
+ mLogger = backupManager.getBackupRestoreEventLogger(/* backupAgent */ this);
+ }
+
/** ${inheritDoc} */
@Override
public void onBackup(ParcelFileDescriptor oldStateDescriptor, BackupDataOutput data,
@@ -205,6 +273,7 @@ public class CallLogBackupAgent extends BackupAgent {
Call call = readCallFromData(data);
if (call != null && call.type != Calls.VOICEMAIL_TYPE) {
writeCallToProvider(call);
+ mBackupRestoreEventLoggerProxy.logItemsRestored(CALLLOGS, /* count */ 1);
if (isDebug()) {
Log.d(TAG, "Restored call: " + call);
}
@@ -233,6 +302,7 @@ public class CallLogBackupAgent extends BackupAgent {
// 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);
+ mBackupRestoreEventLoggerProxy.logItemsBackedUp(CALLLOGS, /* count */ 1);
}
}
@@ -339,6 +409,8 @@ public class CallLogBackupAgent extends BackupAgent {
try {
callId = Integer.parseInt(data.getKey());
} catch (NumberFormatException e) {
+ mBackupRestoreEventLoggerProxy.logItemsRestoreFailed(
+ CALLLOGS, /* count */ 1, ERROR_UNEXPECTED_KEY);
Log.e(TAG, "Unexpected key found in restore: " + data.getKey());
return null;
}
@@ -374,6 +446,8 @@ public class CallLogBackupAgent extends BackupAgent {
int marker = dataInput.readInt();
if (marker != END_OEM_DATA_MARKER) {
+ mBackupRestoreEventLoggerProxy.logItemsRestoreFailed(CALLLOGS, /* count */ 1,
+ ERROR_END_OEM_MARKER_NOT_FOUND);
Log.e(TAG, "Did not find END-OEM marker for call " + call.id);
// The marker does not match the expected value, ignore this call completely.
return null;
@@ -432,6 +506,8 @@ public class CallLogBackupAgent extends BackupAgent {
}
return call;
} catch (IOException e) {
+ mBackupRestoreEventLoggerProxy.logItemsRestoreFailed(
+ CALLLOGS, /* count */ 1, ERROR_READING_CALL_DATA);
Log.e(TAG, "Error reading call data for " + callId, e);
return null;
}
@@ -566,10 +642,14 @@ public class CallLogBackupAgent extends BackupAgent {
output.writeEntityHeader(Integer.toString(call.id), baos.size());
output.writeEntityData(baos.toByteArray(), baos.size());
+ mBackupRestoreEventLoggerProxy.logItemsBackedUp(CALLLOGS, /* count */ 1);
+
if (isDebug()) {
Log.d(TAG, "Wrote call to backup: " + call + " with byte array: " + baos);
}
- } catch (IOException e) {
+ } catch (Exception e) {
+ mBackupRestoreEventLoggerProxy.logItemsBackupFailed(
+ CALLLOGS, /* count */ 1, ERROR_BACKUP_CALL_FAILED);
Log.e(TAG, "Failed to backup call: " + call, e);
}
}
diff --git a/tests/src/com/android/calllogbackup/CallLogBackupAgentTest.java b/tests/src/com/android/calllogbackup/CallLogBackupAgentTest.java
index 4567e40..de681e5 100644
--- a/tests/src/com/android/calllogbackup/CallLogBackupAgentTest.java
+++ b/tests/src/com/android/calllogbackup/CallLogBackupAgentTest.java
@@ -16,6 +16,8 @@
package com.android.calllogbackup;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.eq;
@@ -41,6 +43,7 @@ import org.mockito.MockitoAnnotations;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.EOFException;
+import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
@@ -57,11 +60,38 @@ public class CallLogBackupAgentTest extends AndroidTestCase {
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";
+
+ public int backupRestoreLoggerSuccessCount = 0;
+ public int backupRestoreLoggerFailCount = 0;
+
@Mock DataInput mDataInput;
@Mock DataOutput mDataOutput;
@Mock BackupDataOutput mBackupDataOutput;
@Mock Cursor mCursor;
+ private CallLogBackupAgent.BackupRestoreEventLoggerProxy mBackupRestoreEventLoggerProxy =
+ new CallLogBackupAgent.BackupRestoreEventLoggerProxy() {
+ @Override
+ public void logItemsBackedUp(String dataType, int count) {
+ backupRestoreLoggerSuccessCount += count;
+ }
+
+ @Override
+ public void logItemsBackupFailed(String dataType, int count, String error) {
+ backupRestoreLoggerFailCount += count;
+ }
+
+ @Override
+ public void logItemsRestored(String dataType, int count) {
+ backupRestoreLoggerSuccessCount += count;
+ }
+
+ @Override
+ public void logItemsRestoreFailed(String dataType, int count, String error) {
+ backupRestoreLoggerFailCount += count;
+ }
+ };
+
CallLogBackupAgent mCallLogBackupAgent;
MockitoHelper mMockitoHelper = new MockitoHelper();
@@ -77,6 +107,7 @@ public class CallLogBackupAgentTest extends AndroidTestCase {
MockitoAnnotations.initMocks(this);
mCallLogBackupAgent = new CallLogBackupAgent();
+ mCallLogBackupAgent.setBackupRestoreEventLoggerProxy(mBackupRestoreEventLoggerProxy);
}
@Override
@@ -178,9 +209,45 @@ public class CallLogBackupAgentTest extends AndroidTestCase {
mCallLogBackupAgent.runBackup(state, mBackupDataOutput, calls);
+ // Ensure the {@link BackupRestoreEventLogger} is not notified as no calls were backed up:
+ assertEquals(backupRestoreLoggerSuccessCount, 0);
+ assertEquals(backupRestoreLoggerFailCount, 0);
+
Mockito.verifyNoMoreInteractions(mBackupDataOutput);
}
+ public void testRunBackup_OneNewCall_ErrorAddingCall() 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"));
+
+ // Throw an exception when the call is added to the backup:
+ when(mBackupDataOutput.writeEntityData(any(byte[].class), anyInt()))
+ .thenThrow(IOException.class);
+ mCallLogBackupAgent.runBackup(state, mBackupDataOutput, calls);
+
+ // Ensure the {@link BackupRestoreEventLogger} is informed of the failed backed up call:
+ assertEquals(backupRestoreLoggerSuccessCount, 0);
+ assertEquals(backupRestoreLoggerFailCount, 1);
+ }
+
+ public void testRunBackup_OneNewCall_NullBackupDataOutput() 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"));
+
+ // Invoke runBackup() with a null value for BackupDataOutput causing an exception:
+ mCallLogBackupAgent.runBackup(state, null, calls);
+
+ // Ensure the {@link BackupRestoreEventLogger} is informed of the failed backed up call:
+ assertEquals(backupRestoreLoggerSuccessCount, 0);
+ assertEquals(backupRestoreLoggerFailCount, 1);
+ }
+
public void testRunBackup_OneNewCall() throws Exception {
CallLogBackupState state = new CallLogBackupState();
state.version = CallLogBackupAgent.VERSION;
@@ -189,6 +256,10 @@ public class CallLogBackupAgentTest extends AndroidTestCase {
calls.add(makeCall(101, 0L, 0L, "555-5555"));
mCallLogBackupAgent.runBackup(state, mBackupDataOutput, calls);
+ // Ensure the {@link BackupRestoreEventLogger} is informed of the backed up call:
+ assertEquals(backupRestoreLoggerSuccessCount, 1);
+ assertEquals(backupRestoreLoggerFailCount, 0);
+
verify(mBackupDataOutput).writeEntityHeader(eq("101"), Matchers.anyInt());
verify(mBackupDataOutput).writeEntityData((byte[]) Matchers.any(), Matchers.anyInt());
}
@@ -274,6 +345,10 @@ public class CallLogBackupAgentTest extends AndroidTestCase {
mCallLogBackupAgent.runBackup(state, mBackupDataOutput, calls);
+ // Ensure the {@link BackupRestoreEventLogger} is informed of the 2 backed up calls:
+ assertEquals(backupRestoreLoggerSuccessCount, 2);
+ assertEquals(backupRestoreLoggerFailCount, 0);
+
InOrder inOrder = Mockito.inOrder(mBackupDataOutput);
inOrder.verify(mBackupDataOutput).writeEntityHeader(eq("101"), Matchers.anyInt());
inOrder.verify(mBackupDataOutput).
@@ -296,6 +371,10 @@ public class CallLogBackupAgentTest extends AndroidTestCase {
mCallLogBackupAgent.runBackup(state, mBackupDataOutput, calls);
+ // Ensure the {@link BackupRestoreEventLogger} is informed of the 2 backed up calls:
+ assertEquals(backupRestoreLoggerSuccessCount, 2);
+ assertEquals(backupRestoreLoggerFailCount, 0);
+
InOrder inOrder = Mockito.inOrder(mBackupDataOutput);
inOrder.verify(mBackupDataOutput).writeEntityHeader(eq("102"), Matchers.anyInt());
inOrder.verify(mBackupDataOutput).