Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5188d09a authored by Mohammad Samiul Islam's avatar Mohammad Samiul Islam Committed by Android (Google) Code Review
Browse files

Merge changes from topic "simplify"

* changes:
  Make rollback-app support --staged-ready-timeout flag
  Simplify flags used to wait for staged session ready
parents f8e30f0d 82b52fd1
Loading
Loading
Loading
Loading
+50 −50
Original line number Diff line number Diff line
@@ -103,6 +103,7 @@ import android.util.SparseArray;
import com.android.internal.content.PackageHelper;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.Preconditions;
import com.android.server.LocalServices;
import com.android.server.SystemConfig;
import com.android.server.pm.PackageManagerShellCommandDataLoader.Metadata;
@@ -138,7 +139,7 @@ class PackageManagerShellCommand extends ShellCommand {
    private static final String STDIN_PATH = "-";
    /** Path where ART profiles snapshots are dumped for the shell user */
    private final static String ART_PROFILE_SNAPSHOT_DEBUG_LOCATION = "/data/misc/profman/";
    private static final int DEFAULT_WAIT_MS = 60 * 1000;
    private static final int DEFAULT_STAGED_READY_TIMEOUT_MS = 60 * 1000;
    private static final String TAG = "PackageManagerShellCommand";

    final IPackageManager mInterface;
@@ -463,9 +464,20 @@ class PackageManagerShellCommand extends ShellCommand {
        return 1;
    }

    private int runRollbackApp() {
    private int runRollbackApp() throws RemoteException {
        final PrintWriter pw = getOutPrintWriter();

        String opt;
        long stagedReadyTimeoutMs = DEFAULT_STAGED_READY_TIMEOUT_MS;
        while ((opt = getNextOption()) != null) {
            switch (opt) {
                case "--staged-ready-timeout":
                    stagedReadyTimeoutMs = Long.parseLong(getNextArgRequired());
                    break;
                default:
                    throw new IllegalArgumentException("Unknown option: " + opt);
            }
        }
        final String packageName = getNextArgRequired();
        if (packageName == null) {
            pw.println("Error: package name not specified");
@@ -495,14 +507,21 @@ class PackageManagerShellCommand extends ShellCommand {
        final Intent result = receiver.getResult();
        final int status = result.getIntExtra(RollbackManager.EXTRA_STATUS,
                RollbackManager.STATUS_FAILURE);
        if (status == RollbackManager.STATUS_SUCCESS) {
            pw.println("Success");
            return 0;
        } else {

        if (status != RollbackManager.STATUS_SUCCESS) {
            pw.println("Failure ["
                    + result.getStringExtra(RollbackManager.EXTRA_STATUS_MESSAGE) + "]");
            return 1;
        }

        if (rollback.isStaged() && stagedReadyTimeoutMs > 0) {
            final int committedSessionId = rollback.getCommittedSessionId();
            return doWaitForStagedSessionReady(committedSessionId, stagedReadyTimeoutMs, pw);
        }

        pw.println("Success");
        return 0;

    }

    private void setParamsSize(InstallParams params, List<String> inPaths) {
@@ -1307,11 +1326,12 @@ class PackageManagerShellCommand extends ShellCommand {
            }
            abandonSession = false;

            if (!params.sessionParams.isStaged || !params.mWaitForStagedSessionReady) {
            if (params.sessionParams.isStaged && params.stagedReadyTimeoutMs > 0) {
                return doWaitForStagedSessionReady(sessionId, params.stagedReadyTimeoutMs, pw);
            }

            pw.println("Success");
            return 0;
            }
            return doWaitForStagedSessionRead(sessionId, params.timeoutMs, pw);
        } finally {
            if (abandonSession) {
                try {
@@ -1322,11 +1342,9 @@ class PackageManagerShellCommand extends ShellCommand {
        }
    }

    private int doWaitForStagedSessionRead(int sessionId, long timeoutMs, PrintWriter pw)
    private int doWaitForStagedSessionReady(int sessionId, long timeoutMs, PrintWriter pw)
              throws RemoteException {
        if (timeoutMs <= 0) {
            timeoutMs = DEFAULT_WAIT_MS;
        }
        Preconditions.checkArgument(timeoutMs > 0);
        PackageInstaller.SessionInfo si = mInterface.getPackageInstaller()
                .getSessionInfo(sessionId);
        if (si == null) {
@@ -1376,25 +1394,14 @@ class PackageManagerShellCommand extends ShellCommand {
    private int runInstallCommit() throws RemoteException {
        final PrintWriter pw = getOutPrintWriter();
        String opt;
        boolean waitForStagedSessionReady = true;
        long timeoutMs = -1;
        long stagedReadyTimeoutMs = DEFAULT_STAGED_READY_TIMEOUT_MS;
        while ((opt = getNextOption()) != null) {
            switch (opt) {
                case "--wait-for-staged-ready":
                    waitForStagedSessionReady = true;
                    // If there is only one remaining argument, then it represents the sessionId, we
                    // shouldn't try to parse it as timeoutMs.
                    if (getRemainingArgsCount() > 1) {
                        try {
                            timeoutMs = Long.parseLong(peekNextArg());
                            getNextArg();
                        } catch (NumberFormatException ignore) {
                        }
                    }
                    break;
                case "--no-wait":
                    waitForStagedSessionReady = false;
                case "--staged-ready-timeout":
                    stagedReadyTimeoutMs = Long.parseLong(getNextArgRequired());
                    break;
                default:
                    throw new IllegalArgumentException("Unknown option: " + opt);
            }
        }
        final int sessionId = Integer.parseInt(getNextArg());
@@ -1403,12 +1410,12 @@ class PackageManagerShellCommand extends ShellCommand {
        }
        final PackageInstaller.SessionInfo si = mInterface.getPackageInstaller()
                .getSessionInfo(sessionId);
        if (si == null || !si.isStaged() || !waitForStagedSessionReady) {
        if (si != null && si.isStaged() && stagedReadyTimeoutMs > 0) {
            return doWaitForStagedSessionReady(sessionId, stagedReadyTimeoutMs, pw);
        }
        pw.println("Success");
        return 0;
    }
        return doWaitForStagedSessionRead(sessionId, timeoutMs, pw);
    }

    private int runInstallCreate() throws RemoteException {
        final PrintWriter pw = getOutPrintWriter();
@@ -2738,8 +2745,7 @@ class PackageManagerShellCommand extends ShellCommand {
        SessionParams sessionParams;
        String installerPackageName;
        int userId = UserHandle.USER_ALL;
        boolean mWaitForStagedSessionReady = true;
        long timeoutMs = DEFAULT_WAIT_MS;
        long stagedReadyTimeoutMs = DEFAULT_STAGED_READY_TIMEOUT_MS;
    }

    private InstallParams makeInstallParams() {
@@ -2868,16 +2874,8 @@ class PackageManagerShellCommand extends ShellCommand {
                    }
                    sessionParams.installFlags |= PackageManager.INSTALL_ENABLE_ROLLBACK;
                    break;
                case "--wait-for-staged-ready":
                    params.mWaitForStagedSessionReady = true;
                    try {
                        params.timeoutMs = Long.parseLong(peekNextArg());
                        getNextArg();
                    } catch (NumberFormatException ignore) {
                    }
                    break;
                case "--no-wait":
                    params.mWaitForStagedSessionReady = false;
                case "--staged-ready-timeout":
                    params.stagedReadyTimeoutMs = Long.parseLong(getNextArgRequired());
                    break;
                case "--skip-verification":
                    sessionParams.installFlags |= PackageManager.INSTALL_DISABLE_VERIFICATION;
@@ -3613,7 +3611,7 @@ class PackageManagerShellCommand extends ShellCommand {
        pw.println("       [--preload] [--instant] [--full] [--dont-kill]");
        pw.println("       [--enable-rollback]");
        pw.println("       [--force-uuid internal|UUID] [--pkg PACKAGE] [-S BYTES]");
        pw.println("       [--apex] [--wait-for-staged-ready TIMEOUT]");
        pw.println("       [--apex] [--staged-ready-timeout TIMEOUT]");
        pw.println("       [PATH [SPLIT...]|-]");
        pw.println("    Install an application.  Must provide the apk data to install, either as");
        pw.println("    file path(s) or '-' to read from stdin.  Options are:");
@@ -3641,9 +3639,11 @@ class PackageManagerShellCommand extends ShellCommand {
        pw.println("          3=device setup, 4=user request");
        pw.println("      --force-uuid: force install on to disk volume with given UUID");
        pw.println("      --apex: install an .apex file, not an .apk");
        pw.println("      --wait-for-staged-ready: when performing staged install, wait TIMEOUT");
        pw.println("          ms for pre-reboot verification to complete. If TIMEOUT is not");
        pw.println("          specified it will wait for " + DEFAULT_WAIT_MS + " milliseconds.");
        pw.println("      --staged-ready-timeout: By default, staged sessions wait "
                + DEFAULT_STAGED_READY_TIMEOUT_MS);
        pw.println("          milliseconds for pre-reboot verification to complete when");
        pw.println("          performing staged install. This flag is used to alter the waiting");
        pw.println("          time. You can skip the waiting time by specifying a TIMEOUT of '0'");
        pw.println("");
        pw.println("  install-existing [--user USER_ID|all|current]");
        pw.println("       [--instant] [--full] [--wait] [--restrict-permissions] PACKAGE");
+1 −1
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@ android_test_helper_app {
java_test_host {
    name: "StagedInstallInternalTest",
    srcs: ["src/**/*.java"],
    libs: ["tradefed"],
    libs: ["tradefed", "cts-shim-host-lib"],
    static_libs: [
        "testng",
        "compatibility-tradefed",
+53 −16
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.tests.stagedinstallinternal.host;

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

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

import static org.junit.Assert.assertTrue;
@@ -151,43 +153,78 @@ public class StagedInstallInternalTest extends BaseHostJUnit4Test {
        runPhase("testSystemServerRestartDoesNotAffectStagedSessions_Verify");
    }

    // Test waiting time for staged session to be ready using adb staged install can be altered
    @Test
    public void testAdbStagedInstallWaitForReadyFlagWorks() throws Exception {
    public void testAdbStagdReadyTimeoutFlagWorks() throws Exception {
        assumeTrue("Device does not support updating APEX",
                mHostUtils.isApexUpdateSupported());

        File apexFile = mTestUtils.getTestFile(SHIM_V2);
        String output = getDevice().executeAdbCommand("install", "--staged",
                "--wait-for-staged-ready", "60000", apexFile.getAbsolutePath());
        final File apexFile = mTestUtils.getTestFile(SHIM_V2);
        final String output = getDevice().executeAdbCommand("install", "--staged",
                "--staged-ready-timeout", "60000", apexFile.getAbsolutePath());
        assertThat(output).contains("Reboot device to apply staged session");
        String sessionId = getDevice().executeShellCommand(
        final String sessionId = getDevice().executeShellCommand(
                "pm get-stagedsessions --only-ready --only-parent --only-sessionid").trim();
        assertThat(sessionId).isNotEmpty();
    }

    // Test adb staged installation wait for session to be ready by default
    @Test
    public void testAdbStagedInstallNoWaitFlagWorks() throws Exception {
    public void testAdbStagedInstallWaitsTillReadyByDefault() throws Exception {
        assumeTrue("Device does not support updating APEX",
                mHostUtils.isApexUpdateSupported());

        File apexFile = mTestUtils.getTestFile(SHIM_V2);
        String output = getDevice().executeAdbCommand("install", "--staged",
                "--no-wait", apexFile.getAbsolutePath());
        final File apexFile = mTestUtils.getTestFile(SHIM_V2);
        final String output = getDevice().executeAdbCommand("install", "--staged",
                apexFile.getAbsolutePath());
        assertThat(output).contains("Reboot device to apply staged session");
        final String sessionId = getDevice().executeShellCommand(
                "pm get-stagedsessions --only-ready --only-parent --only-sessionid").trim();
        assertThat(sessionId).isNotEmpty();
    }

    // Test we can skip waiting for staged session to be ready
    @Test
    public void testAdbStagedReadyWaitCanBeSkipped() throws Exception {
        assumeTrue("Device does not support updating APEX",
                mHostUtils.isApexUpdateSupported());

        final File apexFile = mTestUtils.getTestFile(SHIM_V2);
        final String output = getDevice().executeAdbCommand("install", "--staged",
                "--staged-ready-timeout", "0", apexFile.getAbsolutePath());
        assertThat(output).doesNotContain("Reboot device to apply staged session");
        assertThat(output).contains("Success");
        String sessionId = getDevice().executeShellCommand(
        final String sessionId = getDevice().executeShellCommand(
                "pm get-stagedsessions --only-ready --only-parent --only-sessionid").trim();
        assertThat(sessionId).isEmpty();
    }

    // Test rollback-app command waits for staged sessions to be ready
    @Test
    public void testAdbRollbackAppWaitsForStagedReady() throws Exception {
        assumeTrue("Device does not support updating APEX",
                mHostUtils.isApexUpdateSupported());

        final File apexFile = mTestUtils.getTestFile(SHIM_V2);
        String output = getDevice().executeAdbCommand("install", "--staged",
                "--enable-rollback", apexFile.getAbsolutePath());
        assertThat(output).contains("Reboot device to apply staged session");
        getDevice().reboot();
        output = getDevice().executeShellCommand("pm rollback-app " + SHIM_APEX_PACKAGE_NAME);
        assertThat(output).contains("Reboot device to apply staged session");
        final String sessionId = getDevice().executeShellCommand(
                "pm get-stagedsessions --only-ready --only-parent --only-sessionid").trim();
        assertThat(sessionId).isNotEmpty();
    }

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

        File apexFile = mTestUtils.getTestFile(SHIM_V2);
        File apkFile = mTestUtils.getTestFile(APK_A);
        String output = getDevice().executeAdbCommand("install-multi-package",
        final File apexFile = mTestUtils.getTestFile(SHIM_V2);
        final File apkFile = mTestUtils.getTestFile(APK_A);
        final String output = getDevice().executeAdbCommand("install-multi-package",
                apexFile.getAbsolutePath(), apkFile.getAbsolutePath());
        assertThat(output).contains("Created parent session");
        assertThat(output).contains("Created child session");
@@ -227,16 +264,16 @@ public class StagedInstallInternalTest extends BaseHostJUnit4Test {

    private void restartSystemServer() throws Exception {
        // Restart the system server
        ProcessInfo oldPs = getDevice().getProcessByName("system_server");
        final ProcessInfo oldPs = getDevice().getProcessByName("system_server");

        getDevice().enableAdbRoot(); // Need root to restart system server
        assertThat(getDevice().executeShellCommand("am restart")).contains("Restart the system");
        getDevice().disableAdbRoot();

        // Wait for new system server process to start
        long start = System.currentTimeMillis();
        final long start = System.currentTimeMillis();
        while (System.currentTimeMillis() < start + SYSTEM_SERVER_TIMEOUT_MS) {
            ProcessInfo newPs = getDevice().getProcessByName("system_server");
            final ProcessInfo newPs = getDevice().getProcessByName("system_server");
            if (newPs != null) {
                if (newPs.getPid() != oldPs.getPid()) {
                    getDevice().waitForDeviceAvailable();