Loading core/java/android/app/IBackupAgent.aidl +13 −0 Original line number Diff line number Diff line Loading @@ -16,10 +16,13 @@ package android.app; import android.app.backup.BackupRestoreEventLogger; import android.app.backup.IBackupCallback; import android.app.backup.IBackupManager; import android.os.ParcelFileDescriptor; import com.android.internal.infra.AndroidFuture; /** * Interface presented by applications being asked to participate in the * backup & restore mechanism. End user code will not typically implement Loading Loading @@ -193,4 +196,14 @@ oneway interface IBackupAgent { * @param message The message to be passed to the agent's application in an exception. */ void fail(String message); /** * Provides the logging results that were accumulated in the BackupAgent during a backup or * restore operation. This method should be called after the agent completes its backup or * restore. * * @param resultsFuture a future that is completed with the logging results. */ void getLoggerResults( in AndroidFuture<List<BackupRestoreEventLogger.DataTypeResult>> resultsFuture); } core/java/android/app/backup/BackupAgent.java +29 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ import android.util.ArraySet; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.infra.AndroidFuture; import libcore.io.IoUtils; Loading Loading @@ -202,6 +203,7 @@ public abstract class BackupAgent extends ContextWrapper { Handler mHandler = null; @Nullable private volatile BackupRestoreEventLogger mLogger = null; @Nullable private UserHandle mUser; // This field is written from the main thread (in onCreate), and read in a Binder thread (in // onFullBackup that is called from system_server via Binder). Loading Loading @@ -234,6 +236,20 @@ public abstract class BackupAgent extends ContextWrapper { } catch (InterruptedException e) { /* ignored */ } } /** * Get a logger to record app-specific backup and restore events that are happening during a * backup or restore operation. * * <p>The logger instance had been created by the system with the correct {@link * BackupRestoreEventLogger.OperationType} that corresponds to the operation the {@code * BackupAgent} is currently handling. * * @hide */ @Nullable public BackupRestoreEventLogger getBackupRestoreEventLogger() { return mLogger; } public BackupAgent() { super(null); Loading Loading @@ -264,6 +280,9 @@ public abstract class BackupAgent extends ContextWrapper { * @hide */ public void onCreate(UserHandle user, @OperationType int operationType) { // TODO: Instantiate with the correct type using a parameter. mLogger = new BackupRestoreEventLogger(BackupRestoreEventLogger.OperationType.BACKUP); onCreate(); mUser = user; Loading Loading @@ -1305,6 +1324,16 @@ public abstract class BackupAgent extends ContextWrapper { } } } @Override public void getLoggerResults( AndroidFuture<List<BackupRestoreEventLogger.DataTypeResult>> in) { if (mLogger != null) { in.complete(mLogger.getLoggingResults()); } else { in.complete(Collections.emptyList()); } } } static class FailRunnable implements Runnable { Loading core/java/android/app/backup/BackupRestoreEventLogger.aidl 0 → 100644 +19 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 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; parcelable BackupRestoreEventLogger.DataTypeResult; No newline at end of file core/java/android/app/backup/BackupRestoreEventLogger.java +57 −1 Original line number Diff line number Diff line Loading @@ -19,6 +19,10 @@ package android.app.backup; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; import android.util.ArrayMap; import android.util.Slog; import java.lang.annotation.Retention; Loading Loading @@ -312,7 +316,7 @@ public class BackupRestoreEventLogger { /** * Encapsulate logging results for a single data type. */ public static class DataTypeResult { public static class DataTypeResult implements Parcelable { @BackupRestoreDataType private final String mDataType; private int mSuccessCount; Loading Loading @@ -362,5 +366,57 @@ public class BackupRestoreEventLogger { public byte[] getMetadataHash() { return mMetadataHash; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(mDataType); dest.writeInt(mSuccessCount); dest.writeInt(mFailCount); Bundle errorsBundle = new Bundle(); for (Map.Entry<String, Integer> e : mErrors.entrySet()) { errorsBundle.putInt(e.getKey(), e.getValue()); } dest.writeBundle(errorsBundle); dest.writeByteArray(mMetadataHash); } public static final Parcelable.Creator<DataTypeResult> CREATOR = new Parcelable.Creator<>() { public DataTypeResult createFromParcel(Parcel in) { String dataType = in.readString(); int successCount = in.readInt(); int failCount = in.readInt(); Map<String, Integer> errors = new ArrayMap<>(); Bundle errorsBundle = in.readBundle(getClass().getClassLoader()); for (String key : errorsBundle.keySet()) { errors.put(key, errorsBundle.getInt(key)); } byte[] metadataHash = in.createByteArray(); DataTypeResult result = new DataTypeResult(dataType); result.mSuccessCount = successCount; result.mFailCount = failCount; result.mErrors.putAll(errors); result.mMetadataHash = metadataHash; return result; } public DataTypeResult[] newArray(int size) { return new DataTypeResult[size]; } }; } } core/tests/coretests/src/android/app/backup/BackupAgentTest.java +42 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ import java.util.Set; public class BackupAgentTest { // An arbitrary user. private static final UserHandle USER_HANDLE = new UserHandle(15); private static final String DATA_TYPE_BACKED_UP = "test data type"; @Mock FullBackup.BackupScheme mBackupScheme; Loading Loading @@ -73,6 +74,42 @@ public class BackupAgentTest { assertThat(rules).isEqualTo(expectedRules); } @Test public void getBackupRestoreEventLogger_beforeOnCreate_isNull() { BackupAgent agent = new TestFullBackupAgent(); assertThat(agent.getBackupRestoreEventLogger()).isNull(); } @Test public void getBackupRestoreEventLogger_afterOnCreateForBackup_initializedForBackup() { BackupAgent agent = new TestFullBackupAgent(); agent.onCreate(USER_HANDLE, OperationType.BACKUP); // TODO: pass in new operation type assertThat(agent.getBackupRestoreEventLogger().getOperationType()).isEqualTo(1); } @Test public void getBackupRestoreEventLogger_afterOnCreateForRestore_initializedForRestore() { BackupAgent agent = new TestFullBackupAgent(); agent.onCreate(USER_HANDLE, OperationType.BACKUP); // TODO: pass in new operation type assertThat(agent.getBackupRestoreEventLogger().getOperationType()).isEqualTo(1); } @Test public void getBackupRestoreEventLogger_afterBackup_containsLogsLoggedByAgent() throws Exception { BackupAgent agent = new TestFullBackupAgent(); agent.onCreate(USER_HANDLE, OperationType.BACKUP); // TODO: pass in new operation type // TestFullBackupAgent logs DATA_TYPE_BACKED_UP when onFullBackup is called. agent.onFullBackup(new FullBackupDataOutput(/* quota = */ 0)); assertThat(agent.getBackupRestoreEventLogger().getLoggingResults().get(0).getDataType()) .isEqualTo(DATA_TYPE_BACKED_UP); } private BackupAgent getAgentForOperationType(@OperationType int operationType) { BackupAgent agent = new TestFullBackupAgent(); agent.onCreate(USER_HANDLE, operationType); Loading @@ -87,6 +124,11 @@ public class BackupAgentTest { // Left empty as this is a full backup agent. } @Override public void onFullBackup(FullBackupDataOutput data) { getBackupRestoreEventLogger().logItemsBackedUp(DATA_TYPE_BACKED_UP, 1); } @Override public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState) throws IOException { Loading Loading
core/java/android/app/IBackupAgent.aidl +13 −0 Original line number Diff line number Diff line Loading @@ -16,10 +16,13 @@ package android.app; import android.app.backup.BackupRestoreEventLogger; import android.app.backup.IBackupCallback; import android.app.backup.IBackupManager; import android.os.ParcelFileDescriptor; import com.android.internal.infra.AndroidFuture; /** * Interface presented by applications being asked to participate in the * backup & restore mechanism. End user code will not typically implement Loading Loading @@ -193,4 +196,14 @@ oneway interface IBackupAgent { * @param message The message to be passed to the agent's application in an exception. */ void fail(String message); /** * Provides the logging results that were accumulated in the BackupAgent during a backup or * restore operation. This method should be called after the agent completes its backup or * restore. * * @param resultsFuture a future that is completed with the logging results. */ void getLoggerResults( in AndroidFuture<List<BackupRestoreEventLogger.DataTypeResult>> resultsFuture); }
core/java/android/app/backup/BackupAgent.java +29 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ import android.util.ArraySet; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.infra.AndroidFuture; import libcore.io.IoUtils; Loading Loading @@ -202,6 +203,7 @@ public abstract class BackupAgent extends ContextWrapper { Handler mHandler = null; @Nullable private volatile BackupRestoreEventLogger mLogger = null; @Nullable private UserHandle mUser; // This field is written from the main thread (in onCreate), and read in a Binder thread (in // onFullBackup that is called from system_server via Binder). Loading Loading @@ -234,6 +236,20 @@ public abstract class BackupAgent extends ContextWrapper { } catch (InterruptedException e) { /* ignored */ } } /** * Get a logger to record app-specific backup and restore events that are happening during a * backup or restore operation. * * <p>The logger instance had been created by the system with the correct {@link * BackupRestoreEventLogger.OperationType} that corresponds to the operation the {@code * BackupAgent} is currently handling. * * @hide */ @Nullable public BackupRestoreEventLogger getBackupRestoreEventLogger() { return mLogger; } public BackupAgent() { super(null); Loading Loading @@ -264,6 +280,9 @@ public abstract class BackupAgent extends ContextWrapper { * @hide */ public void onCreate(UserHandle user, @OperationType int operationType) { // TODO: Instantiate with the correct type using a parameter. mLogger = new BackupRestoreEventLogger(BackupRestoreEventLogger.OperationType.BACKUP); onCreate(); mUser = user; Loading Loading @@ -1305,6 +1324,16 @@ public abstract class BackupAgent extends ContextWrapper { } } } @Override public void getLoggerResults( AndroidFuture<List<BackupRestoreEventLogger.DataTypeResult>> in) { if (mLogger != null) { in.complete(mLogger.getLoggingResults()); } else { in.complete(Collections.emptyList()); } } } static class FailRunnable implements Runnable { Loading
core/java/android/app/backup/BackupRestoreEventLogger.aidl 0 → 100644 +19 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 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; parcelable BackupRestoreEventLogger.DataTypeResult; No newline at end of file
core/java/android/app/backup/BackupRestoreEventLogger.java +57 −1 Original line number Diff line number Diff line Loading @@ -19,6 +19,10 @@ package android.app.backup; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; import android.util.ArrayMap; import android.util.Slog; import java.lang.annotation.Retention; Loading Loading @@ -312,7 +316,7 @@ public class BackupRestoreEventLogger { /** * Encapsulate logging results for a single data type. */ public static class DataTypeResult { public static class DataTypeResult implements Parcelable { @BackupRestoreDataType private final String mDataType; private int mSuccessCount; Loading Loading @@ -362,5 +366,57 @@ public class BackupRestoreEventLogger { public byte[] getMetadataHash() { return mMetadataHash; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(mDataType); dest.writeInt(mSuccessCount); dest.writeInt(mFailCount); Bundle errorsBundle = new Bundle(); for (Map.Entry<String, Integer> e : mErrors.entrySet()) { errorsBundle.putInt(e.getKey(), e.getValue()); } dest.writeBundle(errorsBundle); dest.writeByteArray(mMetadataHash); } public static final Parcelable.Creator<DataTypeResult> CREATOR = new Parcelable.Creator<>() { public DataTypeResult createFromParcel(Parcel in) { String dataType = in.readString(); int successCount = in.readInt(); int failCount = in.readInt(); Map<String, Integer> errors = new ArrayMap<>(); Bundle errorsBundle = in.readBundle(getClass().getClassLoader()); for (String key : errorsBundle.keySet()) { errors.put(key, errorsBundle.getInt(key)); } byte[] metadataHash = in.createByteArray(); DataTypeResult result = new DataTypeResult(dataType); result.mSuccessCount = successCount; result.mFailCount = failCount; result.mErrors.putAll(errors); result.mMetadataHash = metadataHash; return result; } public DataTypeResult[] newArray(int size) { return new DataTypeResult[size]; } }; } }
core/tests/coretests/src/android/app/backup/BackupAgentTest.java +42 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ import java.util.Set; public class BackupAgentTest { // An arbitrary user. private static final UserHandle USER_HANDLE = new UserHandle(15); private static final String DATA_TYPE_BACKED_UP = "test data type"; @Mock FullBackup.BackupScheme mBackupScheme; Loading Loading @@ -73,6 +74,42 @@ public class BackupAgentTest { assertThat(rules).isEqualTo(expectedRules); } @Test public void getBackupRestoreEventLogger_beforeOnCreate_isNull() { BackupAgent agent = new TestFullBackupAgent(); assertThat(agent.getBackupRestoreEventLogger()).isNull(); } @Test public void getBackupRestoreEventLogger_afterOnCreateForBackup_initializedForBackup() { BackupAgent agent = new TestFullBackupAgent(); agent.onCreate(USER_HANDLE, OperationType.BACKUP); // TODO: pass in new operation type assertThat(agent.getBackupRestoreEventLogger().getOperationType()).isEqualTo(1); } @Test public void getBackupRestoreEventLogger_afterOnCreateForRestore_initializedForRestore() { BackupAgent agent = new TestFullBackupAgent(); agent.onCreate(USER_HANDLE, OperationType.BACKUP); // TODO: pass in new operation type assertThat(agent.getBackupRestoreEventLogger().getOperationType()).isEqualTo(1); } @Test public void getBackupRestoreEventLogger_afterBackup_containsLogsLoggedByAgent() throws Exception { BackupAgent agent = new TestFullBackupAgent(); agent.onCreate(USER_HANDLE, OperationType.BACKUP); // TODO: pass in new operation type // TestFullBackupAgent logs DATA_TYPE_BACKED_UP when onFullBackup is called. agent.onFullBackup(new FullBackupDataOutput(/* quota = */ 0)); assertThat(agent.getBackupRestoreEventLogger().getLoggingResults().get(0).getDataType()) .isEqualTo(DATA_TYPE_BACKED_UP); } private BackupAgent getAgentForOperationType(@OperationType int operationType) { BackupAgent agent = new TestFullBackupAgent(); agent.onCreate(USER_HANDLE, operationType); Loading @@ -87,6 +124,11 @@ public class BackupAgentTest { // Left empty as this is a full backup agent. } @Override public void onFullBackup(FullBackupDataOutput data) { getBackupRestoreEventLogger().logItemsBackedUp(DATA_TYPE_BACKED_UP, 1); } @Override public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState) throws IOException { Loading