Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6dfaaf19 authored by Ruslan Tkhakokhov's avatar Ruslan Tkhakokhov Committed by Android (Google) Code Review
Browse files

Merge "Make BackupRestoreEventLogger System API"

parents ccd8a70a ecc97c0b
Loading
Loading
Loading
Loading
+28 −0
Original line number Diff line number Diff line
@@ -1474,6 +1474,7 @@ package android.app.backup {
    method @RequiresPermission(android.Manifest.permission.BACKUP) public void cancelBackups();
    method @RequiresPermission(android.Manifest.permission.BACKUP) public void excludeKeysFromRestore(@NonNull String, @NonNull java.util.List<java.lang.String>);
    method @RequiresPermission(android.Manifest.permission.BACKUP) public long getAvailableRestoreToken(String);
    method @NonNull public android.app.backup.BackupRestoreEventLogger getBackupRestoreEventLogger(@NonNull android.app.backup.BackupAgent);
    method @RequiresPermission(android.Manifest.permission.BACKUP) public android.content.Intent getConfigurationIntent(String);
    method @RequiresPermission(android.Manifest.permission.BACKUP) public String getCurrentTransport();
    method @Nullable @RequiresPermission(android.Manifest.permission.BACKUP) public android.content.ComponentName getCurrentTransportComponent();
@@ -1592,6 +1593,33 @@ package android.app.backup {
    field public final long bytesTransferred;
  }
  public class BackupRestoreEventLogger {
    method public void logBackupMetaData(@android.app.backup.BackupRestoreEventLogger.BackupRestoreDataType @NonNull String, @NonNull String);
    method public void logItemsBackedUp(@android.app.backup.BackupRestoreEventLogger.BackupRestoreDataType @NonNull String, int);
    method public void logItemsBackupFailed(@android.app.backup.BackupRestoreEventLogger.BackupRestoreDataType @NonNull String, int, @android.app.backup.BackupRestoreEventLogger.BackupRestoreError @Nullable String);
    method public void logItemsRestoreFailed(@android.app.backup.BackupRestoreEventLogger.BackupRestoreDataType @NonNull String, int, @android.app.backup.BackupRestoreEventLogger.BackupRestoreError @Nullable String);
    method public void logItemsRestored(@android.app.backup.BackupRestoreEventLogger.BackupRestoreDataType @NonNull String, int);
    method public void logRestoreMetadata(@android.app.backup.BackupRestoreEventLogger.BackupRestoreDataType @NonNull String, @NonNull String);
  }
  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface BackupRestoreEventLogger.BackupRestoreDataType {
  }
  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface BackupRestoreEventLogger.BackupRestoreError {
  }
  public static final class BackupRestoreEventLogger.DataTypeResult implements android.os.Parcelable {
    ctor public BackupRestoreEventLogger.DataTypeResult(@NonNull String);
    method public int describeContents();
    method @android.app.backup.BackupRestoreEventLogger.BackupRestoreDataType @NonNull public String getDataType();
    method @NonNull public java.util.Map<java.lang.String,java.lang.Integer> getErrors();
    method public int getFailCount();
    method @Nullable public byte[] getMetadataHash();
    method public int getSuccessCount();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.app.backup.BackupRestoreEventLogger.DataTypeResult> CREATOR;
  }
  public class BackupTransport {
    ctor public BackupTransport();
    method public int abortFullRestore();
+23 −0
Original line number Diff line number Diff line
@@ -1018,6 +1018,29 @@ public class BackupManager {
        }
    }

    /**
     * Get an instance of {@link BackupRestoreEventLogger} to report B&R related events during an
     * ongoing backup or restore operation.
     *
     * @param backupAgent the agent currently running a B&R operation.
     *
     * @return an instance of {@code BackupRestoreEventLogger} or {@code null} if the agent has not
     *         finished initialisation, i.e. {@link BackupAgent#onCreate()} has not been called yet.
     * @throws IllegalStateException if called before the agent has finished initialisation.
     *
     * @hide
     */
    @NonNull
    @SystemApi
    public BackupRestoreEventLogger getBackupRestoreEventLogger(@NonNull BackupAgent backupAgent) {
        BackupRestoreEventLogger logger = backupAgent.getBackupRestoreEventLogger();
        if (logger == null) {
            throw new IllegalStateException("Attempting to get logger on an uninitialised "
                    + "BackupAgent");
        }
        return backupAgent.getBackupRestoreEventLogger();
    }

    /*
     * We wrap incoming binder calls with a private class implementation that
     * redirects them into main-thread actions.  This serializes the backup
+8 −4
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.app.backup;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
@@ -35,7 +36,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;

// TODO(b/244436184): Make this @SystemApi
/**
 * Class to log B&R stats for each data type that is backed up and restored by the calling app.
 *
@@ -46,12 +46,15 @@ import java.util.Map;
 *
 * @hide
 */
@SystemApi
public class BackupRestoreEventLogger {
    private static final String TAG = "BackupRestoreEventLogger";

    /**
     * Max number of unique data types for which an instance of this logger can store info. Attempts
     * to use more distinct data type values will be rejected.
     *
     * @hide
     */
    public static final int DATA_TYPES_ALLOWED = 15;

@@ -301,7 +304,7 @@ public class BackupRestoreEventLogger {
    /**
     * Encapsulate logging results for a single data type.
     */
    public static class DataTypeResult implements Parcelable {
    public static final class DataTypeResult implements Parcelable {
        @BackupRestoreDataType
        private final String mDataType;
        private int mSuccessCount;
@@ -309,7 +312,7 @@ public class BackupRestoreEventLogger {
        private final Map<String, Integer> mErrors = new HashMap<>();
        private byte[] mMetadataHash;

        public DataTypeResult(String dataType) {
        public DataTypeResult(@NonNull String dataType) {
            mDataType = dataType;
        }

@@ -358,7 +361,7 @@ public class BackupRestoreEventLogger {
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
        public void writeToParcel(@NonNull Parcel dest, int flags) {
            dest.writeString(mDataType);

            dest.writeInt(mSuccessCount);
@@ -374,6 +377,7 @@ public class BackupRestoreEventLogger {
            dest.writeByteArray(mMetadataHash);
        }

        @NonNull
        public static final Parcelable.Creator<DataTypeResult> CREATOR =
                new Parcelable.Creator<>() {
                    public DataTypeResult createFromParcel(Parcel in) {
+102 −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;

import static com.google.common.truth.Truth.assertThat;

import static org.junit.Assert.assertThrows;

import android.app.backup.BackupAnnotations.BackupDestination;
import android.app.backup.BackupAnnotations.OperationType;
import android.content.Context;
import android.os.ParcelFileDescriptor;
import android.os.UserHandle;
import android.platform.test.annotations.Presubmit;

import androidx.test.runner.AndroidJUnit4;

import org.junit.Before;
import org.junit.Test;
import org.junit.function.ThrowingRunnable;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.io.IOException;

@Presubmit
@RunWith(AndroidJUnit4.class)
public class BackupManagerTest {
    private BackupManager mBackupManager;

    @Mock
    Context mContext;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);

        mBackupManager = new BackupManager(mContext);
    }

    @Test
    public void testGetBackupRestoreEventLogger_returnsBackupLoggerForBackup() {
        BackupAgent agent = getTestAgent();
        agent.onCreate(UserHandle.SYSTEM, BackupDestination.CLOUD,
                OperationType.BACKUP);

        BackupRestoreEventLogger logger = mBackupManager.getBackupRestoreEventLogger(agent);

        assertThat(logger.getOperationType()).isEqualTo(OperationType.BACKUP);
    }

    @Test
    public void testGetBackupRestoreEventLogger_returnsRestoreLoggerForRestore() {
        BackupAgent agent = getTestAgent();
        agent.onCreate(UserHandle.SYSTEM, BackupDestination.CLOUD,
                OperationType.RESTORE);

        BackupRestoreEventLogger logger = mBackupManager.getBackupRestoreEventLogger(agent);

        assertThat(logger.getOperationType()).isEqualTo(OperationType.RESTORE);
    }

    @Test
    public void testGetBackupRestoreEventLogger_uninitialisedAgent_throwsException() {
        BackupAgent agent = getTestAgent();

        assertThrows(IllegalStateException.class,
                () -> mBackupManager.getBackupRestoreEventLogger(agent));
    }

    private static BackupAgent getTestAgent() {
        return new BackupAgent() {
            @Override
            public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
                    ParcelFileDescriptor newState) throws IOException {

            }

            @Override
            public void onRestore(BackupDataInput data, int appVersionCode,
                    ParcelFileDescriptor newState) throws IOException {

            }
        };
    }

}