/*
 * Copyright (C) 2019 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 com.android.cts.rollback;

import static com.android.cts.rollback.lib.RollbackInfoSubject.assertThat;
import static com.android.cts.rollback.lib.RollbackUtils.getRollbackManager;

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

import static org.junit.Assert.fail;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.rollback.RollbackInfo;
import android.content.rollback.RollbackManager;
import android.provider.DeviceConfig;

import androidx.test.InstrumentationRegistry;

import com.android.cts.install.lib.Install;
import com.android.cts.install.lib.InstallUtils;
import com.android.cts.install.lib.LocalIntentSender;
import com.android.cts.install.lib.TestApp;
import com.android.cts.install.lib.Uninstall;
import com.android.cts.rollback.lib.Rollback;
import com.android.cts.rollback.lib.RollbackBroadcastReceiver;
import com.android.cts.rollback.lib.RollbackUtils;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

import java.io.IOException;
import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * CTS Tests for RollbackManager APIs.
 */
@RunWith(JUnit4.class)
public class RollbackManagerTest {
    // TODO: use PackageManager.RollbackDataPolicy.* when they are system API
    private static final int ROLLBACK_DATA_POLICY_RESTORE = 0;
    private static final int ROLLBACK_DATA_POLICY_WIPE = 1;

    private static final String PROPERTY_ENABLE_ROLLBACK_TIMEOUT_MILLIS = "enable_rollback_timeout";

    /**
     * Adopts common permissions needed to test rollbacks and uninstalls the
     * test apps.
     */
    @Before
    public void setup() throws InterruptedException, IOException {
        InstrumentationRegistry.getInstrumentation().getUiAutomation()
                .adoptShellPermissionIdentity(
                    Manifest.permission.INSTALL_PACKAGES,
                    Manifest.permission.DELETE_PACKAGES,
                    Manifest.permission.MANAGE_ROLLBACKS,
                    Manifest.permission.TEST_MANAGE_ROLLBACKS,
                    Manifest.permission.READ_DEVICE_CONFIG,
                    Manifest.permission.WRITE_DEVICE_CONFIG,
                    Manifest.permission.FORCE_STOP_PACKAGES,
                    Manifest.permission.SET_TIME);

        Uninstall.packages(TestApp.A, TestApp.B, TestApp.C);
    }

    /**
     * Drops adopted shell permissions and uninstalls the test apps.
     */
    @After
    public void teardown() throws InterruptedException, IOException {
        Uninstall.packages(TestApp.A, TestApp.B, TestApp.C);

        InstrumentationRegistry.getInstrumentation().getUiAutomation()
                .dropShellPermissionIdentity();
    }

    /**
     * Test basic rollbacks.
     */
    @Test
    public void testBasic() throws Exception {
        Install.single(TestApp.A1).commit();
        assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
        RollbackUtils.waitForRollbackGone(
                () -> getRollbackManager().getAvailableRollbacks(), TestApp.A);
        RollbackUtils.waitForRollbackGone(
                () -> getRollbackManager().getRecentlyCommittedRollbacks(), TestApp.A);

        Install.single(TestApp.A2).setEnableRollback().commit();
        assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
        InstallUtils.processUserData(TestApp.A);
        RollbackInfo available = RollbackUtils.waitForAvailableRollback(TestApp.A);
        assertThat(available).isNotStaged();
        assertThat(available).packagesContainsExactly(
                Rollback.from(TestApp.A2).to(TestApp.A1));
        assertThat(RollbackUtils.getCommittedRollback(TestApp.A)).isNull();

        RollbackUtils.rollback(available.getRollbackId(), TestApp.A2);
        assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
        InstallUtils.processUserData(TestApp.A);
        RollbackUtils.waitForUnavailableRollback(TestApp.A);
        RollbackInfo committed = RollbackUtils.getCommittedRollback(TestApp.A);
        assertThat(committed).isNotNull();
        assertThat(committed).hasRollbackId(available.getRollbackId());
        assertThat(committed).isNotStaged();
        assertThat(committed).packagesContainsExactly(
                Rollback.from(TestApp.A2).to(TestApp.A1));
        assertThat(committed).causePackagesContainsExactly(TestApp.A2);
    }

    /**
     * Tests rollback of multi-package installs is implemented.
     */
    @Test
    public void testBasic_MultiPackage() throws Exception {
        // Prep installation of the test apps.
        Install.multi(TestApp.A1, TestApp.B1).commit();
        Install.multi(TestApp.A2, TestApp.B2).setEnableRollback().commit();
        assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
        assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(2);

        // TestApp.A should now be available for rollback.
        RollbackInfo rollback = RollbackUtils.waitForAvailableRollback(TestApp.A);
        assertThat(rollback).isNotNull();
        assertThat(rollback).packagesContainsExactly(
                Rollback.from(TestApp.A2).to(TestApp.A1),
                Rollback.from(TestApp.B2).to(TestApp.B1));

        // Rollback the app. It should cause both test apps to be rolled back.
        RollbackUtils.rollback(rollback.getRollbackId());
        assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
        assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(1);

        // We should see recent rollbacks listed for both A and B.
        RollbackInfo rollbackA = RollbackUtils.getCommittedRollback(TestApp.A);
        RollbackInfo rollbackB = RollbackUtils.getCommittedRollback(TestApp.B);
        assertThat(rollbackA).packagesContainsExactly(
                Rollback.from(TestApp.A2).to(TestApp.A1),
                Rollback.from(TestApp.B2).to(TestApp.B1));
        assertThat(rollbackA).hasRollbackId(rollback.getRollbackId());
        assertThat(rollbackB).hasRollbackId(rollback.getRollbackId());
    }

    /**
     * Tests rollbacks are properly persisted.
     */
    @Test
    public void testSingleRollbackPersistence() throws Exception {
        RollbackManager rm = RollbackUtils.getRollbackManager();

        Install.single(TestApp.A1).commit();
        Install.single(TestApp.A2).setEnableRollback().commit();
        RollbackInfo rollbackA = RollbackUtils.waitForAvailableRollback(TestApp.A);
        assertThat(rollbackA).isNotNull();

        // Check the available rollback is persisted correctly
        rm.reloadPersistedData();
        rollbackA = RollbackUtils.getAvailableRollback(TestApp.A);
        assertThat(rollbackA).packagesContainsExactly(Rollback.from(TestApp.A2).to(TestApp.A1));

        // Rollback the app
        TestApp cause = new TestApp("Foo", "com.android.tests.rollback.testapp.Foo",
                /*versionCode*/ 42, /*isApex*/ false);
        RollbackUtils.rollback(rollbackA.getRollbackId(), cause);
        RollbackInfo committed = RollbackUtils.getCommittedRollback(TestApp.A);
        assertThat(committed).isNotNull();

        // Check the committed rollback is persisted correctly
        rm.reloadPersistedData();
        committed = RollbackUtils.getCommittedRollback(TestApp.A);
        assertThat(committed).hasRollbackId(rollbackA.getRollbackId());
        assertThat(committed).isNotStaged();
        assertThat(committed).packagesContainsExactly(Rollback.from(TestApp.A2).to(TestApp.A1));
        assertThat(committed).causePackagesContainsExactly(cause);
    }

    /**
     * Tests rollbacks are properly persisted.
     */
    @Test
    public void testMultiRollbackPersistence() throws Exception {
        RollbackManager rm = RollbackUtils.getRollbackManager();

        Install.multi(TestApp.A1, TestApp.B1).commit();
        Install.multi(TestApp.A2, TestApp.B2).setEnableRollback().commit();
        RollbackInfo rollbackA = RollbackUtils.waitForAvailableRollback(TestApp.A);
        RollbackInfo rollbackB = RollbackUtils.waitForAvailableRollback(TestApp.B);
        assertThat(rollbackA).isNotNull();
        assertThat(rollbackB).isNotNull();

        // Check the available rollback is persisted correctly
        rm.reloadPersistedData();
        rollbackA = RollbackUtils.getAvailableRollback(TestApp.A);
        rollbackB = RollbackUtils.getAvailableRollback(TestApp.B);
        assertThat(rollbackB).hasRollbackId(rollbackA.getRollbackId());
        assertThat(rollbackA).packagesContainsExactly(
                Rollback.from(TestApp.A2).to(TestApp.A1),
                Rollback.from(TestApp.B2).to(TestApp.B1));

        // Rollback the app
        RollbackUtils.rollback(rollbackA.getRollbackId());
        RollbackInfo committedA = RollbackUtils.getCommittedRollback(TestApp.A);
        RollbackInfo committedB = RollbackUtils.getCommittedRollback(TestApp.B);
        assertThat(committedA).isNotNull();
        assertThat(committedB).isNotNull();

        // Check the committed rollback is persisted correctly
        rm.reloadPersistedData();
        committedA = RollbackUtils.getCommittedRollback(TestApp.A);
        committedB = RollbackUtils.getCommittedRollback(TestApp.B);
        assertThat(committedA).hasRollbackId(rollbackA.getRollbackId());
        assertThat(committedB).hasRollbackId(rollbackA.getRollbackId());
        assertThat(committedA).isNotStaged();
        assertThat(committedA).packagesContainsExactly(
                Rollback.from(TestApp.A2).to(TestApp.A1),
                Rollback.from(TestApp.B2).to(TestApp.B1));
    }

    /**
     * Tests that the MANAGE_ROLLBACKS permission is required to call
     * RollbackManager APIs.
     */
    @Test
    public void testManageRollbacksPermission() throws Exception {
        // We shouldn't be allowed to call any of the RollbackManager APIs
        // without the MANAGE_ROLLBACKS permission.
        InstallUtils.dropShellPermissionIdentity();
        RollbackManager rm = RollbackUtils.getRollbackManager();

        try {
            rm.getAvailableRollbacks();
            fail("expected SecurityException");
        } catch (SecurityException e) {
            // Expected.
        }

        try {
            rm.getRecentlyCommittedRollbacks();
            fail("expected SecurityException");
        } catch (SecurityException e) {
            // Expected.
        }

        try {
            LocalIntentSender sender = new LocalIntentSender();
            rm.commitRollback(0, Collections.emptyList(), sender.getIntentSender());
            fail("expected SecurityException");
        } catch (SecurityException e) {
            // Expected.
        }

        try {
            rm.reloadPersistedData();
            fail("expected SecurityException");
        } catch (SecurityException e) {
            // Expected.
        }

        try {
            rm.expireRollbackForPackage(TestApp.A);
            fail("expected SecurityException");
        } catch (SecurityException e) {
            // Expected.
        }
    }

    /**
     * Tests that you cannot enable rollback for a package without the
     * MANAGE_ROLLBACKS permission.
     */
    @Test
    public void testEnableRollbackPermission() throws Exception {
        InstallUtils.adoptShellPermissionIdentity(
                Manifest.permission.INSTALL_PACKAGES,
                Manifest.permission.DELETE_PACKAGES);

        Install.single(TestApp.A1).commit();
        Install.single(TestApp.A2).setEnableRollback().commit();

        // We expect v2 of the app was installed, but rollback has not
        // been enabled.
        assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
        InstallUtils.adoptShellPermissionIdentity(
                Manifest.permission.MANAGE_ROLLBACKS,
                Manifest.permission.INSTALL_PACKAGES,
                Manifest.permission.DELETE_PACKAGES);
        assertThat(RollbackUtils.getAvailableRollback(TestApp.A)).isNull();
    }

    /**
     * Tests that you cannot enable rollback for a non-module package when
     * holding the MANAGE_ROLLBACKS permission without TEST_MANAGE_ROLLBACKS.
     */
    @Test
    public void testNonModuleEnableRollback() throws Exception {
        InstallUtils.adoptShellPermissionIdentity(
                Manifest.permission.INSTALL_PACKAGES,
                Manifest.permission.DELETE_PACKAGES,
                Manifest.permission.MANAGE_ROLLBACKS);

        Install.single(TestApp.A1).commit();
        Install.single(TestApp.A2).setEnableRollback().commit();

        // We expect v2 of the app was installed, but rollback has not
        // been enabled because the test app is not a module.
        assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
        assertThat(RollbackUtils.getAvailableRollback(TestApp.A)).isNull();
    }

    /**
     * Tests failure to enable rollback for multi-package installs.
     * If any one of the packages fail to enable rollback, we shouldn't enable
     * rollback for any package.
     */
    @Test
    public void testMultiPackageEnableFail() throws Exception {
        Install.single(TestApp.A1).commit();
        // We should fail to enable rollback here because TestApp B is not
        // already installed.
        Install.multi(TestApp.A2, TestApp.B2).setEnableRollback().commit();

        assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
        assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(2);

        assertThat(RollbackUtils.getAvailableRollback(TestApp.A)).isNull();
        assertThat(RollbackUtils.getAvailableRollback(TestApp.B)).isNull();
    }

    @Test
    public void testGetRollbackDataPolicy() throws Exception {
        final int rollBackDataPolicy = ROLLBACK_DATA_POLICY_WIPE;

        Install.single(TestApp.A1).commit();
        assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);

        // Enable rollback with rollBackDataPolicy
        final int sessionId = Install.single(TestApp.A2).setEnableRollback(
                rollBackDataPolicy).createSession();

        try {
            assertThat(InstallUtils.getPackageInstaller().getSessionInfo(
                    sessionId).getRollbackDataPolicy()).isEqualTo(rollBackDataPolicy);
        } finally {
            // Abandon the session
            InstallUtils.getPackageInstaller().abandonSession(sessionId);
        }
    }

    /**
     * Test that flags are cleared when a rollback is committed.
     */
    @Test
    public void testRollbackClearsFlags() throws Exception {
        Install.single(TestApp.A1).commit();
        assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
        RollbackUtils.waitForRollbackGone(
                () -> getRollbackManager().getAvailableRollbacks(), TestApp.A);

        Install.single(TestApp.A2).setEnableRollback().commit();
        assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
        RollbackInfo available = RollbackUtils.waitForAvailableRollback(TestApp.A);

        DeviceConfig.setProperty("configuration", "namespace_to_package_mapping",
                "testspace:" + TestApp.A, false);
        DeviceConfig.setProperty("testspace", "flagname", "hello", false);
        DeviceConfig.setProperty("testspace", "another", "12345", false);
        assertThat(DeviceConfig.getProperties("testspace").getKeyset()).hasSize(2);

        RollbackUtils.rollback(available.getRollbackId(), TestApp.A2);
        assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);

        assertThat(DeviceConfig.getProperties("testspace").getKeyset()).hasSize(0);
    }

    /**
     * Tests an app can be rolled back to the previous signing key.
     *
     * <p>The rollback capability in the signing lineage allows an app to be updated to an APK
     * signed with a previous signing key in the lineage; however this often defeats the purpose
     * of key rotation as a compromised key could then be used to roll an app back to the previous
     * key. To avoid requiring the rollback capability to support APK rollbacks the PackageManager
     * allows an app to be rolled back to the previous signing key if the rollback install reason
     * is set.
     */
    @Test
    public void testRollbackAfterKeyRotation() throws Exception {
        Install.single(TestApp.AOriginal1).commit();
        assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);

        Install.single(TestApp.ARotated2).setEnableRollback().commit();
        assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);

        RollbackInfo available = RollbackUtils.waitForAvailableRollback(TestApp.A);
        RollbackUtils.rollback(available.getRollbackId(), TestApp.ARotated2);
        assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
    }

    /**
     * Test we can't enable rollback for non-allowlisted app without
     * TEST_MANAGE_ROLLBACKS permission
     */
    @Test
    public void testNonRollbackAllowlistedApp() throws Exception {
        InstallUtils.dropShellPermissionIdentity();
        InstallUtils.adoptShellPermissionIdentity(
                Manifest.permission.INSTALL_PACKAGES,
                Manifest.permission.DELETE_PACKAGES,
                Manifest.permission.MANAGE_ROLLBACKS);

        Install.single(TestApp.A1).commit();
        assertThat(RollbackUtils.getAvailableRollback(TestApp.A)).isNull();

        Install.single(TestApp.A2).setEnableRollback().commit();
        Thread.sleep(TimeUnit.SECONDS.toMillis(2));
        assertThat(RollbackUtils.getAvailableRollback(TestApp.A)).isNull();
    }

    /**
     * Tests user data is restored according to the preset rollback data policy.
     */
    @Test
    public void testRollbackDataPolicy() throws Exception {
        Install.multi(TestApp.A1, TestApp.B1, TestApp.C1).commit();
        // Write user data version = 1
        InstallUtils.processUserData(TestApp.A);
        InstallUtils.processUserData(TestApp.B);
        InstallUtils.processUserData(TestApp.C);

        Install a2 = Install.single(TestApp.A2)
                .setEnableRollback(PackageManager.ROLLBACK_DATA_POLICY_WIPE);
        Install b2 = Install.single(TestApp.B2)
                .setEnableRollback(PackageManager.ROLLBACK_DATA_POLICY_RESTORE);
        Install c2 = Install.single(TestApp.C2)
                .setEnableRollback(PackageManager.ROLLBACK_DATA_POLICY_RETAIN);
        Install.multi(a2, b2, c2).setEnableRollback().commit();
        // Write user data version = 2
        InstallUtils.processUserData(TestApp.A);
        InstallUtils.processUserData(TestApp.B);
        InstallUtils.processUserData(TestApp.C);

        RollbackInfo info = RollbackUtils.getAvailableRollback(TestApp.A);
        RollbackUtils.rollback(info.getRollbackId());
        // Read user data version from userdata.txt
        // A's user data version is -1 for user data is wiped.
        // B's user data version is 1 for user data is restored.
        // C's user data version is 2 for user data is retained.
        assertThat(InstallUtils.getUserDataVersion(TestApp.A)).isEqualTo(-1);
        assertThat(InstallUtils.getUserDataVersion(TestApp.B)).isEqualTo(1);
        assertThat(InstallUtils.getUserDataVersion(TestApp.C)).isEqualTo(2);
    }

    /**
     * Tests user data is restored according to the rollback data policy defined in the manifest.
     */
    @Test
    public void testRollbackDataPolicy_Manifest() throws Exception {
        Install.multi(TestApp.A1, TestApp.B1, TestApp.C1).commit();
        // Write user data version = 1
        InstallUtils.processUserData(TestApp.A);
        InstallUtils.processUserData(TestApp.B);
        InstallUtils.processUserData(TestApp.C);

        Install a2 = Install.single(TestApp.ARollbackWipe2).setEnableRollback();
        Install b2 = Install.single(TestApp.BRollbackRestore2).setEnableRollback();
        Install c2 = Install.single(TestApp.CRollbackRetain2).setEnableRollback();
        Install.multi(a2, b2, c2).setEnableRollback().commit();
        // Write user data version = 2
        InstallUtils.processUserData(TestApp.A);
        InstallUtils.processUserData(TestApp.B);
        InstallUtils.processUserData(TestApp.C);

        RollbackInfo info = RollbackUtils.getAvailableRollback(TestApp.A);
        RollbackUtils.rollback(info.getRollbackId());
        // Read user data version from userdata.txt
        // A's user data version is -1 for user data is wiped.
        // B's user data version is 1 for user data is restored.
        // C's user data version is 2 for user data is retained.
        assertThat(InstallUtils.getUserDataVersion(TestApp.A)).isEqualTo(-1);
        assertThat(InstallUtils.getUserDataVersion(TestApp.B)).isEqualTo(1);
        assertThat(InstallUtils.getUserDataVersion(TestApp.C)).isEqualTo(2);
    }

    /**
     * Test explicit expiration of rollbacks.
     * Does not test the scheduling aspects of rollback expiration.
     */
    @Test
    public void testRollbackExpiration() throws Exception {
        Install.single(TestApp.A1).commit();
        Install.single(TestApp.A2).setEnableRollback().commit();
        RollbackUtils.waitForAvailableRollback(TestApp.A);

        // Expire the rollback.
        RollbackUtils.getRollbackManager().expireRollbackForPackage(TestApp.A);

        // The rollback should no longer be available.
        assertThat(RollbackUtils.getAvailableRollback(TestApp.A)).isNull();
    }

    /**
     * Test restrictions on rollback broadcast sender.
     * A random app should not be able to send a ROLLBACK_COMMITTED broadcast.
     */
    @Test
    public void testRollbackBroadcastRestrictions() throws Exception {
        RollbackBroadcastReceiver broadcastReceiver = new RollbackBroadcastReceiver();
        Intent broadcast = new Intent(Intent.ACTION_ROLLBACK_COMMITTED);
        try {
            InstrumentationRegistry.getContext().sendBroadcast(broadcast);
            fail("Succeeded in sending restricted broadcast from app context.");
        } catch (SecurityException se) {
            // Expected behavior.
        }

        // Confirm that we really haven't received the broadcast.
        // TODO: How long to wait for the expected timeout?
        assertThat(broadcastReceiver.poll(5, TimeUnit.SECONDS)).isNull();

        // TODO: Do we need to do this? Do we need to ensure this is always
        // called, even when the test fails?
        broadcastReceiver.unregister();
    }

    /**
     * Test rollback of apks involving splits.
     */
    @Test
    public void testRollbackWithSplits() throws Exception {
        Install.single(TestApp.ASplit1).commit();
        Install.single(TestApp.ASplit2).setEnableRollback().commit();
        RollbackInfo rollback = RollbackUtils.waitForAvailableRollback(TestApp.A);
        assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);

        RollbackUtils.rollback(rollback.getRollbackId());
        assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
    }

    /**
     * Test bad update automatic rollback.
     */
    @Test
    public void testBadUpdateRollback() throws Exception {
        // Prep installation of the test apps.
        Install.single(TestApp.A1).commit();
        Install.single(TestApp.ACrashing2).setEnableRollback().commit();
        assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);

        Install.single(TestApp.B1).commit();
        Install.single(TestApp.B2).setEnableRollback().commit();
        assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(2);

        // Both test apps should now be available for rollback, and the
        // targetPackage returned for rollback should be correct.
        RollbackInfo rollbackA = RollbackUtils.waitForAvailableRollback(TestApp.A);
        assertThat(rollbackA).packagesContainsExactly(Rollback.from(TestApp.A2).to(TestApp.A1));
        RollbackInfo rollbackB = RollbackUtils.waitForAvailableRollback(TestApp.B);
        assertThat(rollbackB).packagesContainsExactly(Rollback.from(TestApp.B2).to(TestApp.B1));

        // Register rollback committed receiver
        RollbackBroadcastReceiver rollbackReceiver = new RollbackBroadcastReceiver();

        // Crash TestApp.A PackageWatchdog#TRIGGER_FAILURE_COUNT times to trigger rollback
        RollbackUtils.sendCrashBroadcast(TestApp.A, 5);

        // Verify we received a broadcast for the rollback.
        assertThat(rollbackReceiver.poll(1, TimeUnit.MINUTES)).isNotNull();

        // TestApp.A is automatically rolled back by the RollbackPackageHealthObserver
        assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
        // Instrumented app is still the package installer
        String installer = InstrumentationRegistry.getContext().getPackageManager()
                .getInstallerPackageName(TestApp.A);
        assertThat(installer).isEqualTo(getClass().getPackageName());
        // TestApp.B is untouched
        assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(2);
    }

    /**
     * Tests we fail to enable rollbacks if enable-rollback times out.
     */
    @Test
    public void testEnableRollbackTimeoutFailsRollback() throws Exception {
        //setting the timeout to a very short amount that will definitely be triggered
        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ROLLBACK,
                PROPERTY_ENABLE_ROLLBACK_TIMEOUT_MILLIS,
                Long.toString(0), false /* makeDefault*/);

        try {
            Install.single(TestApp.A1).commit();
            RollbackUtils.waitForUnavailableRollback(TestApp.A);

            // Block the RollbackManager to make extra sure it will not be
            // able to enable the rollback in time.
            RollbackManager rm = RollbackUtils.getRollbackManager();
            rm.blockRollbackManager(TimeUnit.SECONDS.toMillis(1));
            Install.single(TestApp.A2).setEnableRollback().commit();
            assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);

            // Give plenty of time for RollbackManager to unblock and attempt
            // to make the rollback available before asserting that the
            // rollback was not made available.
            Thread.sleep(TimeUnit.SECONDS.toMillis(2));
            assertThat(RollbackUtils.getAvailableRollback(TestApp.A)).isNull();
        } finally {
            //setting the timeout back to default
            DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ROLLBACK,
                    PROPERTY_ENABLE_ROLLBACK_TIMEOUT_MILLIS,
                    null, false /* makeDefault*/);
        }
    }

    /**
     * Tests we fail to enable rollbacks if enable-rollback times out for any child session.
     */
    @Test
    public void testEnableRollbackTimeoutFailsRollback_MultiPackage() throws Exception {
        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ROLLBACK,
                PROPERTY_ENABLE_ROLLBACK_TIMEOUT_MILLIS,
                Long.toString(5000), false /* makeDefault*/);

        try {
            Install.multi(TestApp.A1, TestApp.B1).commit();
            RollbackUtils.waitForUnavailableRollback(TestApp.A);

            // Block the 2nd session for 10s so it will not be able to enable the rollback in time.
            RollbackManager rm = RollbackUtils.getRollbackManager();
            rm.blockRollbackManager(TimeUnit.SECONDS.toMillis(0));
            rm.blockRollbackManager(TimeUnit.SECONDS.toMillis(10));
            Install.multi(TestApp.A2, TestApp.B2).setEnableRollback().commit();
            assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
            assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(2);

            // Give plenty of time for RollbackManager to unblock and attempt
            // to make the rollback available before asserting that the
            // rollback was not made available.
            Thread.sleep(TimeUnit.SECONDS.toMillis(2));
            assertThat(RollbackUtils.getAvailableRollback(TestApp.A)).isNull();
            assertThat(RollbackUtils.getAvailableRollback(TestApp.B)).isNull();
        } finally {
            //setting the timeout back to default
            DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ROLLBACK,
                    PROPERTY_ENABLE_ROLLBACK_TIMEOUT_MILLIS,
                    null, false /* makeDefault*/);
        }
    }

    /**
     * Test the scheduling aspect of rollback expiration.
     */
    @Test
    public void testRollbackExpiresAfterLifetime() throws Exception {
        long expirationTime = TimeUnit.SECONDS.toMillis(30);
        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ROLLBACK_BOOT,
                RollbackManager.PROPERTY_ROLLBACK_LIFETIME_MILLIS,
                Long.toString(expirationTime), false /* makeDefault*/);

        try {
            Install.single(TestApp.A1).commit();
            Install.single(TestApp.A2).setEnableRollback().commit();
            RollbackUtils.waitForAvailableRollback(TestApp.A);

            // Give it a little more time, but still not long enough to expire
            Thread.sleep(expirationTime / 2);
            assertThat(RollbackUtils.getAvailableRollback(TestApp.A)).isNotNull();

            // Check that the data has expired after the expiration time (with a buffer of 1 second)
            Thread.sleep(expirationTime / 2 + TimeUnit.SECONDS.toMillis(1));
            assertThat(RollbackUtils.getAvailableRollback(TestApp.A)).isNull();
        } finally {
            // Restore default config values
            DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ROLLBACK_BOOT,
                    RollbackManager.PROPERTY_ROLLBACK_LIFETIME_MILLIS,
                    null, false /* makeDefault*/);
        }
    }

    /**
     * Test that available rollbacks should expire correctly when the property
     * {@link RollbackManager#PROPERTY_ROLLBACK_LIFETIME_MILLIS} is changed
     */
    @Test
    public void testRollbackExpiresWhenLifetimeChanges() throws Exception {
        Install.single(TestApp.A1).commit();
        Install.single(TestApp.A2).setEnableRollback().commit();
        RollbackUtils.waitForAvailableRollback(TestApp.A);

        // Change the lifetime to 0 which should expire rollbacks immediately
        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ROLLBACK_BOOT,
                RollbackManager.PROPERTY_ROLLBACK_LIFETIME_MILLIS,
                Long.toString(0), false /* makeDefault*/);

        try {
            RollbackUtils.waitForUnavailableRollback(TestApp.A);
        } finally {
            // Restore default config values
            DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ROLLBACK_BOOT,
                    RollbackManager.PROPERTY_ROLLBACK_LIFETIME_MILLIS,
                    null, false /* makeDefault*/);
        }
    }

    /**
     * Test that changing time on device does not affect the duration of time that we keep
     * rollback available
     */
    @Test
    public void testTimeChangeDoesNotAffectLifetime() throws Exception {
        long expirationTime = TimeUnit.SECONDS.toMillis(30);
        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ROLLBACK_BOOT,
                RollbackManager.PROPERTY_ROLLBACK_LIFETIME_MILLIS,
                Long.toString(expirationTime), false /* makeDefault*/);

        try {
            Install.single(TestApp.A1).commit();
            Install.single(TestApp.A2).setEnableRollback().commit();
            RollbackUtils.waitForAvailableRollback(TestApp.A);
            RollbackUtils.forwardTimeBy(expirationTime);

            try {
                // The rollback should be still available after forwarding time
                assertThat(RollbackUtils.getAvailableRollback(TestApp.A)).isNotNull();
                // The rollback shouldn't expire when half of the expiration time elapses
                Thread.sleep(expirationTime / 2);
                assertThat(RollbackUtils.getAvailableRollback(TestApp.A)).isNotNull();
                // The rollback now should expire
                Thread.sleep(expirationTime / 2 + TimeUnit.SECONDS.toMillis(1));
                assertThat(RollbackUtils.getAvailableRollback(TestApp.A)).isNull();
            } finally {
                RollbackUtils.forwardTimeBy(-expirationTime);
            }
        } finally {
            // Restore default config values
            DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ROLLBACK_BOOT,
                    RollbackManager.PROPERTY_ROLLBACK_LIFETIME_MILLIS,
                    null, false /* makeDefault*/);
        }
    }
}
