1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.backup.cts; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import android.Manifest; 22 import android.app.UiAutomation; 23 import android.app.backup.BackupManager; 24 import android.app.backup.BackupManagerMonitor; 25 import android.app.backup.BackupObserver; 26 import android.app.backup.BackupRestoreEventLogger.DataTypeResult; 27 import android.app.backup.RestoreObserver; 28 import android.app.backup.RestoreSession; 29 import android.content.Context; 30 import android.os.Bundle; 31 import android.platform.test.annotations.AppModeFull; 32 33 import java.util.List; 34 import java.util.concurrent.CountDownLatch; 35 import java.util.concurrent.TimeUnit; 36 37 @AppModeFull 38 public class BackupRestoreEventLoggerTest extends BaseBackupCtsTest { 39 private static final String BACKUP_APP_PACKAGE 40 = "android.cts.backup.backuprestoreeventloggerapp"; 41 private static final int OPERATION_TIMEOUT_SECONDS = 30; 42 private static final int BACKUP_APP_RESTART_SLEEP_MS = 3_000; 43 44 45 // Copied from LoggingFullBackupAgent.java 46 private static final String DATA_TYPE = "data_type"; 47 private static final String ERROR = "error"; 48 private static final String METADATA = "metadata"; 49 private static final int SUCCESS_COUNT = 1; 50 private static final int FAIL_COUNT = 2; 51 52 private final TestBackupManagerMonitor mBackupMonitor = new TestBackupManagerMonitor(); 53 private final TestBackupManagerMonitor mRestoreMonitor = new TestBackupManagerMonitor(); 54 55 private UiAutomation mUiAutomation; 56 private BackupManager mBackupManager; 57 private BackupObserver mBackupObserver; 58 private RestoreObserver mRestoreObserver; 59 private CountDownLatch mOperationLatch; 60 private RestoreSession mRestoreSession; 61 62 @Override setUp()63 public void setUp() throws Exception { 64 super.setUp(); 65 66 Context context = getInstrumentation().getTargetContext(); 67 68 mUiAutomation = getInstrumentation().getUiAutomation(); 69 mBackupManager = new BackupManager(context); 70 mBackupObserver = new TestBackupObserver(); 71 mRestoreObserver = new TestRestoreObserver(); 72 73 mUiAutomation.adoptShellPermissionIdentity(Manifest.permission.BACKUP); 74 } 75 76 @Override tearDown()77 public void tearDown() throws Exception { 78 79 if (mRestoreSession != null){ 80 mRestoreSession.endRestoreSession(); 81 } 82 mUiAutomation.dropShellPermissionIdentity(); 83 84 super.tearDown(); 85 } 86 testBackupRestoreRoundTrip_logsSentToMonitor()87 public void testBackupRestoreRoundTrip_logsSentToMonitor() throws Exception { 88 if (!isBackupSupported()) { 89 return; 90 } 91 92 // Ensure the app is not in stopped state. 93 createTestFileOfSize(BACKUP_APP_PACKAGE, /* size */ 1); 94 95 // Run a backup. 96 mOperationLatch = new CountDownLatch(/* count */ 1); 97 mBackupManager.requestBackup(new String[] { BACKUP_APP_PACKAGE }, 98 /* observer */ mBackupObserver, mBackupMonitor, /* flags */ 0); 99 boolean backupFinished = mOperationLatch.await(OPERATION_TIMEOUT_SECONDS, 100 TimeUnit.SECONDS); 101 102 // Sleep to allow the app to be killed, so that this doesn't disrupt the restore operation 103 Thread.sleep(BACKUP_APP_RESTART_SLEEP_MS); 104 105 // Run a restore. 106 mOperationLatch = new CountDownLatch(/* count */ 1); 107 mRestoreSession = mBackupManager.beginRestoreSession(); 108 mRestoreSession.restorePackage(BACKUP_APP_PACKAGE, mRestoreObserver, mRestoreMonitor); 109 boolean restoreFinished = mOperationLatch.await(OPERATION_TIMEOUT_SECONDS, 110 TimeUnit.SECONDS); 111 112 113 assertThat(backupFinished).isTrue(); 114 assertThat(restoreFinished).isTrue(); 115 assertLoggingResultsAreCorrect(mBackupMonitor); 116 assertLoggingResultsAreCorrect(mRestoreMonitor); 117 } 118 119 /** 120 * Assert the logging results are consistent with what is logged in LoggingFullBackupAgent.java. 121 */ assertLoggingResultsAreCorrect(TestBackupManagerMonitor monitor)122 private void assertLoggingResultsAreCorrect(TestBackupManagerMonitor monitor) { 123 assertThat(monitor.mAgentBundle).isNotNull(); 124 List<DataTypeResult> dataTypeList = monitor.mAgentBundle.getParcelableArrayList( 125 BackupManagerMonitor.EXTRA_LOG_AGENT_LOGGING_RESULTS, 126 DataTypeResult.class); 127 assertThat(dataTypeList.size()).isEqualTo(/* expected */ 1); 128 DataTypeResult dataTypeResult = dataTypeList.get(/* index */ 0); 129 assertThat(dataTypeResult.getDataType()).isEqualTo(DATA_TYPE); 130 assertThat(dataTypeResult.getSuccessCount()).isEqualTo(SUCCESS_COUNT); 131 assertThat(dataTypeResult.getErrors().get(ERROR)).isEqualTo(FAIL_COUNT); 132 } 133 134 private static class TestBackupManagerMonitor extends BackupManagerMonitor { 135 private Bundle mAgentBundle = null; 136 137 @Override onEvent(Bundle event)138 public void onEvent(Bundle event) { 139 if (event.getInt(BackupManagerMonitor.EXTRA_LOG_EVENT_ID) 140 == BackupManagerMonitor.LOG_EVENT_ID_AGENT_LOGGING_RESULTS) { 141 mAgentBundle = event; 142 } 143 } 144 } 145 146 private class TestBackupObserver extends BackupObserver { 147 @Override backupFinished(int status)148 public void backupFinished(int status) { 149 assertThat(status).isEqualTo(/* expected */ 0); 150 mOperationLatch.countDown(); 151 } 152 } 153 154 private class TestRestoreObserver extends RestoreObserver { 155 156 @Override restoreFinished(int error)157 public void restoreFinished(int error) { 158 assertThat(error).isEqualTo(/* expected */ 0); 159 mOperationLatch.countDown(); 160 } 161 } 162 } 163