/*
 * 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.tests.stagedinstall.host;

import static com.android.cts.shim.lib.ShimPackage.SHIM_APEX_PACKAGE_NAME;

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

import static org.hamcrest.CoreMatchers.endsWith;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeThat;
import static org.junit.Assume.assumeTrue;

import android.cts.install.lib.host.InstallUtilsHost;
import android.platform.test.annotations.LargeTest;

import com.android.apex.ApexInfo;
import com.android.apex.XmlParser;
import com.android.ddmlib.Log;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;


import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;
import org.junit.runner.RunWith;

import java.io.File;
import java.io.FileInputStream;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@RunWith(DeviceJUnit4ClassRunner.class)
public class StagedInstallTest extends BaseHostJUnit4Test {

    private static final String TAG = "StagedInstallTest";

    private static final String PACKAGE_NAME = "com.android.tests.stagedinstall";

    private static final String BROADCAST_RECEIVER_COMPONENT = PACKAGE_NAME + "/"
            + PACKAGE_NAME + ".LauncherActivity";

    private final InstallUtilsHost mHostUtils = new InstallUtilsHost(this);

    private String mDefaultLauncher = null;

    @Rule
    public final FailedTestLogHook mFailedTestLogHook = new FailedTestLogHook(this);

    /**
     * Runs the given phase of a test by calling into the device.
     * Throws an exception if the test phase fails.
     * <p>
     * For example, <code>runPhase("testInstallStagedApkCommit");</code>
     */
    private void runPhase(String phase) throws Exception {
        assertThat(runDeviceTests(PACKAGE_NAME,
                "com.android.tests.stagedinstall.StagedInstallTest",
                phase)).isTrue();
    }

    // We do not assert the success of cleanup phase since it might fail due to flaky reasons.
    private void cleanUp() throws Exception {
        try {
            runDeviceTests(PACKAGE_NAME,
                    "com.android.tests.stagedinstall.StagedInstallTest",
                    "cleanUp");
        } catch (AssertionError e) {
            Log.e(TAG, e);
        }
    }

    @Before
    public void setUp() throws Exception {
        cleanUp();
        mHostUtils.uninstallShimApexIfNecessary();
        storeDefaultLauncher();
    }

    @After
    public void tearDown() throws Exception {
        cleanUp();
        mHostUtils.uninstallShimApexIfNecessary();
        setDefaultLauncher(mDefaultLauncher);
    }

    /**
     * Tests for staged install involving only one apk.
     */
    @Test
    @LargeTest
    public void testInstallStagedApk() throws Exception {
        assumeSystemUser();

        setDefaultLauncher(BROADCAST_RECEIVER_COMPONENT);
        runPhase("testInstallStagedApk_Commit");
        getDevice().reboot();
        runPhase("testInstallStagedApk_VerifyPostReboot");
        runPhase("testInstallStagedApk_AbandonSessionIsNoop");
    }

    @Test
    public void testFailInstallIfNoPermission() throws Exception {
        runPhase("testFailInstallIfNoPermission");
    }

    @Test
    @LargeTest
    public void testAbandonStagedApkBeforeReboot() throws Exception {
        runPhase("testAbandonStagedApkBeforeReboot_CommitAndAbandon");
        getDevice().reboot();
        runPhase("testAbandonStagedApkBeforeReboot_VerifyPostReboot");
    }

    @Test
    @LargeTest
    public void testAbandonStagedApkBeforeReady() throws Exception {
        runPhase("testAbandonStagedApkBeforeReady_CommitAndAbandon");
        getDevice().reboot();
        runPhase("testAbandonStagedApkBeforeReady_VerifyPostReboot");
    }

    @Test
    public void testStageAnotherSessionImmediatelyAfterAbandon() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());
        runPhase("testStageAnotherSessionImmediatelyAfterAbandon");
    }

    @Test
    public void testStageAnotherSessionImmediatelyAfterAbandonMultiPackage() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());
        runPhase("testStageAnotherSessionImmediatelyAfterAbandonMultiPackage");
    }

    @Test
    public void testNoSessionUpdatedBroadcastSentForStagedSessionAbandon() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());
        runPhase("testNoSessionUpdatedBroadcastSentForStagedSessionAbandon");
    }

    @Test
    @LargeTest
    public void testInstallMultipleStagedApks() throws Exception {
        assumeSystemUser();

        setDefaultLauncher(BROADCAST_RECEIVER_COMPONENT);
        runPhase("testInstallMultipleStagedApks_Commit");
        getDevice().reboot();
        runPhase("testInstallMultipleStagedApks_VerifyPostReboot");
    }

    private void assumeSystemUser() throws Exception {
        String systemUser = "0";
        assumeThat("Current user is not system user",
                getDevice().executeShellCommand("am get-current-user").trim(), equalTo(systemUser));
    }

    @Test
    public void testGetActiveStagedSessions() throws Exception {
        assumeTrue("Device does not support file-system checkpoint",
                mHostUtils.isCheckpointSupported());

        runPhase("testGetActiveStagedSessions");
    }

    /**
     * Verifies that active staged session fulfils conditions stated at
     * {@link PackageInstaller.SessionInfo#isStagedSessionActive}
     */
    @Test
    public void testIsStagedSessionActive() throws Exception {
        runPhase("testIsStagedSessionActive");
    }

    @Test
    public void testGetActiveStagedSessionsNoSessionActive() throws Exception {
        runPhase("testGetActiveStagedSessionsNoSessionActive");
    }

    @Test
    public void testGetActiveStagedSessions_MultiApkSession() throws Exception {
        assumeTrue("Device does not support file-system checkpoint",
                mHostUtils.isCheckpointSupported());

        runPhase("testGetActiveStagedSessions_MultiApkSession");
    }

    @Test
    public void testStagedInstallDowngrade_DowngradeNotRequested_Fails() throws Exception {
        runPhase("testStagedInstallDowngrade_DowngradeNotRequested_Fails_Commit");
    }

    @Test
    @LargeTest
    public void testStagedInstallDowngrade_DowngradeRequested_DebugBuild() throws Exception {
        assumeThat(getDevice().getBuildFlavor(), not(endsWith("-user")));

        runPhase("testStagedInstallDowngrade_DowngradeRequested_Commit");
        getDevice().reboot();
        runPhase("testStagedInstallDowngrade_DowngradeRequested_DebugBuild_VerifyPostReboot");
    }

    @Test
    public void testStagedInstallDowngrade_DowngradeRequested_UserBuild() throws Exception {
        assumeThat(getDevice().getBuildFlavor(), endsWith("-user"));
        assumeFalse("Device is debuggable", isDebuggable());

        runPhase("testStagedInstallDowngrade_DowngradeRequested_Fails_Commit");
    }

    @Test
    public void testShimApexShouldPreInstalledIfUpdatingApexIsSupported() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        final ITestDevice.ApexInfo shimApex = mHostUtils.getShimApex().orElseThrow(
                () -> new AssertionError("Can't find " + SHIM_APEX_PACKAGE_NAME)
        );
        assertThat(shimApex.versionCode).isEqualTo(1);
    }

    @Test
    @LargeTest
    public void testInstallStagedApex() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        setDefaultLauncher(BROADCAST_RECEIVER_COMPONENT);
        runPhase("testInstallStagedApex_Commit");
        getDevice().reboot();
        runPhase("testInstallStagedApex_VerifyPostReboot");
    }

    @Test
    // Don't mark as @LargeTest since we want at least one test to install apex during pre-submit.
    public void testInstallStagedApexAndApk() throws Exception {
        assumeSystemUser();
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        setDefaultLauncher(BROADCAST_RECEIVER_COMPONENT);
        runPhase("testInstallStagedApexAndApk_Commit");
        getDevice().reboot();
        runPhase("testInstallStagedApexAndApk_VerifyPostReboot");
    }

    @Test
    public void testsFailsNonStagedApexInstall() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        runPhase("testsFailsNonStagedApexInstall");
    }

    @Test
    public void testInstallStagedNonPreInstalledApex_Fails() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        runPhase("testInstallStagedNonPreInstalledApex_Fails");
    }

    @Test
    public void testInstallStagedDifferentPackageNameWithInstalledApex_Fails() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        runPhase("testInstallStagedDifferentPackageNameWithInstalledApex_Fails");
    }

    @Test
    @LargeTest
    public void testStageApkWithSameNameAsApexShouldFail() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        runPhase("testStageApkWithSameNameAsApexShouldFail_Commit");
        getDevice().reboot();
        runPhase("testStageApkWithSameNameAsApexShouldFail_VerifyPostReboot");
    }

    @Test
    public void testNonStagedInstallApkWithSameNameAsApexShouldFail() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());
        runPhase("testNonStagedInstallApkWithSameNameAsApexShouldFail");
    }

    @Test
    @LargeTest
    public void testStagedInstallDowngradeApex_DowngradeNotRequested_Fails() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        installV3Apex();
        runPhase("testStagedInstallDowngradeApex_DowngradeNotRequested_Fails_Commit");
        getDevice().reboot();
        runPhase("testStagedInstallDowngradeApex_DowngradeNotRequested_Fails_VerifyPostReboot");
    }

    @Test
    @LargeTest
    public void testStagedInstallDowngradeApex_DowngradeRequested_DebugBuild() throws Exception {
        assumeThat(getDevice().getBuildFlavor(), not(endsWith("-user")));
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        installV3Apex();
        runPhase("testStagedInstallDowngradeApex_DowngradeRequested_DebugBuild_Commit");
        getDevice().reboot();
        runPhase("testStagedInstallDowngradeApex_DowngradeRequested_DebugBuild_VerifyPostReboot");
    }

    @Test
    @LargeTest
    public void testStagedInstallDowngradeApex_DowngradeRequested_UserBuild_Fails()
            throws Exception {
        assumeThat(getDevice().getBuildFlavor(), endsWith("-user"));
        assumeFalse("Device is debuggable", isDebuggable());
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        installV3Apex();
        runPhase("testStagedInstallDowngradeApex_DowngradeRequested_UserBuild_Fails_Commit");
        getDevice().reboot();
        runPhase("testStagedInstallDowngradeApex_DowngradeRequested_UserBuild_Fails_"
                + "VerifyPostReboot");
    }

    @Test
    @LargeTest
    public void testStagedInstallDowngradeApexToSystemVersion_DebugBuild() throws Exception {
        assumeThat(getDevice().getBuildFlavor(), not(endsWith("-user")));
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        installV2Apex();
        runPhase("testStagedInstallDowngradeApexToSystemVersion_DebugBuild_Commit");
        getDevice().reboot();
        runPhase("testStagedInstallDowngradeApexToSystemVersion_DebugBuild_VerifyPostReboot");
    }

    @Test
    @LargeTest
    public void testInstallStagedApex_SameGrade() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());
        installV3Apex();
        ApexInfo shim1 =
                readApexInfoList().stream()
                        .filter(a -> a.getModuleName().equals(SHIM_APEX_PACKAGE_NAME))
                        .filter(ApexInfo::getIsActive)
                        .findAny()
                        .orElseThrow(() ->
                                new AssertionError(
                                        "No active version of " + SHIM_APEX_PACKAGE_NAME
                                                + " found in /apex/apex-info-list.xml"));

        installV3Apex();
        ApexInfo shim2 =
                readApexInfoList().stream()
                        .filter(a -> a.getModuleName().equals(SHIM_APEX_PACKAGE_NAME))
                        .filter(ApexInfo::getIsActive)
                        .findAny()
                        .orElseThrow(() ->
                                new AssertionError(
                                        "No active version of " + SHIM_APEX_PACKAGE_NAME
                                                + " found in /apex/apex-info-list.xml"));
        assertThat(shim1.getLastUpdateMillis()).isNotEqualTo(shim2.getLastUpdateMillis());
    }

    @Test
    @LargeTest
    public void testInstallStagedApex_SameGrade_NewOneWins() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        installV2Apex();

        runPhase("testInstallStagedApex_SameGrade_NewOneWins_Commit");
        getDevice().reboot();
        runPhase("testInstallStagedApex_SameGrade_NewOneWins_VerifyPostReboot");
    }

    @Test
    public void testInstallApex_DeviceDoesNotSupportApex_Fails() throws Exception {
        assumeFalse("Device supports updating APEX", mHostUtils.isApexUpdateSupported());

        runPhase("testInstallApex_DeviceDoesNotSupportApex_Fails");
    }

    private void installV2Apex()throws Exception {
        runPhase("testInstallV2Apex_Commit");
        getDevice().reboot();
        runPhase("testInstallV2Apex_VerifyPostReboot");
    }

    private void installV2SignedBobApex() throws Exception {
        runPhase("testInstallV2SignedBobApex_Commit");
        getDevice().reboot();
        runPhase("testInstallV2SignedBobApex_VerifyPostReboot");
    }

    private void installV3Apex()throws Exception {
        runPhase("testInstallV3Apex_Commit");
        getDevice().reboot();
        runPhase("testInstallV3Apex_VerifyPostReboot");
    }

    @Test
    public void testFailsInvalidApexInstall() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());
        runPhase("testFailsInvalidApexInstall_Commit");
        runPhase("testFailsInvalidApexInstall_AbandonSessionIsNoop");
    }

    @Test
    public void testStagedApkSessionCallbacks() throws Exception {
        runPhase("testStagedApkSessionCallbacks");
    }

    @Test
    @LargeTest
    public void testInstallStagedApexWithoutApexSuffix() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        runPhase("testInstallStagedApexWithoutApexSuffix_Commit");
        getDevice().reboot();
        runPhase("testInstallStagedApexWithoutApexSuffix_VerifyPostReboot");
    }

    @Test
    public void testRejectsApexDifferentCertificate() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        runPhase("testRejectsApexDifferentCertificate");
    }

    /**
     * Tests for staged install involving rotated keys.
     *
     * Here alice means the original default key that cts.shim.v1 package was signed with and
     * bob is the new key alice rotates to. Where ambiguous, we will refer keys as alice and bob
     * instead of "old key" and "new key".
     *
     * By default, rotated keys have rollback capability enabled for old keys. When we remove
     * rollback capability from a key, it is called "Distrusting Event" and the distrusted key can
     * not update the app anymore.
     */

    // Should not be able to update with a key that has not been rotated.
    @Test
    public void testUpdateWithDifferentKeyButNoRotation() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        runPhase("testUpdateWithDifferentKeyButNoRotation");
    }

    // Should be able to update with a key that has been rotated.
    @Test
    @LargeTest
    public void testUpdateWithDifferentKey() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        runPhase("testUpdateWithDifferentKey_Commit");
        getDevice().reboot();
        runPhase("testUpdateWithDifferentKey_VerifyPostReboot");
    }

    // Should not be able to update with a key that is no longer trusted (i.e, has no
    // rollback capability)
    @Test
    @LargeTest
    public void testUntrustedOldKeyIsRejected() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        installV2SignedBobApex();
        runPhase("testUntrustedOldKeyIsRejected");
    }

    // Should be able to update with an old key which is trusted
    @Test
    @LargeTest
    public void testTrustedOldKeyIsAccepted() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        runPhase("testTrustedOldKeyIsAccepted_Commit");
        getDevice().reboot();
        runPhase("testTrustedOldKeyIsAccepted_CommitPostReboot");
        getDevice().reboot();
        runPhase("testTrustedOldKeyIsAccepted_VerifyPostReboot");
    }

    // Should be able to update further with rotated key
    @Test
    @LargeTest
    public void testAfterRotationNewKeyCanUpdateFurther() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        installV2SignedBobApex();
        runPhase("testAfterRotationNewKeyCanUpdateFurther_CommitPostReboot");
        getDevice().reboot();
        runPhase("testAfterRotationNewKeyCanUpdateFurther_VerifyPostReboot");
    }

    @Test
    @LargeTest
    public void testAfterRotationNewKeyCanUpdateFurtherWithoutLineage() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        installV2SignedBobApex();
        runPhase("testAfterRotationNewKeyCanUpdateFurtherWithoutLineage");
    }

    /**
     * Tests for staging and installing multiple staged sessions.
     */

    // Should fail to stage multiple sessions when check-point is not available
    @Test
    public void testFailStagingMultipleSessionsIfNoCheckPoint() throws Exception {
        assumeFalse("Device supports file-system checkpoint",
                mHostUtils.isCheckpointSupported());

        runPhase("testFailStagingMultipleSessionsIfNoCheckPoint");
    }

    @Test
    public void testFailOverlappingMultipleStagedInstall_BothSinglePackage_Apk() throws Exception {
        assumeTrue("Device does not support file-system checkpoint",
                mHostUtils.isCheckpointSupported());

        runPhase("testFailOverlappingMultipleStagedInstall_BothSinglePackage_Apk");
    }

    @Test
    public void testAllowNonOverlappingMultipleStagedInstall_MultiPackageSinglePackage_Apk()
            throws Exception {
        assumeTrue("Device does not support file-system checkpoint",
                mHostUtils.isCheckpointSupported());

        runPhase("testAllowNonOverlappingMultipleStagedInstall_MultiPackageSinglePackage_Apk");
    }

    @Test
    public void testFailOverlappingMultipleStagedInstall_BothMultiPackage_Apk() throws Exception {
        assumeTrue("Device does not support file-system checkpoint",
                mHostUtils.isCheckpointSupported());

        runPhase("testFailOverlappingMultipleStagedInstall_BothMultiPackage_Apk");
    }

    // Test for installing multiple staged sessions at the same time
    @Test
    @LargeTest
    public void testMultipleStagedInstall_ApkOnly() throws Exception {
        assumeTrue("Device does not support file-system checkpoint",
                mHostUtils.isCheckpointSupported());

        runPhase("testMultipleStagedInstall_ApkOnly_Commit");
        getDevice().reboot();
        runPhase("testMultipleStagedInstall_ApkOnly_VerifyPostReboot");
    }

    // If apk installation fails in one staged session, then all staged session should fail.
    @Test
    @LargeTest
    public void testInstallMultipleStagedSession_PartialFail_ApkOnly() throws Exception {
        assumeTrue("Device does not support file-system checkpoint",
                mHostUtils.isCheckpointSupported());

        runPhase("testInstallMultipleStagedSession_PartialFail_ApkOnly_Commit");
        getDevice().reboot();
        runPhase("testInstallMultipleStagedSession_PartialFail_ApkOnly_VerifyPostReboot");
    }

    // Failure reason of staged install should be be persisted for single sessions
    @Test
    @LargeTest
    public void testFailureReasonPersists_SingleSession() throws Exception {
        assumeTrue("Device does not support file-system checkpoint",
                mHostUtils.isCheckpointSupported());

        runPhase("testFailureReasonPersists_SingleSession_Commit");
        getDevice().reboot();
        runPhase("testFailureReasonPersists_SingleSession_VerifyPostReboot");
    }

    // Failure reason of staged install should be be persisted for multi session staged install
    @Test
    @LargeTest
    public void testFailureReasonPersists_MultiSession() throws Exception {
        assumeTrue("Device does not support file-system checkpoint",
                mHostUtils.isCheckpointSupported());

        runPhase("testFailureReasonPersists_MultipleSession_Commit");
        getDevice().reboot();
        runPhase("testFailureReasonPersists_MultipleSession_VerifyPostReboot");
    }

    @Test
    @LargeTest
    public void testSamegradeSystemApex() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        runPhase("testSamegradeSystemApex_Commit");
        getDevice().reboot();
        runPhase("testSamegradeSystemApex_VerifyPostReboot");
    }

    @Test
    @LargeTest
    public void testInstallApkChangingFingerprint() throws Exception {
        try {
            getDevice().executeShellCommand("setprop persist.pm.mock-upgrade true");
            runPhase("testInstallApkChangingFingerprint");
            getDevice().reboot();
            runPhase("testInstallApkChangingFingerprint_VerifyAborted");
        } finally {
            getDevice().executeShellCommand("setprop persist.pm.mock-upgrade false");
        }
    }

    @Test
    @LargeTest
    public void testInstallStagedNoHashtreeApex() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        runPhase("testInstallStagedNoHashtreeApex_Commit");
        getDevice().reboot();
        runPhase("testInstallStagedNoHashtreeApex_VerifyPostReboot");
    }

    /**
     * Should fail to verify apex targeting older dev sdk
     */
    @Test
    public void testApexTargetingOldDevSdkFailsVerification() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        runPhase("testApexTargetingOldDevSdkFailsVerification");
    }

    /**
     * Apex should fail to install if apk-in-apex fails to get scanned
     */
    @Test
    @LargeTest
    public void testApexFailsToInstallIfApkInApexFailsToScan() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        runPhase("testApexFailsToInstallIfApkInApexFailsToScan_Commit");
        getDevice().reboot();
        runPhase("testApexFailsToInstallIfApkInApexFailsToScan_VerifyPostReboot");
    }

    @Test
    public void testCorruptedApexFailsVerification_b146895998() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        runPhase("testCorruptedApexFailsVerification_b146895998");
    }

    /**
     * Should fail to pass apk signature check
     */
    @Test
    public void testApexWithUnsignedApkFailsVerification() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        runPhase("testApexWithUnsignedApkFailsVerification");
    }

    /**
     * Should fail to verify apex signed payload with a different key
     */
    @Test
    public void testApexSignPayloadWithDifferentKeyFailsVerification() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        runPhase("testApexSignPayloadWithDifferentKeyFailsVerification");
    }

    /**
     * Should fail to verify apex with unsigned payload
     */
    @Test
    public void testApexWithUnsignedPayloadFailsVerification() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        runPhase("testApexWithUnsignedPayloadFailsVerification");
    }

    @Test
    @LargeTest
    public void testApexSetsUpdatedSystemAppFlag() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        runPhase("testApexSetsUpdatedSystemAppFlag_preUpdate");
        installV2Apex();
        runPhase("testApexSetsUpdatedSystemAppFlag_postUpdate");
    }

    /**
     * Test non-priv apps cannot access /data/app-staging folder contents
     */
    @Test
    public void testAppStagingDirCannotBeReadByNonPrivApps() throws Exception {
        runPhase("testAppStagingDirCannotBeReadByNonPrivApps");
    }

    @Test
    @LargeTest
    public void testUpdatedApexFromDataApexActiveCanBePulled() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        installV2Apex();

        final ITestDevice.ApexInfo shimApex = mHostUtils.getShimApex().orElseThrow(
                () -> new AssertionError("Can't find " + SHIM_APEX_PACKAGE_NAME)
        );

        assertThat(shimApex.sourceDir).startsWith("/data/apex/active");
        assertThat(getDevice().pullFile(shimApex.sourceDir)).isNotNull();
    }

    @Test
    public void testApexInfoList() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        // Check that content of /apex/apex-info-list.xml matches output of
        // `adb shell pm list packages --apex-only --show-versioncode -f`.
        List<ApexInfo> apexInfoList =
                readApexInfoList().stream()
                    .filter(a -> a.getIsActive())
                    .collect(Collectors.toList());
        Set<ITestDevice.ApexInfo> activeApexes = getDevice().getActiveApexes();
        assertThat(apexInfoList.size()).isEqualTo(activeApexes.size());
        for (ITestDevice.ApexInfo apex : activeApexes) {
            // Note: we can't assert equality of the apex.name and apexInfo.getModuleName() since
            // they represent different concepts (the former is package name, while latter is apex
            // module name)
            List<ApexInfo> temp =
                    apexInfoList.stream()
                            .filter(a -> a.getModulePath().equals(apex.sourceDir))
                            .collect(Collectors.toList());
            assertThat(temp).hasSize(1);
            ApexInfo apexInfo = temp.get(0);
            assertThat(apexInfo.getModulePath()).isEqualTo(apex.sourceDir);
            assertThat(apexInfo.getVersionCode()).isEqualTo(apex.versionCode);
            assertThat(apexInfo.getIsActive()).isTrue();
            assertThat(apexInfo.getLastUpdateMillis()).isGreaterThan(0);
        }
    }

    @Test
    @LargeTest
    public void testApexInfoListAfterUpdate() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        ApexInfo shimBeforeUpdate = getShimApexInfo();

        installV2Apex();

        List<ApexInfo> shimApexInfo =
                readApexInfoList().stream()
                        .filter(a -> a.getModuleName().equals(SHIM_APEX_PACKAGE_NAME))
                        .collect(Collectors.toList());

        assertThat(shimApexInfo).hasSize(2);

        ApexInfo factoryShimApexInfo =
                shimApexInfo.stream()
                        .filter(ApexInfo::getIsFactory)
                        .findAny()
                        .orElseThrow(() ->
                                new AssertionError(
                                        "No factory version of " + SHIM_APEX_PACKAGE_NAME
                                                + " found in /apex/apex-info-list.xml"));
        assertThat(factoryShimApexInfo.getModuleName()).isEqualTo(SHIM_APEX_PACKAGE_NAME);
        assertThat(factoryShimApexInfo.getIsActive()).isFalse();
        assertThat(factoryShimApexInfo.getIsFactory()).isTrue();
        assertThat(factoryShimApexInfo.getVersionCode()).isEqualTo(1);
        assertThat(factoryShimApexInfo.getModulePath())
                .isEqualTo(factoryShimApexInfo.getPreinstalledModulePath());
        assertThat(factoryShimApexInfo.getLastUpdateMillis())
                .isEqualTo(shimBeforeUpdate.getLastUpdateMillis());

        ApexInfo activeShimApexInfo =
                shimApexInfo.stream()
                        .filter(ApexInfo::getIsActive)
                        .findAny()
                        .orElseThrow(() ->
                                new AssertionError(
                                        "No active version of " + SHIM_APEX_PACKAGE_NAME
                                                + " found in /apex/apex-info-list.xml"));
        assertThat(activeShimApexInfo.getModuleName()).isEqualTo(SHIM_APEX_PACKAGE_NAME);
        assertThat(activeShimApexInfo.getIsActive()).isTrue();
        assertThat(activeShimApexInfo.getIsFactory()).isFalse();
        assertThat(activeShimApexInfo.getVersionCode()).isEqualTo(2);
        assertThat(activeShimApexInfo.getPreinstalledModulePath())
                .isEqualTo(factoryShimApexInfo.getModulePath());
        assertThat(activeShimApexInfo.getLastUpdateMillis())
                .isNotEqualTo(shimBeforeUpdate.getLastUpdateMillis());
    }

    @Test
    @LargeTest
    public void testRebootlessUpdate() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        runPhase("testRebootlessUpdate");
        ApexInfo activeShimApexInfo = getActiveShimApexInfo();
        assertThat(activeShimApexInfo.getModuleName()).isEqualTo(SHIM_APEX_PACKAGE_NAME);
        assertThat(activeShimApexInfo.getIsActive()).isTrue();
        assertThat(activeShimApexInfo.getIsFactory()).isFalse();
        assertThat(activeShimApexInfo.getVersionCode()).isEqualTo(2);
    }

    @Test
    @LargeTest
    public void testRebootlessUpdate_fromV2ToV3_sameBoot() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        runPhase("testRebootlessUpdate");
        runPhase("testRebootlessUpdate_installV3");
        ApexInfo activeShimApexInfo = getActiveShimApexInfo();
        assertThat(activeShimApexInfo.getModuleName()).isEqualTo(SHIM_APEX_PACKAGE_NAME);
        assertThat(activeShimApexInfo.getIsActive()).isTrue();
        assertThat(activeShimApexInfo.getIsFactory()).isFalse();
        assertThat(activeShimApexInfo.getVersionCode()).isEqualTo(3);
    }

    @Test
    @LargeTest
    public void testRebootlessUpdate_fromV2ToV3_rebootInBetween() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        runPhase("testRebootlessUpdate");
        getDevice().reboot();
        runPhase("testRebootlessUpdate_installV3");
        ApexInfo activeShimApexInfo = getActiveShimApexInfo();
        assertThat(activeShimApexInfo.getModuleName()).isEqualTo(SHIM_APEX_PACKAGE_NAME);
        assertThat(activeShimApexInfo.getIsActive()).isTrue();
        assertThat(activeShimApexInfo.getIsFactory()).isFalse();
        assertThat(activeShimApexInfo.getVersionCode()).isEqualTo(3);
    }

    @Test
    @LargeTest
    public void testRebootlessUpdate_downgrage_fails() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        runPhase("testRebootlessUpdate_installV3");
        runPhase("testRebootlessUpdate_downgradeToV2_fails");
    }

    @Test
    public void testRebootlessUpdate_noPermission_fails() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        runPhase("testRebootlessUpdate_noPermission_fails");
    }

    @Test
    public void testRebootlessUpdate_noPreInstalledApex_fails() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        runPhase("testRebootlessUpdate_noPreInstalledApex_fails");
    }

    @Test
    public void testRebootlessUpdate_unsignedPayload_fails() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        runPhase("testRebootlessUpdate_unsignedPayload_fails");
    }

    @Test
    public void testRebootlessUpdate_payloadSignedWithDifferentKey_fails() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        runPhase("testRebootlessUpdate_payloadSignedWithDifferentKey_fails");
    }

    @Test
    public void testRebootlessUpdate_outerContainerSignedWithDifferentCert_fails()
            throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        runPhase("testRebootlessUpdate_outerContainerSignedWithDifferentCert_fails");
    }

    @Test
    public void testRebootlessUpdate_outerContainerUnsigned_fails() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        runPhase("testRebootlessUpdate_outerContainerUnsigned_fails");
    }

    @Test
    public void testRebootlessUpdate_targetsOlderSdk_fails() throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        runPhase("testRebootlessUpdate_targetsOlderSdk_fails");
    }

    @Test
    @LargeTest
    public void testGetInactiveApexFactoryPackagesAfterApexInstall_containsNoDuplicates()
            throws Exception {
        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());

        installV2Apex();
        runPhase("testGetInactiveApexFactoryPackagesAfterApexInstall_containsNoDuplicates");
    }

    private List<ApexInfo> readApexInfoList() throws Exception {
        File file = getDevice().pullFile("/apex/apex-info-list.xml");
        try (FileInputStream stream = new FileInputStream(file)) {
            return XmlParser.readApexInfoList(stream).getApexInfo();
        }
    }

    private ApexInfo getShimApexInfo() throws Exception {
        List<ApexInfo> temp =
                readApexInfoList().stream()
                            .filter(a -> a.getModuleName().equals(SHIM_APEX_PACKAGE_NAME))
                            .collect(Collectors.toList());
        assertThat(temp).hasSize(1);
        return temp.get(0);
    }

    private ApexInfo getActiveShimApexInfo() throws Exception {
        return readApexInfoList().stream()
                    .filter(a -> a.getModuleName().equals(SHIM_APEX_PACKAGE_NAME))
                    .filter(ApexInfo::getIsActive)
                    .findAny()
                    .orElseThrow(() ->
                            new AssertionError(
                                    "No active version of " + SHIM_APEX_PACKAGE_NAME
                                            + " found in /apex/apex-info-list.xml"));
    }

    /**
     * Store the component name of the default launcher. This value will be used to reset the
     * default launcher to its correct component upon test completion.
     */
    private void storeDefaultLauncher() throws DeviceNotAvailableException {
        final String PREFIX = "Launcher: ComponentInfo{";
        final String POSTFIX = "}";
        for (String s : getDevice().executeShellCommand("cmd shortcut get-default-launcher")
                .split("\n")) {
            if (s.startsWith(PREFIX) && s.endsWith(POSTFIX)) {
                mDefaultLauncher = s.substring(PREFIX.length(), s.length() - POSTFIX.length());
            }
        }
    }

    /**
     * Set the default launcher to a given component.
     * If set to the broadcast receiver component of this test app, this will allow the test app to
     * receive SESSION_COMMITTED broadcasts.
     */
    private void setDefaultLauncher(String launcherComponent) throws DeviceNotAvailableException {
        assertThat(launcherComponent).isNotEmpty();
        int user = getDevice().getCurrentUser();
        getDevice().executeShellCommand(
                "cmd package set-home-activity --user " + user + " " + launcherComponent);
    }

    private static final class FailedTestLogHook extends TestWatcher {

        private final BaseHostJUnit4Test mInstance;
        private String mStagedSessionsBeforeTest;

        private FailedTestLogHook(BaseHostJUnit4Test instance) {
            this.mInstance = instance;
        }

        @Override
        protected void failed(Throwable e, Description description) {
            String stagedSessionsAfterTest = getStagedSessions();
            Log.e(TAG, "Test " + description + " failed.\n"
                    + "Staged sessions before test started:\n" + mStagedSessionsBeforeTest + "\n"
                    + "Staged sessions after test failed:\n" + stagedSessionsAfterTest);
        }

        @Override
        protected void starting(Description description) {
            mStagedSessionsBeforeTest = getStagedSessions();
        }

        private String getStagedSessions() {
            try {
                return mInstance.getDevice().executeShellV2Command("pm get-stagedsessions").getStdout();
            } catch (DeviceNotAvailableException e) {
                Log.e(TAG, e);
                return "Failed to get staged sessions";
            }
        }
    }

    private boolean isDebuggable() throws Exception {
        return getDevice().getIntProperty("ro.debuggable", 0) == 1;
    }
}
