summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/backup/BackupRestoreEventLogger.java17
-rw-r--r--core/tests/coretests/src/android/app/backup/BackupRestoreEventLoggerTest.java34
-rw-r--r--core/tests/coretests/src/android/app/backup/DataTypeResultTest.java117
-rw-r--r--packages/LocalTransport/src/com/android/localtransport/LocalTransport.java18
4 files changed, 171 insertions, 15 deletions
diff --git a/core/java/android/app/backup/BackupRestoreEventLogger.java b/core/java/android/app/backup/BackupRestoreEventLogger.java
index 112c5fd808ef..8bde3a5f2efa 100644
--- a/core/java/android/app/backup/BackupRestoreEventLogger.java
+++ b/core/java/android/app/backup/BackupRestoreEventLogger.java
@@ -34,9 +34,11 @@ import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
/**
* Class to log B&R stats for each data type that is backed up and restored by the calling app.
@@ -325,6 +327,21 @@ public final class BackupRestoreEventLogger {
}
}
+ /** @hide */
+ public static String toString(DataTypeResult result) {
+ Objects.requireNonNull(result, "result cannot be null");
+ StringBuilder string = new StringBuilder("type=").append(result.mDataType)
+ .append(", successCount=").append(result.mSuccessCount)
+ .append(", failCount=").append(result.mFailCount);
+ if (!result.mErrors.isEmpty()) {
+ string.append(", errors=").append(result.mErrors);
+ }
+ if (result.mMetadataHash != null) {
+ string.append(", metadataHash=").append(Arrays.toString(result.mMetadataHash));
+ }
+ return string.toString();
+ }
+
/**
* Encapsulate logging results for a single data type.
*/
diff --git a/core/tests/coretests/src/android/app/backup/BackupRestoreEventLoggerTest.java b/core/tests/coretests/src/android/app/backup/BackupRestoreEventLoggerTest.java
index 7b41217d6200..ab2e77e57b47 100644
--- a/core/tests/coretests/src/android/app/backup/BackupRestoreEventLoggerTest.java
+++ b/core/tests/coretests/src/android/app/backup/BackupRestoreEventLoggerTest.java
@@ -23,6 +23,8 @@ import static com.google.common.truth.Truth.assertThat;
import static junit.framework.Assert.fail;
+import static org.junit.Assert.assertThrows;
+
import android.app.backup.BackupRestoreEventLogger.DataTypeResult;
import android.os.Parcel;
import android.platform.test.annotations.Presubmit;
@@ -32,6 +34,8 @@ import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.server.backup.Flags;
+import com.google.common.truth.Expect;
+
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -42,6 +46,7 @@ import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
@Presubmit
@@ -64,6 +69,9 @@ public class BackupRestoreEventLoggerTest {
@Rule
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+ @Rule
+ public final Expect expect = Expect.create();
+
@Before
public void setUp() throws Exception {
mHashDigest = MessageDigest.getInstance("SHA-256");
@@ -366,6 +374,32 @@ public class BackupRestoreEventLoggerTest {
assertThat(mLogger.getLoggingResults()).isEmpty();
}
+ @Test
+ public void testDataTypeResultToString_nullArgs() {
+ assertThrows(NullPointerException.class, () -> BackupRestoreEventLogger.toString(null));
+ }
+
+ @Test
+ public void testDataTypeResultToString_typeOnly() {
+ DataTypeResult result = new DataTypeResult("The Type is Bond, James Bond!");
+
+ expect.withMessage("toString()")
+ .that(BackupRestoreEventLogger.toString(result)).isEqualTo(
+ "type=The Type is Bond, James Bond!, successCount=0, failCount=0");
+ }
+
+ @Test
+ public void testDataTypeResultToString_allFields() {
+ DataTypeResult result = DataTypeResultTest.createDataTypeResult(
+ "The Type is Bond, James Bond!", /* successCount= */ 42, /* failCount= */ 108,
+ Map.of("D'OH!", 666, "", 0), new byte[] { 4, 8, 15, 16, 23, 42 });
+
+ expect.withMessage("toString()")
+ .that(BackupRestoreEventLogger.toString(result)).isEqualTo(
+ "type=The Type is Bond, James Bond!, successCount=42, failCount=108, "
+ + "errors={=0, D'OH!=666}, metadataHash=[4, 8, 15, 16, 23, 42]");
+ }
+
private static DataTypeResult getResultForDataType(
BackupRestoreEventLogger logger, String dataType) {
Optional<DataTypeResult> result = getResultForDataTypeIfPresent(logger, dataType);
diff --git a/core/tests/coretests/src/android/app/backup/DataTypeResultTest.java b/core/tests/coretests/src/android/app/backup/DataTypeResultTest.java
new file mode 100644
index 000000000000..cf9e9c6e2f95
--- /dev/null
+++ b/core/tests/coretests/src/android/app/backup/DataTypeResultTest.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2025 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 android.app.backup;
+
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import android.app.backup.BackupRestoreEventLogger.DataTypeResult;
+import android.os.Bundle;
+import android.os.Parcel;
+
+import com.google.common.truth.Expect;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.util.Map;
+
+public final class DataTypeResultTest {
+
+ @Rule
+ public final Expect expect = Expect.create();
+
+ @Test
+ public void testGetters_defaultConstructorFields() {
+ var result = new DataTypeResult("The Type is Bond, James Bond!");
+
+ expect.withMessage("getDataType()").that(result.getDataType())
+ .isEqualTo("The Type is Bond, James Bond!");
+ expect.withMessage("getSuccessCount()").that(result.getSuccessCount()).isEqualTo(0);
+ expect.withMessage("getFailCount()").that(result.getFailCount()).isEqualTo(0);
+ expect.withMessage("getErrorsCount()").that(result.getErrors()).isEmpty();
+ expect.withMessage("getMetadataHash()").that(result.getMetadataHash()).isNull();
+ expect.withMessage("describeContents()").that(result.describeContents()).isEqualTo(0);
+ }
+
+ @Test
+ public void testGetters_allFields() {
+ DataTypeResult result = createDataTypeResult("The Type is Bond, James Bond!",
+ /* successCount= */ 42, /* failCount= */ 108, Map.of("D'OH!", 666),
+ new byte[] { 4, 8, 15, 16, 23, 42 });
+
+ expect.withMessage("getDataType()").that(result.getDataType())
+ .isEqualTo("The Type is Bond, James Bond!");
+ expect.withMessage("getSuccessCount()").that(result.getSuccessCount()).isEqualTo(42);
+ expect.withMessage("getFailCount()").that(result.getFailCount()).isEqualTo(108);
+ expect.withMessage("getErrorsCount()").that(result.getErrors()).containsExactly("D'OH!",
+ 666);
+ expect.withMessage("getMetadataHash()").that(result.getMetadataHash()).asList()
+ .containsExactly((byte) 4, (byte) 8, (byte) 15, (byte) 16, (byte) 23, (byte) 42)
+ .inOrder();
+ expect.withMessage("describeContents()").that(result.describeContents()).isEqualTo(0);
+ }
+
+ @Test
+ public void testParcelMethods() {
+ DataTypeResult original = createDataTypeResult("The Type is Bond, James Bond!",
+ /* successCount= */ 42, /* failCount= */ 108, Map.of("D'OH!", 666),
+ new byte[] { 4, 8, 15, 16, 23, 42 });
+ Parcel parcel = Parcel.obtain();
+ try {
+ original.writeToParcel(parcel, /* flags= */ 0);
+
+ parcel.setDataPosition(0);
+ var clone = DataTypeResult.CREATOR.createFromParcel(parcel);
+ assertWithMessage("createFromParcel()").that(clone).isNotNull();
+
+ expect.withMessage("getDataType()").that(clone.getDataType())
+ .isEqualTo(original.getDataType());
+ expect.withMessage("getSuccessCount()").that(clone.getSuccessCount())
+ .isEqualTo(original.getSuccessCount());
+ expect.withMessage("getFailCount()").that(clone.getFailCount())
+ .isEqualTo(original.getFailCount());
+ expect.withMessage("getErrorsCount()").that(clone.getErrors())
+ .containsExactlyEntriesIn(original.getErrors()).inOrder();
+ expect.withMessage("getMetadataHash()").that(clone.getMetadataHash())
+ .isEqualTo(original.getMetadataHash());
+ expect.withMessage("describeContents()").that(clone.describeContents()).isEqualTo(0);
+ } finally {
+ parcel.recycle();
+ }
+ }
+
+ static DataTypeResult createDataTypeResult(String dataType, int successCount, int failCount,
+ Map<String, Integer> errors, byte... metadataHash) {
+ Parcel parcel = Parcel.obtain();
+ try {
+ parcel.writeString(dataType);
+ parcel.writeInt(successCount);
+ parcel.writeInt(failCount);
+ Bundle errorsBundle = new Bundle();
+ errors.entrySet()
+ .forEach(entry -> errorsBundle.putInt(entry.getKey(), entry.getValue()));
+ parcel.writeBundle(errorsBundle);
+ parcel.writeByteArray(metadataHash);
+
+ parcel.setDataPosition(0);
+ var result = DataTypeResult.CREATOR.createFromParcel(parcel);
+ assertWithMessage("createFromParcel()").that(result).isNotNull();
+ return result;
+ } finally {
+ parcel.recycle();
+ }
+ }
+}
diff --git a/packages/LocalTransport/src/com/android/localtransport/LocalTransport.java b/packages/LocalTransport/src/com/android/localtransport/LocalTransport.java
index a3b06e8c71fc..1af3bc898306 100644
--- a/packages/LocalTransport/src/com/android/localtransport/LocalTransport.java
+++ b/packages/LocalTransport/src/com/android/localtransport/LocalTransport.java
@@ -23,6 +23,7 @@ import android.app.backup.BackupAnnotations;
import android.app.backup.BackupDataInput;
import android.app.backup.BackupDataOutput;
import android.app.backup.BackupManagerMonitor;
+import android.app.backup.BackupRestoreEventLogger;
import android.app.backup.BackupRestoreEventLogger.DataTypeResult;
import android.app.backup.BackupTransport;
import android.app.backup.RestoreDescription;
@@ -52,7 +53,6 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -924,21 +924,9 @@ public class LocalTransport extends BackupTransport {
BackupManagerMonitor.EXTRA_LOG_AGENT_LOGGING_RESULTS,
DataTypeResult.class);
for (DataTypeResult result : results) {
- Log.i(TAG, "\tdataType: " + result.getDataType());
- Log.i(TAG, "\tsuccessCount: " + result.getSuccessCount());
- Log.i(TAG, "\tfailCount: " + result.getFailCount());
- Log.i(TAG, "\tmetadataHash: " + Arrays.toString(result.getMetadataHash()));
-
- if (!result.getErrors().isEmpty()) {
- Log.i(TAG, "\terrors {");
- for (String error : result.getErrors().keySet()) {
- Log.i(TAG, "\t\t" + error + ": " + result.getErrors().get(error));
- }
- Log.i(TAG, "\t}");
- }
-
- Log.i(TAG, "}");
+ Log.i(TAG, "\t" + BackupRestoreEventLogger.toString(result));
}
+ Log.i(TAG, "}");
}
}
}