1 /* 2 * Copyright (C) 2019 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 com.android.server.rollback; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import static org.mockito.ArgumentMatchers.any; 22 import static org.mockito.ArgumentMatchers.anyInt; 23 import static org.mockito.ArgumentMatchers.argThat; 24 import static org.mockito.ArgumentMatchers.eq; 25 import static org.mockito.Mockito.never; 26 import static org.mockito.Mockito.verify; 27 import static org.mockito.Mockito.when; 28 29 import android.content.pm.PackageManagerInternal; 30 import android.content.pm.VersionedPackage; 31 import android.content.rollback.PackageRollbackInfo; 32 import android.util.SparseArray; 33 import android.util.SparseIntArray; 34 35 import com.android.server.pm.PackageList; 36 import com.android.server.pm.parsing.pkg.PackageImpl; 37 import com.google.common.collect.Range; 38 39 import org.junit.Before; 40 import org.junit.Test; 41 import org.junit.runner.RunWith; 42 import org.junit.runners.JUnit4; 43 import org.mockito.ArgumentMatcher; 44 import org.mockito.Mock; 45 import org.mockito.MockitoAnnotations; 46 47 import java.io.File; 48 import java.time.Instant; 49 import java.util.ArrayList; 50 import java.util.Arrays; 51 import java.util.List; 52 53 @RunWith(JUnit4.class) 54 public class RollbackUnitTest { 55 56 private static final String PKG_1 = "test.testpackage.pkg1"; 57 private static final String PKG_2 = "test.testpackage.pkg2"; 58 private static final String PKG_3 = "com.blah.hello.three"; 59 private static final String PKG_4 = "com.something.4pack"; 60 private static final int USER = 0; 61 private static final String INSTALLER = "some.installer"; 62 63 @Mock private AppDataRollbackHelper mMockDataHelper; 64 @Mock private PackageManagerInternal mMockPmi; 65 66 private List<String> mPackages; 67 private PackageList mPackageList; 68 69 @Before setUp()70 public void setUp() { 71 MockitoAnnotations.initMocks(this); 72 mPackages = new ArrayList<>(); 73 mPackageList = new PackageList(mPackages, null); 74 when(mMockPmi.getPackageList()).thenReturn(mPackageList); 75 } 76 createStagedRollback(int rollbackId, File backupDir, int originalSessionId)77 private Rollback createStagedRollback(int rollbackId, File backupDir, int originalSessionId) { 78 return new Rollback(rollbackId, backupDir, originalSessionId, /* isStaged */ true, USER, 79 INSTALLER, null, new SparseIntArray(0)); 80 } 81 createNonStagedRollback(int rollbackId, File backupDir)82 private Rollback createNonStagedRollback(int rollbackId, File backupDir) { 83 return new Rollback(rollbackId, backupDir, -1, /* isStaged */ false, USER, 84 INSTALLER, null, new SparseIntArray(0)); 85 } 86 87 @Test newEmptyStagedRollbackDefaults()88 public void newEmptyStagedRollbackDefaults() { 89 int rollbackId = 123; 90 int sessionId = 567; 91 File file = new File("/test/testing"); 92 93 Rollback rollback = createStagedRollback(rollbackId, file, sessionId); 94 95 assertThat(rollback.isEnabling()).isTrue(); 96 assertThat(rollback.getBackupDir().getAbsolutePath()).isEqualTo("/test/testing"); 97 assertThat(rollback.isStaged()).isTrue(); 98 assertThat(rollback.getOriginalSessionId()).isEqualTo(567); 99 } 100 101 @Test newEmptyNonStagedRollbackDefaults()102 public void newEmptyNonStagedRollbackDefaults() { 103 int rollbackId = 123; 104 File file = new File("/test/testing"); 105 106 Rollback rollback = createNonStagedRollback(rollbackId, file); 107 108 assertThat(rollback.isEnabling()).isTrue(); 109 assertThat(rollback.getBackupDir().getAbsolutePath()).isEqualTo("/test/testing"); 110 assertThat(rollback.isStaged()).isFalse(); 111 } 112 113 @Test rollbackMadeAvailable()114 public void rollbackMadeAvailable() { 115 Rollback rollback = createNonStagedRollback(123, new File("/test/testing")); 116 117 assertThat(rollback.isEnabling()).isTrue(); 118 assertThat(rollback.isAvailable()).isFalse(); 119 assertThat(rollback.isCommitted()).isFalse(); 120 121 Instant availableTime = Instant.now(); 122 rollback.makeAvailable(); 123 124 assertThat(rollback.isEnabling()).isFalse(); 125 assertThat(rollback.isAvailable()).isTrue(); 126 assertThat(rollback.isCommitted()).isFalse(); 127 128 assertThat(rollback.getTimestamp()).isIn(Range.closed(availableTime, Instant.now())); 129 } 130 131 @Test deletedRollbackCannotBeMadeAvailable()132 public void deletedRollbackCannotBeMadeAvailable() { 133 Rollback rollback = createNonStagedRollback(123, new File("/test/testing")); 134 135 rollback.delete(mMockDataHelper, "test"); 136 137 assertThat(rollback.isDeleted()).isTrue(); 138 139 rollback.makeAvailable(); 140 141 assertThat(rollback.isAvailable()).isFalse(); 142 assertThat(rollback.isDeleted()).isTrue(); 143 } 144 145 @Test getPackageNamesAllAndJustApex()146 public void getPackageNamesAllAndJustApex() { 147 Rollback rollback = createNonStagedRollback(123, new File("/test/testing")); 148 PackageRollbackInfo pkgInfo1 = newPkgInfoFor(PKG_1, 12, 10, false); 149 PackageRollbackInfo pkgInfo2 = newPkgInfoFor(PKG_2, 18, 11, true); 150 PackageRollbackInfo pkgInfo3 = newPkgInfoFor(PKG_3, 19, 1, false); 151 PackageRollbackInfo pkgInfo4 = newPkgInfoFor(PKG_4, 12, 1, true); 152 153 rollback.info.getPackages().addAll(Arrays.asList(pkgInfo1, pkgInfo2, pkgInfo3, pkgInfo4)); 154 155 assertThat(rollback.getPackageNames()).containsExactly(PKG_1, PKG_2, PKG_3, PKG_4); 156 assertThat(rollback.getApexPackageNames()).containsExactly(PKG_2, PKG_4); 157 } 158 159 @Test includesPackagesAfterEnable()160 public void includesPackagesAfterEnable() { 161 Rollback rollback = createNonStagedRollback(123, new File("/test/testing")); 162 PackageRollbackInfo pkgInfo1 = newPkgInfoFor(PKG_1, 12, 10, false); 163 PackageRollbackInfo pkgInfo2 = newPkgInfoFor(PKG_2, 18, 12, true); 164 PackageRollbackInfo pkgInfo3 = newPkgInfoFor(PKG_3, 157, 156, false); 165 PackageRollbackInfo pkgInfo4 = newPkgInfoFor(PKG_4, 99, 1, true); 166 167 rollback.info.getPackages().addAll(Arrays.asList(pkgInfo1, pkgInfo2, pkgInfo3, pkgInfo4)); 168 169 assertThat(rollback.includesPackage(PKG_2)).isTrue(); 170 assertThat(rollback.includesPackage(PKG_3)).isTrue(); 171 assertThat(rollback.includesPackage("com.something.else")).isFalse(); 172 173 assertThat(rollback.includesPackageWithDifferentVersion(PKG_1, 12)).isFalse(); 174 assertThat(rollback.includesPackageWithDifferentVersion(PKG_1, 1)).isTrue(); 175 176 assertThat(rollback.includesPackageWithDifferentVersion(PKG_2, 18)).isFalse(); 177 assertThat(rollback.includesPackageWithDifferentVersion(PKG_2, 12)).isTrue(); 178 179 assertThat(rollback.includesPackageWithDifferentVersion(PKG_3, 157)).isFalse(); 180 assertThat(rollback.includesPackageWithDifferentVersion(PKG_3, 156)).isTrue(); 181 assertThat(rollback.includesPackageWithDifferentVersion(PKG_3, 15)).isTrue(); 182 183 assertThat(rollback.includesPackageWithDifferentVersion(PKG_4, 99)).isFalse(); 184 assertThat(rollback.includesPackageWithDifferentVersion(PKG_4, 100)).isTrue(); 185 } 186 187 @Test snapshotWhenEnabling()188 public void snapshotWhenEnabling() { 189 Rollback rollback = createNonStagedRollback(123, new File("/test/testing")); 190 PackageRollbackInfo pkgInfo1 = newPkgInfoFor(PKG_1, 12, 10, false); 191 PackageRollbackInfo pkgInfo2 = newPkgInfoFor(PKG_2, 18, 12, true); 192 rollback.info.getPackages().addAll(Arrays.asList(pkgInfo1, pkgInfo2)); 193 194 assertThat(rollback.isEnabling()).isTrue(); 195 196 int[] userIds = {4, 77}; 197 rollback.snapshotUserData(PKG_2, userIds, mMockDataHelper); 198 199 // Data is snapshotted for the specified package. 200 verify(mMockDataHelper).snapshotAppData(eq(123), pkgRollbackInfoFor(PKG_2), eq(userIds)); 201 verify(mMockDataHelper, never()) 202 .snapshotAppData(anyInt(), pkgRollbackInfoFor(PKG_1), any()); 203 } 204 205 @Test snapshotWhenAvailable()206 public void snapshotWhenAvailable() { 207 Rollback rollback = createNonStagedRollback(123, new File("/test/testing")); 208 PackageRollbackInfo pkgInfo1 = newPkgInfoFor(PKG_1, 12, 10, false); 209 PackageRollbackInfo pkgInfo2 = newPkgInfoFor(PKG_2, 18, 12, true); 210 rollback.info.getPackages().addAll(Arrays.asList(pkgInfo1, pkgInfo2)); 211 212 rollback.makeAvailable(); 213 214 assertThat(rollback.isAvailable()).isTrue(); 215 216 int[] userIds = {4, 77}; 217 rollback.snapshotUserData(PKG_2, userIds, mMockDataHelper); 218 219 // No data is snapshotted as rollback was not in the enabling state. 220 verify(mMockDataHelper, never()) 221 .snapshotAppData(anyInt(), pkgRollbackInfoFor(PKG_1), any()); 222 verify(mMockDataHelper, never()) 223 .snapshotAppData(anyInt(), pkgRollbackInfoFor(PKG_2), any()); 224 } 225 226 @Test snapshotWhenDeleted()227 public void snapshotWhenDeleted() { 228 Rollback rollback = createNonStagedRollback(123, new File("/test/testing")); 229 PackageRollbackInfo pkgInfo1 = newPkgInfoFor(PKG_1, 12, 10, false); 230 PackageRollbackInfo pkgInfo2 = newPkgInfoFor(PKG_2, 18, 12, true); 231 rollback.info.getPackages().addAll(Arrays.asList(pkgInfo1, pkgInfo2)); 232 233 rollback.delete(mMockDataHelper, "test"); 234 235 assertThat(rollback.isDeleted()).isTrue(); 236 237 int[] userIds = {4, 77}; 238 rollback.snapshotUserData(PKG_2, userIds, mMockDataHelper); 239 240 // No data is snapshotted as rollback was not in the enabling state. 241 verify(mMockDataHelper, never()) 242 .snapshotAppData(anyInt(), pkgRollbackInfoFor(PKG_1), any()); 243 verify(mMockDataHelper, never()) 244 .snapshotAppData(anyInt(), pkgRollbackInfoFor(PKG_2), any()); 245 } 246 247 @Test snapshotThenDeleteNoApex()248 public void snapshotThenDeleteNoApex() { 249 Rollback rollback = createNonStagedRollback(123, new File("/test/testing")); 250 PackageRollbackInfo pkgInfo1 = newPkgInfoFor(PKG_1, 12, 10, false); 251 PackageRollbackInfo pkgInfo2 = newPkgInfoFor(PKG_2, 18, 12, false); 252 rollback.info.getPackages().addAll(Arrays.asList(pkgInfo1, pkgInfo2)); 253 254 int[] userIds = {111, 222}; 255 rollback.snapshotUserData(PKG_2, userIds, mMockDataHelper); 256 257 verify(mMockDataHelper).snapshotAppData(eq(123), pkgRollbackInfoFor(PKG_2), eq(userIds)); 258 259 rollback.delete(mMockDataHelper, "test"); 260 261 verify(mMockDataHelper).destroyAppDataSnapshot(eq(123), pkgRollbackInfoFor(PKG_2), eq(111)); 262 verify(mMockDataHelper).destroyAppDataSnapshot(eq(123), pkgRollbackInfoFor(PKG_2), eq(222)); 263 verify(mMockDataHelper, never()).destroyApexDeSnapshots(anyInt()); 264 verify(mMockDataHelper, never()).destroyApexCeSnapshots(anyInt(), anyInt()); 265 266 assertThat(rollback.isDeleted()).isTrue(); 267 } 268 269 @Test snapshotThenDeleteWithApex()270 public void snapshotThenDeleteWithApex() { 271 Rollback rollback = createNonStagedRollback(123, new File("/test/testing")); 272 PackageRollbackInfo pkgInfo1 = newPkgInfoFor(PKG_1, 12, 10, false); 273 PackageRollbackInfo pkgInfo2 = newPkgInfoFor(PKG_2, 18, 12, true); 274 rollback.info.getPackages().addAll(Arrays.asList(pkgInfo1, pkgInfo2)); 275 276 int[] userIds = {111, 222}; 277 rollback.snapshotUserData(PKG_2, userIds, mMockDataHelper); 278 279 verify(mMockDataHelper).snapshotAppData(eq(123), pkgRollbackInfoFor(PKG_2), eq(userIds)); 280 281 rollback.delete(mMockDataHelper, "test"); 282 283 verify(mMockDataHelper, never()) 284 .destroyAppDataSnapshot(anyInt(), pkgRollbackInfoFor(PKG_2), anyInt()); 285 verify(mMockDataHelper).destroyApexDeSnapshots(123); 286 verify(mMockDataHelper).destroyApexCeSnapshots(111, 123); 287 verify(mMockDataHelper).destroyApexCeSnapshots(222, 123); 288 289 assertThat(rollback.isDeleted()).isTrue(); 290 } 291 292 @Test restoreUserDataDoesNothingIfNotInProgress()293 public void restoreUserDataDoesNothingIfNotInProgress() { 294 Rollback rollback = createNonStagedRollback(123, new File("/test/testing")); 295 PackageRollbackInfo pkgInfo1 = newPkgInfoFor(PKG_1, 12, 10, false); 296 PackageRollbackInfo pkgInfo2 = newPkgInfoFor(PKG_2, 18, 12, true); 297 rollback.info.getPackages().addAll(Arrays.asList(pkgInfo1, pkgInfo2)); 298 299 assertThat(rollback.isRestoreUserDataInProgress()).isFalse(); 300 301 assertThat(rollback.restoreUserDataForPackageIfInProgress( 302 PKG_1, new int[] { 5 }, 333, "", mMockDataHelper)).isFalse(); 303 304 verify(mMockDataHelper, never()).restoreAppData(anyInt(), any(), anyInt(), anyInt(), any()); 305 } 306 307 @Test restoreUserDataDoesNothingIfPackageNotFound()308 public void restoreUserDataDoesNothingIfPackageNotFound() { 309 Rollback rollback = createNonStagedRollback(123, new File("/test/testing")); 310 PackageRollbackInfo pkgInfo1 = newPkgInfoFor(PKG_1, 12, 10, false); 311 PackageRollbackInfo pkgInfo2 = newPkgInfoFor(PKG_2, 18, 12, true); 312 rollback.info.getPackages().addAll(Arrays.asList(pkgInfo1, pkgInfo2)); 313 314 rollback.setRestoreUserDataInProgress(true); 315 assertThat(rollback.isRestoreUserDataInProgress()).isTrue(); 316 317 assertThat(rollback.restoreUserDataForPackageIfInProgress( 318 PKG_3, new int[] { 5 }, 333, "", mMockDataHelper)).isFalse(); 319 320 verify(mMockDataHelper, never()).restoreAppData(anyInt(), any(), anyInt(), anyInt(), any()); 321 } 322 323 @Test restoreUserDataRestoresIfInProgressAndPackageFound()324 public void restoreUserDataRestoresIfInProgressAndPackageFound() { 325 Rollback rollback = createNonStagedRollback(123, new File("/test/testing")); 326 PackageRollbackInfo pkgInfo1 = newPkgInfoFor(PKG_1, 12, 10, false); 327 PackageRollbackInfo pkgInfo2 = newPkgInfoFor(PKG_2, 18, 12, true); 328 rollback.info.getPackages().addAll(Arrays.asList(pkgInfo1, pkgInfo2)); 329 330 rollback.setRestoreUserDataInProgress(true); 331 assertThat(rollback.isRestoreUserDataInProgress()).isTrue(); 332 333 assertThat(rollback.restoreUserDataForPackageIfInProgress( 334 PKG_1, new int[] { 5, 7 }, 333, "blah", mMockDataHelper)).isTrue(); 335 336 verify(mMockDataHelper).restoreAppData(123, pkgInfo1, 5, 333, "blah"); 337 verify(mMockDataHelper).restoreAppData(123, pkgInfo1, 7, 333, "blah"); 338 } 339 340 @Test allPackagesEnabled()341 public void allPackagesEnabled() { 342 int[] sessionIds = new int[]{ 7777, 8888 }; 343 Rollback rollback = new Rollback(123, new File("/test/testing"), -1, false, USER, INSTALLER, 344 sessionIds, new SparseIntArray(0)); 345 // #allPackagesEnabled returns false when 1 out of 2 packages is enabled. 346 rollback.info.getPackages().add(newPkgInfoFor(PKG_1, 12, 10, false)); 347 assertThat(rollback.allPackagesEnabled()).isFalse(); 348 // #allPackagesEnabled returns false for ApkInApex doesn't count. 349 rollback.info.getPackages().add(newPkgInfoForApkInApex(PKG_3, 157, 156)); 350 assertThat(rollback.allPackagesEnabled()).isFalse(); 351 // #allPackagesEnabled returns true when 2 out of 2 packages are enabled. 352 rollback.info.getPackages().add(newPkgInfoFor(PKG_2, 18, 12, true)); 353 assertThat(rollback.allPackagesEnabled()).isTrue(); 354 } 355 356 @Test minExtVerConstraintNotViolated()357 public void minExtVerConstraintNotViolated() { 358 addPkgWithMinExtVersions("pkg0", new int[][] {{30, 4}}); 359 addPkgWithMinExtVersions("pkg1", new int[][] {}); 360 addPkgWithMinExtVersions("pkg2", new int[][] {{30, 5}, {31, 1}}); 361 addPkgWithMinExtVersions("pkg3", new int[][] {{31, 7}, {32, 15}}); 362 363 assertThat(Rollback.extensionVersionReductionWouldViolateConstraint( 364 sparseArrayFrom(new int[][] {{30, 5}}), mMockPmi)).isFalse(); 365 } 366 367 @Test minExtVerConstraintExists()368 public void minExtVerConstraintExists() { 369 addPkgWithMinExtVersions("pkg0", null); 370 addPkgWithMinExtVersions("pkg1", new int[][] {{30, 5}, {31, 1}}); 371 372 assertThat(Rollback.extensionVersionReductionWouldViolateConstraint( 373 sparseArrayFrom(new int[][] {{30, 4}}), mMockPmi)).isTrue(); 374 } 375 376 @Test minExtVerConstraintExistsOnOnePackage()377 public void minExtVerConstraintExistsOnOnePackage() { 378 addPkgWithMinExtVersions("pkg0", new int[][] {{30, 4}}); 379 addPkgWithMinExtVersions("pkg1", new int[][] {}); 380 addPkgWithMinExtVersions("pkg2", new int[][] {{30, 5}, {31, 1}}); 381 addPkgWithMinExtVersions("pkg3", new int[][] {{31, 7}, {32, 15}}); 382 383 assertThat(Rollback.extensionVersionReductionWouldViolateConstraint( 384 sparseArrayFrom(new int[][] {{30, 4}}), mMockPmi)).isTrue(); 385 } 386 387 @Test minExtVerConstraintDifferentSdk()388 public void minExtVerConstraintDifferentSdk() { 389 addPkgWithMinExtVersions("pkg0", null); 390 addPkgWithMinExtVersions("pkg1", new int[][] {{30, 5}, {31, 1}}); 391 392 assertThat(Rollback.extensionVersionReductionWouldViolateConstraint( 393 sparseArrayFrom(new int[][] {{32, 4}}), mMockPmi)).isFalse(); 394 } 395 396 @Test minExtVerConstraintNoneRecordedOnRollback()397 public void minExtVerConstraintNoneRecordedOnRollback() { 398 addPkgWithMinExtVersions("pkg0", new int[][] {{30, 4}}); 399 addPkgWithMinExtVersions("pkg1", new int[][] {}); 400 addPkgWithMinExtVersions("pkg2", new int[][] {{30, 5}, {31, 1}}); 401 addPkgWithMinExtVersions("pkg3", new int[][] {{31, 7}, {32, 15}}); 402 403 assertThat(Rollback.extensionVersionReductionWouldViolateConstraint( 404 new SparseIntArray(0), mMockPmi)).isFalse(); 405 } 406 407 @Test minExtVerConstraintNoMinsRecorded()408 public void minExtVerConstraintNoMinsRecorded() { 409 addPkgWithMinExtVersions("pkg0", null); 410 addPkgWithMinExtVersions("pkg1", null); 411 412 assertThat(Rollback.extensionVersionReductionWouldViolateConstraint( 413 sparseArrayFrom(new int[][] {{32, 4}}), mMockPmi)).isFalse(); 414 } 415 addPkgWithMinExtVersions(String pkg, int[][] minExtVersions)416 private void addPkgWithMinExtVersions(String pkg, int[][] minExtVersions) { 417 mPackages.add(pkg); 418 PackageImpl pkgImpl = new PackageImpl(pkg, "baseCodePath", "codePath", null, false); 419 pkgImpl.setMinExtensionVersions(sparseArrayFrom(minExtVersions)); 420 421 when(mMockPmi.getPackage(pkg)).thenReturn(pkgImpl); 422 } 423 sparseArrayFrom(int[][] arr)424 private static SparseIntArray sparseArrayFrom(int[][] arr) { 425 if (arr == null) { 426 return null; 427 } 428 SparseIntArray result = new SparseIntArray(arr.length); 429 for (int[] pair : arr) { 430 result.put(pair[0], pair[1]); 431 } 432 return result; 433 } 434 435 @Test readAndWriteStagedRollbackIdsFile()436 public void readAndWriteStagedRollbackIdsFile() throws Exception { 437 File testFile = File.createTempFile("test", ".txt"); 438 RollbackPackageHealthObserver.writeStagedRollbackId(testFile, 2468, null); 439 RollbackPackageHealthObserver.writeStagedRollbackId(testFile, 12345, 440 new VersionedPackage("com.test.package", 1)); 441 RollbackPackageHealthObserver.writeStagedRollbackId(testFile, 13579, 442 new VersionedPackage("com.test.package2", 2)); 443 SparseArray<String> readInfo = 444 RollbackPackageHealthObserver.readStagedRollbackIds(testFile); 445 assertThat(readInfo.size()).isEqualTo(3); 446 447 assertThat(readInfo.keyAt(0)).isEqualTo(2468); 448 assertThat(readInfo.valueAt(0)).isEqualTo(""); 449 assertThat(readInfo.keyAt(1)).isEqualTo(12345); 450 assertThat(readInfo.valueAt(1)).isEqualTo("com.test.package"); 451 assertThat(readInfo.keyAt(2)).isEqualTo(13579); 452 assertThat(readInfo.valueAt(2)).isEqualTo("com.test.package2"); 453 } 454 newPkgInfoFor( String packageName, long fromVersion, long toVersion, boolean isApex)455 private static PackageRollbackInfo newPkgInfoFor( 456 String packageName, long fromVersion, long toVersion, boolean isApex) { 457 return new PackageRollbackInfo(new VersionedPackage(packageName, fromVersion), 458 new VersionedPackage(packageName, toVersion), 459 new ArrayList<>(), new ArrayList<>(), isApex, false, new ArrayList<>()); 460 } 461 462 /** 463 * TODO: merge newPkgInfoFor and newPkgInfoForApkInApex by using enums to specify 464 * 1. IS_APK 465 * 2. IS_APEX 466 * 3. IS_APK_IN_APEX 467 */ newPkgInfoForApkInApex( String packageName, long fromVersion, long toVersion)468 private static PackageRollbackInfo newPkgInfoForApkInApex( 469 String packageName, long fromVersion, long toVersion) { 470 return new PackageRollbackInfo(new VersionedPackage(packageName, fromVersion), 471 new VersionedPackage(packageName, toVersion), 472 new ArrayList<>(), new ArrayList<>(), false, true, new ArrayList<>()); 473 } 474 475 private static class PackageRollbackInfoForPackage implements 476 ArgumentMatcher<PackageRollbackInfo> { 477 private final String mPkg; 478 PackageRollbackInfoForPackage(String pkg)479 PackageRollbackInfoForPackage(String pkg) { 480 mPkg = pkg; 481 } 482 483 @Override matches(PackageRollbackInfo pkgRollbackInfo)484 public boolean matches(PackageRollbackInfo pkgRollbackInfo) { 485 return pkgRollbackInfo.getPackageName().equals(mPkg); 486 } 487 } 488 pkgRollbackInfoFor(String pkg)489 private static PackageRollbackInfo pkgRollbackInfoFor(String pkg) { 490 return argThat(new PackageRollbackInfoForPackage(pkg)); 491 } 492 } 493