Enable SystemBackupAgent to integrate with metrics.
Pass a logger instance to BackupHelpers in SystemBackupAgent.
Bug: 296844513
Test: atest -v SystemBackupAgentTest; manual: override flag value, add log events to some helpers in the SystemBackupAgent, check that the correct agent logs are printed in the backup dumpsys.
Change-Id: I2d14d49516849f4c992e8180baf4c3d431326a26
diff --git a/core/java/android/app/backup/BackupHelperWithLogger.java b/core/java/android/app/backup/BackupHelperWithLogger.java
new file mode 100644
index 0000000..1a59a53
--- /dev/null
+++ b/core/java/android/app/backup/BackupHelperWithLogger.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2023 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 android.os.ParcelFileDescriptor;
+
+/**
+ * Utility class for writing BackupHelpers with added logging capabilities.
+ * Used for passing a logger object to Helper in key shared backup agents
+ *
+ * @hide
+ */
+public abstract class BackupHelperWithLogger implements BackupHelper {
+ private BackupRestoreEventLogger mLogger;
+ private boolean mIsLoggerSet = false;
+
+ public abstract void writeNewStateDescription(ParcelFileDescriptor newState);
+
+ public abstract void restoreEntity(BackupDataInputStream data);
+
+ public abstract void performBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
+ ParcelFileDescriptor newState);
+
+ /**
+ * Gets the logger so that the backuphelper can log success/error for each datatype handled
+ */
+ public BackupRestoreEventLogger getLogger() {
+ return mLogger;
+ }
+
+ /**
+ * Allow the shared backup agent to pass a logger to each of its backup helper
+ */
+ public void setLogger(BackupRestoreEventLogger logger) {
+ mLogger = logger;
+ mIsLoggerSet = true;
+ }
+
+ /**
+ * Allow the helper to check if its shared backup agent has passed a logger
+ */
+ public boolean isLoggerSet() {
+ return mIsLoggerSet;
+ }
+}
diff --git a/core/java/android/app/backup/BlobBackupHelper.java b/core/java/android/app/backup/BlobBackupHelper.java
index 82d0a94c..a55ff48 100644
--- a/core/java/android/app/backup/BlobBackupHelper.java
+++ b/core/java/android/app/backup/BlobBackupHelper.java
@@ -39,7 +39,7 @@
*
* @hide
*/
-public abstract class BlobBackupHelper implements BackupHelper {
+public abstract class BlobBackupHelper extends BackupHelperWithLogger {
private static final String TAG = "BlobBackupHelper";
private static final boolean DEBUG = false;
diff --git a/core/java/com/android/server/backup/AccountSyncSettingsBackupHelper.java b/core/java/com/android/server/backup/AccountSyncSettingsBackupHelper.java
index ce9ab82..2ff6225 100644
--- a/core/java/com/android/server/backup/AccountSyncSettingsBackupHelper.java
+++ b/core/java/com/android/server/backup/AccountSyncSettingsBackupHelper.java
@@ -21,6 +21,7 @@
import android.app.backup.BackupDataInputStream;
import android.app.backup.BackupDataOutput;
import android.app.backup.BackupHelper;
+import android.app.backup.BackupHelperWithLogger;
import android.content.ContentResolver;
import android.content.Context;
import android.content.SyncAdapterType;
@@ -56,7 +57,7 @@
* sync settings are backed up as a JSON object containing all the necessary information for
* restoring the sync settings later.
*/
-public class AccountSyncSettingsBackupHelper implements BackupHelper {
+public class AccountSyncSettingsBackupHelper extends BackupHelperWithLogger {
private static final String TAG = "AccountSyncSettingsBackupHelper";
private static final boolean DEBUG = false;
diff --git a/services/backup/flags.aconfig b/services/backup/flags.aconfig
index 549fa36..4022e33 100644
--- a/services/backup/flags.aconfig
+++ b/services/backup/flags.aconfig
@@ -10,6 +10,15 @@
}
flag {
+ name: "enable_metrics_system_backup_agents"
+ namespace: "backup"
+ description: "Enable SystemBackupAgent to collect B&R agent metrics by passing an instance of "
+ "the logger to each BackupHelper."
+ bug: "296844513"
+ is_fixed_read_only: true
+}
+
+flag {
name: "enable_max_size_writes_to_pipes"
namespace: "onboarding"
description: "Enables the write buffer to pipes to be of maximum size."
diff --git a/services/core/Android.bp b/services/core/Android.bp
index fdcd27d..3164e08 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -211,6 +211,7 @@
"com_android_wm_shell_flags_lib",
"com.android.server.utils_aconfig-java",
"service-jobscheduler-deviceidle.flags-aconfig-java",
+ "backup_flags_lib",
"policy_flags_lib",
],
javac_shard_size: 50,
diff --git a/services/core/java/com/android/server/backup/SystemBackupAgent.java b/services/core/java/com/android/server/backup/SystemBackupAgent.java
index de4979a..5b9469b 100644
--- a/services/core/java/com/android/server/backup/SystemBackupAgent.java
+++ b/services/core/java/com/android/server/backup/SystemBackupAgent.java
@@ -20,7 +20,8 @@
import android.app.backup.BackupAgentHelper;
import android.app.backup.BackupAnnotations.BackupDestination;
import android.app.backup.BackupDataInput;
-import android.app.backup.BackupHelper;
+import android.app.backup.BackupHelperWithLogger;
+import android.app.backup.BackupRestoreEventLogger;
import android.app.backup.FullBackup;
import android.app.backup.FullBackupDataOutput;
import android.app.backup.WallpaperBackupHelper;
@@ -33,9 +34,10 @@
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Slog;
-
import com.google.android.collect.Sets;
+import com.android.server.backup.Flags;
+
import java.io.File;
import java.io.IOException;
import java.util.Set;
@@ -107,10 +109,12 @@
private int mUserId = UserHandle.USER_SYSTEM;
private boolean mIsProfileUser = false;
+ private BackupRestoreEventLogger mLogger;
@Override
public void onCreate(UserHandle user, @BackupDestination int backupDestination) {
super.onCreate(user, backupDestination);
+ mLogger = this.getBackupRestoreEventLogger();
mUserId = user.getIdentifier();
if (mUserId != UserHandle.USER_SYSTEM) {
@@ -209,9 +213,12 @@
}
}
- private void addHelperIfEligibleForUser(String keyPrefix, BackupHelper helper) {
+ private void addHelperIfEligibleForUser(String keyPrefix, BackupHelperWithLogger helper) {
if (isHelperEligibleForUser(keyPrefix)) {
addHelper(keyPrefix, helper);
+ if (Flags.enableMetricsSystemBackupAgents()) {
+ helper.setLogger(mLogger);
+ }
}
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/backup/SystemBackupAgentTest.java b/services/tests/mockingservicestests/src/com/android/server/backup/SystemBackupAgentTest.java
index 4095be7..18dc114 100644
--- a/services/tests/mockingservicestests/src/com/android/server/backup/SystemBackupAgentTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/backup/SystemBackupAgentTest.java
@@ -20,11 +20,13 @@
import android.annotation.NonNull;
import android.app.backup.BackupHelper;
+import android.app.backup.BackupHelperWithLogger;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.platform.test.annotations.Presubmit;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.util.ArraySet;
import static org.mockito.Mockito.when;
@@ -32,7 +34,10 @@
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
+import com.android.server.backup.Flags;
+
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -55,6 +60,9 @@
@Mock
private PackageManager mPackageManagerMock;
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
@@ -71,7 +79,7 @@
mSystemBackupAgent.onCreate(userHandle, /* backupDestination= */ 0);
- assertThat(mSystemBackupAgent.mAddedHelpers)
+ assertThat(mSystemBackupAgent.mAddedHelpersKey)
.containsExactly(
"account_sync_settings",
"preferred_activities",
@@ -96,7 +104,7 @@
mSystemBackupAgent.onCreate(userHandle, /* backupDestination= */ 0);
- assertThat(mSystemBackupAgent.mAddedHelpers)
+ assertThat(mSystemBackupAgent.mAddedHelpersKey)
.containsExactly(
"account_sync_settings",
"preferred_activities",
@@ -118,7 +126,7 @@
mSystemBackupAgent.onCreate(userHandle, /* backupDestination= */ 0);
- assertThat(mSystemBackupAgent.mAddedHelpers)
+ assertThat(mSystemBackupAgent.mAddedHelpersKey)
.containsExactly(
"account_sync_settings",
"notifications",
@@ -134,7 +142,7 @@
mSystemBackupAgent.onCreate(userHandle, /* backupDestination= */ 0);
- assertThat(mSystemBackupAgent.mAddedHelpers)
+ assertThat(mSystemBackupAgent.mAddedHelpersKey)
.containsExactly(
"account_sync_settings",
"preferred_activities",
@@ -147,12 +155,42 @@
"companion");
}
+ @Test
+ public void onAddHelperIfEligibleForUser_flagIsOff_helpersHaveNoLogger() {
+ UserHandle userHandle = new UserHandle(UserHandle.USER_SYSTEM);
+ when(mUserManagerMock.isProfile()).thenReturn(false);
+ mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_METRICS_SYSTEM_BACKUP_AGENTS);
+
+ mSystemBackupAgent.onCreate(userHandle, /* backupDestination= */ 0);
+
+ for (BackupHelperWithLogger helper:mSystemBackupAgent.mAddedHelpers){
+ assertThat(helper.isLoggerSet()).isFalse();
+ }
+ }
+
+ @Test
+ public void onAddHelperIfEligibleForUser_flagIsOn_helpersHaveLogger() {
+ UserHandle userHandle = new UserHandle(UserHandle.USER_SYSTEM);
+ when(mUserManagerMock.isProfile()).thenReturn(false);
+ mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_METRICS_SYSTEM_BACKUP_AGENTS);
+
+ mSystemBackupAgent.onCreate(userHandle, /* backupDestination= */ 0);
+
+ for (BackupHelperWithLogger helper:mSystemBackupAgent.mAddedHelpers){
+ assertThat(helper.isLoggerSet()).isTrue();
+ }
+ }
+
private class TestableSystemBackupAgent extends SystemBackupAgent {
- final Set<String> mAddedHelpers = new ArraySet<>();
+ final Set<String> mAddedHelpersKey = new ArraySet<>();
+ final Set<BackupHelperWithLogger> mAddedHelpers = new ArraySet<>();
@Override
public void addHelper(String keyPrefix, BackupHelper helper) {
- mAddedHelpers.add(keyPrefix);
+ mAddedHelpersKey.add(keyPrefix);
+ if (helper instanceof BackupHelperWithLogger) {
+ mAddedHelpers.add((BackupHelperWithLogger) helper);
+ }
}
@Override