Fix bug where RollbackManagerService ignores package name.

RollbackManagerService incorrectly ignores the package name passed to
getAvailableRollback and executeRollback.

This CL fixes the bug and adds a regression test. The infrastructure for
having multiple test apps in RollbackTest will also be useful for
testing rollback of multi-package installs.

Test: atest RollbackTest (with selinux disabled)
Bug: 112431924

Change-Id: I84c8fdeb97aba557a1f8fd2e71a2bb0d87b10636
diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
index 707b139..0c21312 100644
--- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
+++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
@@ -211,7 +211,8 @@
             ensureRollbackDataLoadedLocked();
             for (int i = 0; i < mAvailableRollbacks.size(); ++i) {
                 PackageRollbackData data = mAvailableRollbacks.get(i);
-                if (data.info.higherVersion.equals(installedVersion)) {
+                if (data.info.packageName.equals(packageName)
+                        && data.info.higherVersion.equals(installedVersion)) {
                     // TODO: For atomic installs, check all dependent packages
                     // for available rollbacks and include that info here.
                     return new RollbackInfo(data.info);
@@ -308,7 +309,8 @@
                 PackageRollbackData available = mAvailableRollbacks.get(i);
                 // TODO: Check if available.info.lowerVersion matches
                 // rollback.targetPackage.lowerVersion?
-                if (available.info.higherVersion.equals(installedVersion)) {
+                if (available.info.packageName.equals(packageName)
+                        && available.info.higherVersion.equals(installedVersion)) {
                     data = available;
                     break;
                 }
diff --git a/tests/RollbackTest/Android.mk b/tests/RollbackTest/Android.mk
index 8aadde9..34aa258 100644
--- a/tests/RollbackTest/Android.mk
+++ b/tests/RollbackTest/Android.mk
@@ -14,27 +14,49 @@
 
 LOCAL_PATH:= $(call my-dir)
 
-# RollbackTestAppV1
+# RollbackTestAppAv1.apk
 include $(CLEAR_VARS)
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-LOCAL_MANIFEST_FILE := TestApp/AndroidManifestV1.xml
-LOCAL_PACKAGE_NAME := RollbackTestAppV1
 LOCAL_SDK_VERSION := current
 LOCAL_SRC_FILES := $(call all-java-files-under, TestApp/src)
+LOCAL_MANIFEST_FILE := TestApp/Av1.xml
+LOCAL_PACKAGE_NAME := RollbackTestAppAv1
 include $(BUILD_PACKAGE)
-ROLLBACK_TEST_APP_V1 := $(LOCAL_INSTALLED_MODULE)
+ROLLBACK_TEST_APP_AV1 := $(LOCAL_INSTALLED_MODULE)
 
-# RollbackTestAppV2
+# RollbackTestAppAv2.apk
 include $(CLEAR_VARS)
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-LOCAL_MANIFEST_FILE := TestApp/AndroidManifestV2.xml
-LOCAL_PACKAGE_NAME := RollbackTestAppV2
 LOCAL_SDK_VERSION := current
 LOCAL_SRC_FILES := $(call all-java-files-under, TestApp/src)
+LOCAL_MANIFEST_FILE := TestApp/Av2.xml
+LOCAL_PACKAGE_NAME := RollbackTestAppAv2
 include $(BUILD_PACKAGE)
-ROLLBACK_TEST_APP_V2 := $(LOCAL_INSTALLED_MODULE)
+ROLLBACK_TEST_APP_AV2 := $(LOCAL_INSTALLED_MODULE)
+
+# RollbackTestAppBv1.apk
+include $(CLEAR_VARS)
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+LOCAL_SDK_VERSION := current
+LOCAL_SRC_FILES := $(call all-java-files-under, TestApp/src)
+LOCAL_MANIFEST_FILE := TestApp/Bv1.xml
+LOCAL_PACKAGE_NAME := RollbackTestAppBv1
+include $(BUILD_PACKAGE)
+ROLLBACK_TEST_APP_BV1 := $(LOCAL_INSTALLED_MODULE)
+
+# RollbackTestAppBv2.apk
+include $(CLEAR_VARS)
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+LOCAL_SDK_VERSION := current
+LOCAL_SRC_FILES := $(call all-java-files-under, TestApp/src)
+LOCAL_MANIFEST_FILE := TestApp/Bv2.xml
+LOCAL_PACKAGE_NAME := RollbackTestAppBv2
+include $(BUILD_PACKAGE)
+ROLLBACK_TEST_APP_BV2 := $(LOCAL_INSTALLED_MODULE)
 
 # RollbackTest
 include $(CLEAR_VARS)
@@ -43,11 +65,17 @@
 LOCAL_MODULE_TAGS := tests
 LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
 LOCAL_COMPATIBILITY_SUITE := general-tests
-LOCAL_JAVA_RESOURCE_FILES := $(ROLLBACK_TEST_APP_V1) $(ROLLBACK_TEST_APP_V2)
+LOCAL_JAVA_RESOURCE_FILES := \
+  $(ROLLBACK_TEST_APP_AV1) \
+  $(ROLLBACK_TEST_APP_AV2) \
+  $(ROLLBACK_TEST_APP_BV1) \
+  $(ROLLBACK_TEST_APP_BV2)
 LOCAL_SDK_VERSION := system_current
 LOCAL_TEST_CONFIG := RollbackTest.xml
 include $(BUILD_PACKAGE)
 
 # Clean up local variables
-ROLLBACK_TEST_APP_V1 :=
-ROLLBACK_TEST_APP_V2 :=
+ROLLBACK_TEST_APP_AV1 :=
+ROLLBACK_TEST_APP_AV2 :=
+ROLLBACK_TEST_APP_BV1 :=
+ROLLBACK_TEST_APP_BV2 :=
diff --git a/tests/RollbackTest/TestApp/AndroidManifestV1.xml b/tests/RollbackTest/TestApp/Av1.xml
similarity index 92%
copy from tests/RollbackTest/TestApp/AndroidManifestV1.xml
copy to tests/RollbackTest/TestApp/Av1.xml
index 07a9f7d..996d831 100644
--- a/tests/RollbackTest/TestApp/AndroidManifestV1.xml
+++ b/tests/RollbackTest/TestApp/Av1.xml
@@ -15,14 +15,14 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.tests.rollback.testapp"
+    package="com.android.tests.rollback.testapp.A"
     android:versionCode="1"
     android:versionName="1.0" >
 
 
     <uses-sdk android:minSdkVersion="19" />
 
-    <application android:label="Rollback Test App V1">
+    <application android:label="Rollback Test App A v1">
         <meta-data android:name="version" android:value="1" />
         <receiver android:name="com.android.tests.rollback.testapp.ProcessUserData"
                   android:exported="true" />
diff --git a/tests/RollbackTest/TestApp/AndroidManifestV2.xml b/tests/RollbackTest/TestApp/Av2.xml
similarity index 92%
rename from tests/RollbackTest/TestApp/AndroidManifestV2.xml
rename to tests/RollbackTest/TestApp/Av2.xml
index d1da991..21c7260 100644
--- a/tests/RollbackTest/TestApp/AndroidManifestV2.xml
+++ b/tests/RollbackTest/TestApp/Av2.xml
@@ -15,14 +15,14 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.tests.rollback.testapp"
+    package="com.android.tests.rollback.testapp.A"
     android:versionCode="2"
     android:versionName="2.0" >
 
 
     <uses-sdk android:minSdkVersion="19" />
 
-    <application android:label="Rollback Test App V2">
+    <application android:label="Rollback Test App A v2">
         <meta-data android:name="version" android:value="2" />
         <receiver android:name="com.android.tests.rollback.testapp.ProcessUserData"
                   android:exported="true" />
diff --git a/tests/RollbackTest/TestApp/AndroidManifestV1.xml b/tests/RollbackTest/TestApp/Bv1.xml
similarity index 92%
rename from tests/RollbackTest/TestApp/AndroidManifestV1.xml
rename to tests/RollbackTest/TestApp/Bv1.xml
index 07a9f7d..de0fd0d 100644
--- a/tests/RollbackTest/TestApp/AndroidManifestV1.xml
+++ b/tests/RollbackTest/TestApp/Bv1.xml
@@ -15,14 +15,14 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.tests.rollback.testapp"
+    package="com.android.tests.rollback.testapp.B"
     android:versionCode="1"
     android:versionName="1.0" >
 
 
     <uses-sdk android:minSdkVersion="19" />
 
-    <application android:label="Rollback Test App V1">
+    <application android:label="Rollback Test App B v1">
         <meta-data android:name="version" android:value="1" />
         <receiver android:name="com.android.tests.rollback.testapp.ProcessUserData"
                   android:exported="true" />
diff --git a/tests/RollbackTest/TestApp/AndroidManifestV2.xml b/tests/RollbackTest/TestApp/Bv2.xml
similarity index 92%
copy from tests/RollbackTest/TestApp/AndroidManifestV2.xml
copy to tests/RollbackTest/TestApp/Bv2.xml
index d1da991..6c2e66a 100644
--- a/tests/RollbackTest/TestApp/AndroidManifestV2.xml
+++ b/tests/RollbackTest/TestApp/Bv2.xml
@@ -15,14 +15,14 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.tests.rollback.testapp"
+    package="com.android.tests.rollback.testapp.B"
     android:versionCode="2"
     android:versionName="2.0" >
 
 
     <uses-sdk android:minSdkVersion="19" />
 
-    <application android:label="Rollback Test App V2">
+    <application android:label="Rollback Test App B v2">
         <meta-data android:name="version" android:value="2" />
         <receiver android:name="com.android.tests.rollback.testapp.ProcessUserData"
                   android:exported="true" />
diff --git a/tests/RollbackTest/src/com/android/tests/rollback/RollbackTest.java b/tests/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
index 37c79c6..2fa027e 100644
--- a/tests/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
+++ b/tests/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
@@ -56,7 +56,8 @@
 
     private static final String TAG = "RollbackTest";
 
-    private static final String TEST_APP_PACKAGE_NAME = "com.android.tests.rollback.testapp";
+    private static final String TEST_APP_A = "com.android.tests.rollback.testapp.A";
+    private static final String TEST_APP_B = "com.android.tests.rollback.testapp.B";
 
     /**
      * Test basic rollbacks.
@@ -89,16 +90,16 @@
             RollbackBroadcastReceiver broadcastReceiver = new RollbackBroadcastReceiver();
             RollbackManager rm = RollbackTestUtils.getRollbackManager();
 
-            // Uninstall com.android.tests.rollback.testapp
-            RollbackTestUtils.uninstall("com.android.tests.rollback.testapp");
-            assertEquals(-1, RollbackTestUtils.getInstalledVersion(TEST_APP_PACKAGE_NAME));
+            // Uninstall TEST_APP_A
+            RollbackTestUtils.uninstall(TEST_APP_A);
+            assertEquals(-1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
 
             // TODO: There is currently a race condition between when the app is
             // uninstalled and when rollback manager deletes the rollback. Fix it
             // so that's not the case!
             for (int i = 0; i < 5; ++i) {
                 for (RollbackInfo info : rm.getRecentlyExecutedRollbacks()) {
-                    if (TEST_APP_PACKAGE_NAME.equals(info.targetPackage.packageName)) {
+                    if (TEST_APP_A.equals(info.targetPackage.packageName)) {
                         Log.i(TAG, "Sleeping 1 second to wait for uninstall to take effect.");
                         Thread.sleep(1000);
                         break;
@@ -107,27 +108,27 @@
             }
 
             // The app should not be available for rollback.
-            assertNull(rm.getAvailableRollback(TEST_APP_PACKAGE_NAME));
-            assertFalse(rm.getPackagesWithAvailableRollbacks().contains(TEST_APP_PACKAGE_NAME));
+            assertNull(rm.getAvailableRollback(TEST_APP_A));
+            assertFalse(rm.getPackagesWithAvailableRollbacks().contains(TEST_APP_A));
 
             // There should be no recently executed rollbacks for this package.
             for (RollbackInfo info : rm.getRecentlyExecutedRollbacks()) {
-                assertNotEquals(TEST_APP_PACKAGE_NAME, info.targetPackage.packageName);
+                assertNotEquals(TEST_APP_A, info.targetPackage.packageName);
             }
 
             // Install v1 of the app (without rollbacks enabled).
-            RollbackTestUtils.install("RollbackTestAppV1.apk", false);
-            assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_PACKAGE_NAME));
+            RollbackTestUtils.install("RollbackTestAppAv1.apk", false);
+            assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
 
             // Upgrade from v1 to v2, with rollbacks enabled.
-            RollbackTestUtils.install("RollbackTestAppV2.apk", true);
-            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_PACKAGE_NAME));
+            RollbackTestUtils.install("RollbackTestAppAv2.apk", true);
+            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
 
             // The app should now be available for rollback.
-            assertTrue(rm.getPackagesWithAvailableRollbacks().contains(TEST_APP_PACKAGE_NAME));
-            RollbackInfo rollback = rm.getAvailableRollback(TEST_APP_PACKAGE_NAME);
+            assertTrue(rm.getPackagesWithAvailableRollbacks().contains(TEST_APP_A));
+            RollbackInfo rollback = rm.getAvailableRollback(TEST_APP_A);
             assertNotNull(rollback);
-            assertEquals(TEST_APP_PACKAGE_NAME, rollback.targetPackage.packageName);
+            assertEquals(TEST_APP_A, rollback.targetPackage.packageName);
             assertEquals(2, rollback.targetPackage.higherVersion.versionCode);
             assertEquals(1, rollback.targetPackage.lowerVersion.versionCode);
 
@@ -138,26 +139,26 @@
 
             // Roll back the app.
             RollbackTestUtils.rollback(rollback);
-            assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_PACKAGE_NAME));
+            assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
 
             // Verify we received a broadcast for the rollback.
             // TODO: Race condition between the timeout and when the broadcast is
             // received could lead to test flakiness.
             Intent broadcast = broadcastReceiver.poll(5, TimeUnit.SECONDS);
             assertNotNull(broadcast);
-            assertEquals(TEST_APP_PACKAGE_NAME, broadcast.getData().getSchemeSpecificPart());
+            assertEquals(TEST_APP_A, broadcast.getData().getSchemeSpecificPart());
             assertNull(broadcastReceiver.poll(0, TimeUnit.SECONDS));
 
             // Verify the recent rollback has been recorded.
             rollback = null;
             for (RollbackInfo r : rm.getRecentlyExecutedRollbacks()) {
-                if (TEST_APP_PACKAGE_NAME.equals(r.targetPackage.packageName)) {
+                if (TEST_APP_A.equals(r.targetPackage.packageName)) {
                     assertNull(rollback);
                     rollback = r;
                 }
             }
             assertNotNull(rollback);
-            assertEquals(TEST_APP_PACKAGE_NAME, rollback.targetPackage.packageName);
+            assertEquals(TEST_APP_A, rollback.targetPackage.packageName);
             assertEquals(2, rollback.targetPackage.higherVersion.versionCode);
             assertEquals(1, rollback.targetPackage.lowerVersion.versionCode);
 
@@ -181,17 +182,17 @@
 
             RollbackManager rm = RollbackTestUtils.getRollbackManager();
 
-            // Prep installation of com.android.tests.rollback.testapp
-            RollbackTestUtils.uninstall("com.android.tests.rollback.testapp");
-            RollbackTestUtils.install("RollbackTestAppV1.apk", false);
-            RollbackTestUtils.install("RollbackTestAppV2.apk", true);
-            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_PACKAGE_NAME));
+            // Prep installation of TEST_APP_A
+            RollbackTestUtils.uninstall(TEST_APP_A);
+            RollbackTestUtils.install("RollbackTestAppAv1.apk", false);
+            RollbackTestUtils.install("RollbackTestAppAv2.apk", true);
+            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
 
             // The app should now be available for rollback.
-            assertTrue(rm.getPackagesWithAvailableRollbacks().contains(TEST_APP_PACKAGE_NAME));
-            RollbackInfo rollback = rm.getAvailableRollback(TEST_APP_PACKAGE_NAME);
+            assertTrue(rm.getPackagesWithAvailableRollbacks().contains(TEST_APP_A));
+            RollbackInfo rollback = rm.getAvailableRollback(TEST_APP_A);
             assertNotNull(rollback);
-            assertEquals(TEST_APP_PACKAGE_NAME, rollback.targetPackage.packageName);
+            assertEquals(TEST_APP_A, rollback.targetPackage.packageName);
             assertEquals(2, rollback.targetPackage.higherVersion.versionCode);
             assertEquals(1, rollback.targetPackage.lowerVersion.versionCode);
 
@@ -199,27 +200,27 @@
             rm.reloadPersistedData();
 
             // The app should still be available for rollback.
-            assertTrue(rm.getPackagesWithAvailableRollbacks().contains(TEST_APP_PACKAGE_NAME));
-            rollback = rm.getAvailableRollback(TEST_APP_PACKAGE_NAME);
+            assertTrue(rm.getPackagesWithAvailableRollbacks().contains(TEST_APP_A));
+            rollback = rm.getAvailableRollback(TEST_APP_A);
             assertNotNull(rollback);
-            assertEquals(TEST_APP_PACKAGE_NAME, rollback.targetPackage.packageName);
+            assertEquals(TEST_APP_A, rollback.targetPackage.packageName);
             assertEquals(2, rollback.targetPackage.higherVersion.versionCode);
             assertEquals(1, rollback.targetPackage.lowerVersion.versionCode);
 
             // Roll back the app.
             RollbackTestUtils.rollback(rollback);
-            assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_PACKAGE_NAME));
+            assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
 
             // Verify the recent rollback has been recorded.
             rollback = null;
             for (RollbackInfo r : rm.getRecentlyExecutedRollbacks()) {
-                if (TEST_APP_PACKAGE_NAME.equals(r.targetPackage.packageName)) {
+                if (TEST_APP_A.equals(r.targetPackage.packageName)) {
                     assertNull(rollback);
                     rollback = r;
                 }
             }
             assertNotNull(rollback);
-            assertEquals(TEST_APP_PACKAGE_NAME, rollback.targetPackage.packageName);
+            assertEquals(TEST_APP_A, rollback.targetPackage.packageName);
             assertEquals(2, rollback.targetPackage.higherVersion.versionCode);
             assertEquals(1, rollback.targetPackage.lowerVersion.versionCode);
 
@@ -229,13 +230,13 @@
             // Verify the recent rollback is still recorded.
             rollback = null;
             for (RollbackInfo r : rm.getRecentlyExecutedRollbacks()) {
-                if (TEST_APP_PACKAGE_NAME.equals(r.targetPackage.packageName)) {
+                if (TEST_APP_A.equals(r.targetPackage.packageName)) {
                     assertNull(rollback);
                     rollback = r;
                 }
             }
             assertNotNull(rollback);
-            assertEquals(TEST_APP_PACKAGE_NAME, rollback.targetPackage.packageName);
+            assertEquals(TEST_APP_A, rollback.targetPackage.packageName);
             assertEquals(2, rollback.targetPackage.higherVersion.versionCode);
             assertEquals(1, rollback.targetPackage.lowerVersion.versionCode);
         } finally {
@@ -256,25 +257,25 @@
                     Manifest.permission.MANAGE_ROLLBACKS);
 
             RollbackManager rm = RollbackTestUtils.getRollbackManager();
-            RollbackTestUtils.uninstall("com.android.tests.rollback.testapp");
-            RollbackTestUtils.install("RollbackTestAppV1.apk", false);
-            RollbackTestUtils.install("RollbackTestAppV2.apk", true);
-            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_PACKAGE_NAME));
+            RollbackTestUtils.uninstall(TEST_APP_A);
+            RollbackTestUtils.install("RollbackTestAppAv1.apk", false);
+            RollbackTestUtils.install("RollbackTestAppAv2.apk", true);
+            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
 
             // The app should now be available for rollback.
-            assertTrue(rm.getPackagesWithAvailableRollbacks().contains(TEST_APP_PACKAGE_NAME));
-            RollbackInfo rollback = rm.getAvailableRollback(TEST_APP_PACKAGE_NAME);
+            assertTrue(rm.getPackagesWithAvailableRollbacks().contains(TEST_APP_A));
+            RollbackInfo rollback = rm.getAvailableRollback(TEST_APP_A);
             assertNotNull(rollback);
-            assertEquals(TEST_APP_PACKAGE_NAME, rollback.targetPackage.packageName);
+            assertEquals(TEST_APP_A, rollback.targetPackage.packageName);
             assertEquals(2, rollback.targetPackage.higherVersion.versionCode);
             assertEquals(1, rollback.targetPackage.lowerVersion.versionCode);
 
             // Expire the rollback.
-            rm.expireRollbackForPackage(TEST_APP_PACKAGE_NAME);
+            rm.expireRollbackForPackage(TEST_APP_A);
 
             // The rollback should no longer be available.
-            assertNull(rm.getAvailableRollback(TEST_APP_PACKAGE_NAME));
-            assertFalse(rm.getPackagesWithAvailableRollbacks().contains(TEST_APP_PACKAGE_NAME));
+            assertNull(rm.getAvailableRollback(TEST_APP_A));
+            assertFalse(rm.getPackagesWithAvailableRollbacks().contains(TEST_APP_A));
         } finally {
             RollbackTestUtils.dropShellPermissionIdentity();
         }
@@ -285,10 +286,9 @@
     // Calls into the test app to process user data.
     // Asserts if the user data could not be processed or was version
     // incompatible with the previously processed user data.
-    private void processUserData() throws Exception {
+    private void processUserData(String packageName) throws Exception {
         Intent intent = new Intent();
-        intent.setComponent(new ComponentName(
-                    "com.android.tests.rollback.testapp",
+        intent.setComponent(new ComponentName(packageName,
                     "com.android.tests.rollback.testapp.ProcessUserData"));
         Context context = InstrumentationRegistry.getContext();
 
@@ -339,16 +339,16 @@
                     Manifest.permission.DELETE_PACKAGES,
                     Manifest.permission.MANAGE_ROLLBACKS);
 
-            RollbackTestUtils.uninstall("com.android.tests.rollback.testapp");
+            RollbackTestUtils.uninstall(TEST_APP_A);
             RollbackTestUtils.install("RollbackTestAppV1.apk", false);
-            processUserData();
+            processUserData(TEST_APP_A);
             RollbackTestUtils.install("RollbackTestAppV2.apk", true);
-            processUserData();
+            processUserData(TEST_APP_A);
 
             RollbackManager rm = RollbackTestUtils.getRollbackManager();
-            RollbackInfo rollback = rm.getAvailableRollback(TEST_APP_PACKAGE_NAME);
+            RollbackInfo rollback = rm.getAvailableRollback(TEST_APP_A);
             RollbackTestUtils.rollback(rollback);
-            processUserData();
+            processUserData(TEST_APP_A);
         } finally {
             RollbackTestUtils.dropShellPermissionIdentity();
         }
@@ -380,6 +380,58 @@
     }
 
     /**
+     * Regression test for rollback in the case when multiple apps are
+     * available for rollback at the same time.
+     */
+    @Test
+    public void testMultipleRollbackAvailable() throws Exception {
+        try {
+            RollbackTestUtils.adoptShellPermissionIdentity(
+                    Manifest.permission.INSTALL_PACKAGES,
+                    Manifest.permission.DELETE_PACKAGES,
+                    Manifest.permission.MANAGE_ROLLBACKS);
+            RollbackManager rm = RollbackTestUtils.getRollbackManager();
+
+            // Prep installation of the test apps.
+            RollbackTestUtils.uninstall(TEST_APP_A);
+            RollbackTestUtils.install("RollbackTestAppAv1.apk", false);
+            RollbackTestUtils.install("RollbackTestAppAv2.apk", true);
+            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+
+            RollbackTestUtils.uninstall(TEST_APP_B);
+            RollbackTestUtils.install("RollbackTestAppBv1.apk", false);
+            RollbackTestUtils.install("RollbackTestAppBv2.apk", true);
+            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_B));
+
+            // Both test apps should now be available for rollback, and the
+            // targetPackage returned for rollback should be correct.
+            RollbackInfo rollbackA = rm.getAvailableRollback(TEST_APP_A);
+            assertNotNull(rollbackA);
+            assertEquals(TEST_APP_A, rollbackA.targetPackage.packageName);
+
+            RollbackInfo rollbackB = rm.getAvailableRollback(TEST_APP_B);
+            assertNotNull(rollbackB);
+            assertEquals(TEST_APP_B, rollbackB.targetPackage.packageName);
+
+            // Executing rollback should roll back the correct package.
+            RollbackTestUtils.rollback(rollbackA);
+            assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_B));
+
+            RollbackTestUtils.uninstall(TEST_APP_A);
+            RollbackTestUtils.install("RollbackTestAppAv1.apk", false);
+            RollbackTestUtils.install("RollbackTestAppAv2.apk", true);
+            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+
+            RollbackTestUtils.rollback(rollbackB);
+            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+            assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_B));
+        } finally {
+            RollbackTestUtils.dropShellPermissionIdentity();
+        }
+    }
+
+    /**
      * Test that the MANAGE_ROLLBACKS permission is required to call
      * RollbackManager APIs.
      */
@@ -390,7 +442,7 @@
         RollbackManager rm = RollbackTestUtils.getRollbackManager();
 
         try {
-            rm.getAvailableRollback(TEST_APP_PACKAGE_NAME);
+            rm.getAvailableRollback(TEST_APP_A);
             fail("expected SecurityException");
         } catch (SecurityException e) {
             // Expected.
@@ -427,7 +479,7 @@
         }
 
         try {
-            rm.expireRollbackForPackage(TEST_APP_PACKAGE_NAME);
+            rm.expireRollbackForPackage(TEST_APP_A);
             fail("expected SecurityException");
         } catch (SecurityException e) {
             // Expected.