1/* 2 * Copyright (C) 2017 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 17package com.android.server.backup.utils; 18 19import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_EVENT_ID; 20import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_APK_NOT_INSTALLED; 21import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_CANNOT_RESTORE_WITHOUT_APK; 22import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_FULL_RESTORE_ALLOW_BACKUP_FALSE; 23import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_FULL_RESTORE_SIGNATURE_MISMATCH; 24import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_RESTORE_ANY_VERSION; 25import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_SYSTEM_APP_NO_AGENT; 26import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_VERSIONS_MATCH; 27import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_VERSION_OF_BACKUP_OLDER; 28 29import static com.google.common.truth.Truth.assertThat; 30 31import static org.mockito.Mockito.doReturn; 32import static org.mockito.Mockito.mock; 33import static org.mockito.Mockito.when; 34import static org.mockito.Mockito.verify; 35import static org.mockito.Mockito.verifyNoMoreInteractions; 36import static org.mockito.Mockito.verifyZeroInteractions; 37import static org.mockito.internal.verification.VerificationModeFactory.times; 38 39import android.app.backup.IBackupManagerMonitor; 40import android.content.Context; 41import android.content.pm.ApplicationInfo; 42import android.content.pm.PackageInfo; 43import android.content.pm.PackageManagerInternal; 44import android.content.pm.PackageParser; 45import android.content.pm.Signature; 46import android.content.pm.SigningInfo; 47import android.os.Bundle; 48import android.os.Process; 49import android.platform.test.annotations.Presubmit; 50import android.support.test.InstrumentationRegistry; 51import android.support.test.filters.SmallTest; 52import android.support.test.runner.AndroidJUnit4; 53 54import com.android.frameworks.servicestests.R; 55import com.android.server.backup.FileMetadata; 56import com.android.server.backup.BackupManagerService; 57import com.android.server.backup.restore.PerformAdbRestoreTask; 58import com.android.server.backup.restore.RestorePolicy; 59import com.android.server.backup.testutils.PackageManagerStub; 60 61import com.google.common.hash.Hashing; 62 63import org.junit.Before; 64import org.junit.Test; 65import org.junit.runner.RunWith; 66import org.mockito.ArgumentCaptor; 67import org.mockito.Mock; 68import org.mockito.MockitoAnnotations; 69 70import java.io.InputStream; 71import java.util.Arrays; 72import java.util.List; 73 74@SmallTest 75@Presubmit 76@RunWith(AndroidJUnit4.class) 77public class TarBackupReaderTest { 78 private static final String TELEPHONY_PACKAGE_NAME = "com.android.providers.telephony"; 79 private static final String TELEPHONY_PACKAGE_SIGNATURE_SHA256 = 80 "301aa3cb081134501c45f1422abc66c24224fd5ded5fdc8f17e697176fd866aa"; 81 private static final int TELEPHONY_PACKAGE_VERSION = 25; 82 private static final String TEST_PACKAGE_NAME = "com.android.backup.testing"; 83 private static final Signature FAKE_SIGNATURE_1 = new Signature("1234"); 84 private static final Signature FAKE_SIGNATURE_2 = new Signature("5678"); 85 86 @Mock private BytesReadListener mBytesReadListenerMock; 87 @Mock private IBackupManagerMonitor mBackupManagerMonitorMock; 88 @Mock private PackageManagerInternal mMockPackageManagerInternal; 89 90 private final PackageManagerStub mPackageManagerStub = new PackageManagerStub(); 91 private Context mContext; 92 93 @Before 94 public void setUp() throws Exception { 95 MockitoAnnotations.initMocks(this); 96 97 mContext = InstrumentationRegistry.getContext(); 98 } 99 100 @Test 101 public void readTarHeaders_backupEncrypted_correctlyParsesFileMetadata() throws Exception { 102 InputStream inputStream = mContext.getResources().openRawResource( 103 R.raw.backup_telephony_with_password); 104 InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream( 105 inputStream, "123"); 106 TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream, 107 mBytesReadListenerMock, mBackupManagerMonitorMock); 108 FileMetadata fileMetadata = tarBackupReader.readTarHeaders(); 109 110 assertThat(fileMetadata.packageName).isEqualTo(TELEPHONY_PACKAGE_NAME); 111 assertThat(fileMetadata.mode).isEqualTo(0600); 112 assertThat(fileMetadata.size).isEqualTo(2438); 113 assertThat(fileMetadata.domain).isEqualTo(null); 114 assertThat(fileMetadata.path).isEqualTo("_manifest"); 115 } 116 117 @Test 118 public void readTarHeaders_backupNotEncrypted_correctlyParsesFileMetadata() throws Exception { 119 InputStream inputStream = mContext.getResources().openRawResource( 120 R.raw.backup_telephony_no_password); 121 InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream( 122 inputStream, null); 123 TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream, 124 mBytesReadListenerMock, mBackupManagerMonitorMock); 125 FileMetadata fileMetadata = tarBackupReader.readTarHeaders(); 126 127 assertThat(fileMetadata.packageName).isEqualTo(TELEPHONY_PACKAGE_NAME); 128 assertThat(fileMetadata.mode).isEqualTo(0600); 129 assertThat(fileMetadata.size).isEqualTo(2438); 130 assertThat(fileMetadata.domain).isEqualTo(null); 131 assertThat(fileMetadata.path).isEqualTo("_manifest"); 132 } 133 134 @Test 135 public void readTarHeaders_backupNotEncrypted_correctlyReadsPaxHeader() throws Exception { 136 // Files with long names (>100 chars) will force backup to add PAX header. 137 InputStream inputStream = mContext.getResources().openRawResource( 138 R.raw.backup_file_with_long_name); 139 InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream( 140 inputStream, null); 141 TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream, 142 mBytesReadListenerMock, mBackupManagerMonitorMock); 143 144 // Read manifest file. 145 FileMetadata fileMetadata = tarBackupReader.readTarHeaders(); 146 Signature[] signatures = tarBackupReader.readAppManifestAndReturnSignatures( 147 fileMetadata); 148 RestorePolicy restorePolicy = tarBackupReader.chooseRestorePolicy( 149 mPackageManagerStub, false /* allowApks */, fileMetadata, signatures, 150 mMockPackageManagerInternal); 151 152 assertThat(restorePolicy).isEqualTo(RestorePolicy.IGNORE); 153 assertThat(fileMetadata.packageName).isEqualTo(TEST_PACKAGE_NAME); 154 assertThat(fileMetadata.path).isEqualTo(BackupManagerService.BACKUP_MANIFEST_FILENAME); 155 156 tarBackupReader.skipTarPadding(fileMetadata.size); 157 158 // Read actual file (PAX header will only exist here). 159 fileMetadata = tarBackupReader.readTarHeaders(); 160 signatures = tarBackupReader.readAppManifestAndReturnSignatures( 161 fileMetadata); 162 restorePolicy = tarBackupReader.chooseRestorePolicy( 163 mPackageManagerStub, false /* allowApks */, fileMetadata, signatures, 164 mMockPackageManagerInternal); 165 166 assertThat(restorePolicy).isEqualTo(RestorePolicy.IGNORE); 167 assertThat(fileMetadata.packageName).isEqualTo(TEST_PACKAGE_NAME); 168 char[] expectedFileNameChars = new char[200]; 169 Arrays.fill(expectedFileNameChars, '1'); 170 String expectedFileName = new String(expectedFileNameChars); 171 assertThat(fileMetadata.path).isEqualTo(expectedFileName); 172 } 173 174 @Test 175 public void readAppManifest_backupEncrypted_correctlyParsesAppManifest() throws Exception { 176 InputStream inputStream = mContext.getResources().openRawResource( 177 R.raw.backup_telephony_with_password); 178 InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream( 179 inputStream, "123"); 180 TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream, 181 mBytesReadListenerMock, mBackupManagerMonitorMock); 182 FileMetadata fileMetadata = tarBackupReader.readTarHeaders(); 183 184 Signature[] signatures = tarBackupReader.readAppManifestAndReturnSignatures(fileMetadata); 185 186 assertThat(fileMetadata.version).isEqualTo(TELEPHONY_PACKAGE_VERSION); 187 assertThat(fileMetadata.hasApk).isFalse(); 188 assertThat(signatures).isNotNull(); 189 assertThat(signatures).hasLength(1); 190 191 String signatureSha256 = Hashing.sha256().hashBytes(signatures[0].toByteArray()).toString(); 192 assertThat(signatureSha256).isEqualTo(TELEPHONY_PACKAGE_SIGNATURE_SHA256); 193 } 194 195 @Test 196 public void readAppManifest_backupNotEncrypted_correctlyParsesAppManifest() throws Exception { 197 InputStream inputStream = mContext.getResources().openRawResource( 198 R.raw.backup_telephony_no_password); 199 InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream( 200 inputStream, null); 201 TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream, 202 mBytesReadListenerMock, mBackupManagerMonitorMock); 203 FileMetadata fileMetadata = tarBackupReader.readTarHeaders(); 204 205 Signature[] signatures = tarBackupReader.readAppManifestAndReturnSignatures(fileMetadata); 206 207 assertThat(fileMetadata.version).isEqualTo(TELEPHONY_PACKAGE_VERSION); 208 assertThat(fileMetadata.hasApk).isFalse(); 209 assertThat(signatures).isNotNull(); 210 assertThat(signatures).hasLength(1); 211 212 String signatureSha256 = Hashing.sha256().hashBytes(signatures[0].toByteArray()).toString(); 213 assertThat(signatureSha256).isEqualTo(TELEPHONY_PACKAGE_SIGNATURE_SHA256); 214 } 215 216 @Test 217 public void chooseRestorePolicy_signaturesIsNull_returnsIgnore() throws Exception { 218 InputStream inputStream = mContext.getResources().openRawResource( 219 R.raw.backup_telephony_no_password); 220 InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream( 221 inputStream, null); 222 TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream, 223 mBytesReadListenerMock, mBackupManagerMonitorMock); 224 225 RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub, 226 true /* allowApks */, new FileMetadata(), null /* signatures */, 227 mMockPackageManagerInternal); 228 229 assertThat(policy).isEqualTo(RestorePolicy.IGNORE); 230 verifyZeroInteractions(mBackupManagerMonitorMock); 231 } 232 233 @Test 234 public void chooseRestorePolicy_packageDoesNotExistAndAllowApksAndHasApk_returnsAcceptIfApk() 235 throws Exception { 236 InputStream inputStream = mContext.getResources().openRawResource( 237 R.raw.backup_telephony_no_password); 238 InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream( 239 inputStream, null); 240 TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream, 241 mBytesReadListenerMock, mBackupManagerMonitorMock); 242 FileMetadata info = new FileMetadata(); 243 info.hasApk = true; 244 PackageManagerStub.sPackageInfo = null; 245 246 RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub, 247 true /* allowApks */, info, new Signature[0] /* signatures */, 248 mMockPackageManagerInternal); 249 250 assertThat(policy).isEqualTo(RestorePolicy.ACCEPT_IF_APK); 251 ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class); 252 verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture()); 253 assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo( 254 LOG_EVENT_ID_APK_NOT_INSTALLED); 255 } 256 257 @Test 258 public void 259 chooseRestorePolicy_packageDoesNotExistAndAllowApksAndDoesNotHaveApk_returnsAcceptIfApkLogsCannotRestore() 260 throws Exception { 261 InputStream inputStream = mContext.getResources().openRawResource( 262 R.raw.backup_telephony_no_password); 263 InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream( 264 inputStream, null); 265 TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream, 266 mBytesReadListenerMock, mBackupManagerMonitorMock); 267 FileMetadata info = new FileMetadata(); 268 info.hasApk = false; 269 PackageManagerStub.sPackageInfo = null; 270 271 RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub, 272 true /* allowApks */, info, new Signature[0] /* signatures */, 273 mMockPackageManagerInternal); 274 275 assertThat(policy).isEqualTo(RestorePolicy.ACCEPT_IF_APK); 276 ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class); 277 verify(mBackupManagerMonitorMock, times(2)).onEvent(bundleCaptor.capture()); 278 List<Bundle> eventBundles = bundleCaptor.getAllValues(); 279 assertThat(eventBundles).hasSize(2); 280 assertThat(eventBundles.get(0).get(EXTRA_LOG_EVENT_ID)).isEqualTo( 281 LOG_EVENT_ID_APK_NOT_INSTALLED); 282 assertThat(eventBundles.get(1).get(EXTRA_LOG_EVENT_ID)).isEqualTo( 283 LOG_EVENT_ID_CANNOT_RESTORE_WITHOUT_APK); 284 } 285 286 @Test 287 public void chooseRestorePolicy_packageDoesNotExistAndDoesNotAllowApks_returnsIgnore() 288 throws Exception { 289 InputStream inputStream = mContext.getResources().openRawResource( 290 R.raw.backup_telephony_no_password); 291 InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream( 292 inputStream, null); 293 TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream, 294 mBytesReadListenerMock, mBackupManagerMonitorMock); 295 PackageManagerStub.sPackageInfo = null; 296 297 RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub, 298 false /* allowApks */, new FileMetadata(), new Signature[0] /* signatures */, 299 mMockPackageManagerInternal); 300 301 assertThat(policy).isEqualTo(RestorePolicy.IGNORE); 302 ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class); 303 verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture()); 304 assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo( 305 LOG_EVENT_ID_APK_NOT_INSTALLED); 306 } 307 308 @Test 309 public void chooseRestorePolicy_doesNotAllowsBackup_returnsIgnore() throws Exception { 310 InputStream inputStream = mContext.getResources().openRawResource( 311 R.raw.backup_telephony_no_password); 312 InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream( 313 inputStream, null); 314 TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream, 315 mBytesReadListenerMock, mBackupManagerMonitorMock); 316 317 PackageInfo packageInfo = new PackageInfo(); 318 packageInfo.applicationInfo = new ApplicationInfo(); 319 packageInfo.applicationInfo.flags = ~ApplicationInfo.FLAG_ALLOW_BACKUP; 320 PackageManagerStub.sPackageInfo = packageInfo; 321 322 RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub, 323 false /* allowApks */, new FileMetadata(), new Signature[0] /* signatures */, 324 mMockPackageManagerInternal); 325 326 assertThat(policy).isEqualTo(RestorePolicy.IGNORE); 327 ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class); 328 verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture()); 329 assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo( 330 LOG_EVENT_ID_FULL_RESTORE_ALLOW_BACKUP_FALSE); 331 } 332 333 @Test 334 public void chooseRestorePolicy_systemAppWithNoAgent_returnsIgnore() throws Exception { 335 InputStream inputStream = mContext.getResources().openRawResource( 336 R.raw.backup_telephony_no_password); 337 InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream( 338 inputStream, null); 339 TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream, 340 mBytesReadListenerMock, mBackupManagerMonitorMock); 341 342 PackageInfo packageInfo = new PackageInfo(); 343 packageInfo.applicationInfo = new ApplicationInfo(); 344 packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP; 345 packageInfo.applicationInfo.uid = Process.SYSTEM_UID; 346 packageInfo.applicationInfo.backupAgentName = null; 347 PackageManagerStub.sPackageInfo = packageInfo; 348 349 RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub, 350 false /* allowApks */, new FileMetadata(), new Signature[0] /* signatures */, 351 mMockPackageManagerInternal); 352 353 assertThat(policy).isEqualTo(RestorePolicy.IGNORE); 354 ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class); 355 verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture()); 356 assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo( 357 LOG_EVENT_ID_SYSTEM_APP_NO_AGENT); 358 } 359 360 @Test 361 public void chooseRestorePolicy_nonSystemAppSignaturesDoNotMatch_returnsIgnore() 362 throws Exception { 363 InputStream inputStream = mContext.getResources().openRawResource( 364 R.raw.backup_telephony_no_password); 365 InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream( 366 inputStream, null); 367 TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream, 368 mBytesReadListenerMock, mBackupManagerMonitorMock); 369 Signature[] signatures = new Signature[]{FAKE_SIGNATURE_1}; 370 371 PackageInfo packageInfo = new PackageInfo(); 372 packageInfo.applicationInfo = new ApplicationInfo(); 373 packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP; 374 packageInfo.applicationInfo.uid = Process.FIRST_APPLICATION_UID; 375 packageInfo.applicationInfo.backupAgentName = null; 376 packageInfo.signingInfo = new SigningInfo( 377 new PackageParser.SigningDetails( 378 new Signature[] {FAKE_SIGNATURE_2}, 379 PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3, 380 null, 381 null, 382 null)); 383 PackageManagerStub.sPackageInfo = packageInfo; 384 385 RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub, 386 false /* allowApks */, new FileMetadata(), signatures, mMockPackageManagerInternal); 387 388 assertThat(policy).isEqualTo(RestorePolicy.IGNORE); 389 ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class); 390 verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture()); 391 assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo( 392 LOG_EVENT_ID_FULL_RESTORE_SIGNATURE_MISMATCH); 393 } 394 395 @Test 396 public void chooseRestorePolicy_systemAppWithBackupAgentAndRestoreAnyVersion_returnsAccept() 397 throws Exception { 398 InputStream inputStream = mContext.getResources().openRawResource( 399 R.raw.backup_telephony_no_password); 400 InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream( 401 inputStream, null); 402 TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream, 403 mBytesReadListenerMock, mBackupManagerMonitorMock); 404 Signature[] signatures = new Signature[]{FAKE_SIGNATURE_1}; 405 406 PackageInfo packageInfo = new PackageInfo(); 407 packageInfo.packageName = "test"; 408 packageInfo.applicationInfo = new ApplicationInfo(); 409 packageInfo.applicationInfo.flags |= 410 ApplicationInfo.FLAG_ALLOW_BACKUP | ApplicationInfo.FLAG_RESTORE_ANY_VERSION; 411 packageInfo.applicationInfo.uid = Process.SYSTEM_UID; 412 packageInfo.applicationInfo.backupAgentName = "backup.agent"; 413 packageInfo.signingInfo = new SigningInfo( 414 new PackageParser.SigningDetails( 415 new Signature[] {FAKE_SIGNATURE_1}, 416 PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3, 417 null, 418 null, 419 null)); 420 PackageManagerStub.sPackageInfo = packageInfo; 421 422 doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(FAKE_SIGNATURE_1, 423 packageInfo.packageName); 424 RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub, 425 false /* allowApks */, new FileMetadata(), signatures, mMockPackageManagerInternal); 426 427 assertThat(policy).isEqualTo(RestorePolicy.ACCEPT); 428 ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class); 429 verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture()); 430 assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo( 431 LOG_EVENT_ID_RESTORE_ANY_VERSION); 432 } 433 434 @Test 435 public void chooseRestorePolicy_restoreAnyVersion_returnsAccept() throws Exception { 436 InputStream inputStream = mContext.getResources().openRawResource( 437 R.raw.backup_telephony_no_password); 438 InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream( 439 inputStream, null); 440 TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream, 441 mBytesReadListenerMock, mBackupManagerMonitorMock); 442 Signature[] signatures = new Signature[]{FAKE_SIGNATURE_1}; 443 444 PackageInfo packageInfo = new PackageInfo(); 445 packageInfo.packageName = "test"; 446 packageInfo.applicationInfo = new ApplicationInfo(); 447 packageInfo.applicationInfo.flags |= 448 ApplicationInfo.FLAG_ALLOW_BACKUP | ApplicationInfo.FLAG_RESTORE_ANY_VERSION; 449 packageInfo.applicationInfo.uid = Process.FIRST_APPLICATION_UID; 450 packageInfo.applicationInfo.backupAgentName = null; 451 packageInfo.signingInfo = new SigningInfo( 452 new PackageParser.SigningDetails( 453 new Signature[] {FAKE_SIGNATURE_1}, 454 PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3, 455 null, 456 null, 457 null)); 458 PackageManagerStub.sPackageInfo = packageInfo; 459 460 doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(FAKE_SIGNATURE_1, 461 packageInfo.packageName); 462 RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub, 463 false /* allowApks */, new FileMetadata(), signatures, mMockPackageManagerInternal); 464 465 assertThat(policy).isEqualTo(RestorePolicy.ACCEPT); 466 ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class); 467 verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture()); 468 assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo( 469 LOG_EVENT_ID_RESTORE_ANY_VERSION); 470 } 471 472 @Test 473 public void chooseRestorePolicy_notRestoreAnyVersionButVersionMatch_returnsAccept() 474 throws Exception { 475 InputStream inputStream = mContext.getResources().openRawResource( 476 R.raw.backup_telephony_no_password); 477 InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream( 478 inputStream, null); 479 TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream, 480 mBytesReadListenerMock, mBackupManagerMonitorMock); 481 Signature[] signatures = new Signature[]{FAKE_SIGNATURE_1}; 482 FileMetadata info = new FileMetadata(); 483 info.version = 1; 484 485 PackageInfo packageInfo = new PackageInfo(); 486 packageInfo.packageName = "test"; 487 packageInfo.applicationInfo = new ApplicationInfo(); 488 packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP; 489 packageInfo.applicationInfo.flags &= ~ApplicationInfo.FLAG_RESTORE_ANY_VERSION; 490 packageInfo.applicationInfo.uid = Process.FIRST_APPLICATION_UID; 491 packageInfo.applicationInfo.backupAgentName = null; 492 packageInfo.signingInfo = new SigningInfo( 493 new PackageParser.SigningDetails( 494 new Signature[] {FAKE_SIGNATURE_1}, 495 PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3, 496 null, 497 null, 498 null)); 499 packageInfo.versionCode = 2; 500 PackageManagerStub.sPackageInfo = packageInfo; 501 502 doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(FAKE_SIGNATURE_1, 503 packageInfo.packageName); 504 RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub, 505 false /* allowApks */, info, signatures, mMockPackageManagerInternal); 506 507 assertThat(policy).isEqualTo(RestorePolicy.ACCEPT); 508 ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class); 509 verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture()); 510 assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo( 511 LOG_EVENT_ID_VERSIONS_MATCH); 512 } 513 514 @Test 515 public void 516 chooseRestorePolicy_notRestoreAnyVersionAndVersionMismatchButAllowApksAndHasApk_returnsAcceptIfApk() 517 throws Exception { 518 InputStream inputStream = mContext.getResources().openRawResource( 519 R.raw.backup_telephony_no_password); 520 InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream( 521 inputStream, null); 522 TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream, 523 mBytesReadListenerMock, mBackupManagerMonitorMock); 524 Signature[] signatures = new Signature[]{FAKE_SIGNATURE_1}; 525 FileMetadata info = new FileMetadata(); 526 info.version = 2; 527 info.hasApk = true; 528 529 PackageInfo packageInfo = new PackageInfo(); 530 packageInfo.packageName = "test"; 531 packageInfo.applicationInfo = new ApplicationInfo(); 532 packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP; 533 packageInfo.applicationInfo.flags &= ~ApplicationInfo.FLAG_RESTORE_ANY_VERSION; 534 packageInfo.applicationInfo.uid = Process.FIRST_APPLICATION_UID; 535 packageInfo.applicationInfo.backupAgentName = null; 536 packageInfo.signingInfo = new SigningInfo( 537 new PackageParser.SigningDetails( 538 new Signature[] {FAKE_SIGNATURE_1}, 539 PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3, 540 null, 541 null, 542 null)); 543 packageInfo.versionCode = 1; 544 PackageManagerStub.sPackageInfo = packageInfo; 545 546 doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(FAKE_SIGNATURE_1, 547 packageInfo.packageName); 548 RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub, 549 true /* allowApks */, info, signatures, mMockPackageManagerInternal); 550 551 assertThat(policy).isEqualTo(RestorePolicy.ACCEPT_IF_APK); 552 verifyNoMoreInteractions(mBackupManagerMonitorMock); 553 } 554 555 @Test 556 public void 557 chooseRestorePolicy_notRestoreAnyVersionAndVersionMismatchAndDoesNotAllowApks_returnsIgnore() 558 throws Exception { 559 InputStream inputStream = mContext.getResources().openRawResource( 560 R.raw.backup_telephony_no_password); 561 InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream( 562 inputStream, null); 563 TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream, 564 mBytesReadListenerMock, mBackupManagerMonitorMock); 565 Signature[] signatures = new Signature[]{FAKE_SIGNATURE_1}; 566 FileMetadata info = new FileMetadata(); 567 info.version = 2; 568 569 PackageInfo packageInfo = new PackageInfo(); 570 packageInfo.packageName = "test"; 571 packageInfo.applicationInfo = new ApplicationInfo(); 572 packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP; 573 packageInfo.applicationInfo.flags &= ~ApplicationInfo.FLAG_RESTORE_ANY_VERSION; 574 packageInfo.applicationInfo.uid = Process.FIRST_APPLICATION_UID; 575 packageInfo.applicationInfo.backupAgentName = null; 576 packageInfo.signingInfo = new SigningInfo( 577 new PackageParser.SigningDetails( 578 new Signature[] {FAKE_SIGNATURE_1}, 579 PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3, 580 null, 581 null, 582 null)); 583 packageInfo.versionCode = 1; 584 PackageManagerStub.sPackageInfo = packageInfo; 585 586 doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(FAKE_SIGNATURE_1, 587 packageInfo.packageName); 588 RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub, 589 false /* allowApks */, info, signatures, mMockPackageManagerInternal); 590 591 assertThat(policy).isEqualTo(RestorePolicy.IGNORE); 592 ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class); 593 verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture()); 594 assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo( 595 LOG_EVENT_ID_VERSION_OF_BACKUP_OLDER); 596 } 597} 598 599