Merge changes from topic "simplify"
* changes:
Make rollback-app support --staged-ready-timeout flag
Simplify flags used to wait for staged session ready
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 7e2ef41..4d2e22a 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -103,6 +103,7 @@
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 @@
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 @@
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 @@
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 @@
}
abandonSession = false;
- if (!params.sessionParams.isStaged || !params.mWaitForStagedSessionReady) {
- pw.println("Success");
- return 0;
+ if (params.sessionParams.isStaged && params.stagedReadyTimeoutMs > 0) {
+ return doWaitForStagedSessionReady(sessionId, params.stagedReadyTimeoutMs, pw);
}
- return doWaitForStagedSessionRead(sessionId, params.timeoutMs, pw);
+
+ pw.println("Success");
+ return 0;
} finally {
if (abandonSession) {
try {
@@ -1322,11 +1342,9 @@
}
}
- 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 @@
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) {
- }
- }
+ case "--staged-ready-timeout":
+ stagedReadyTimeoutMs = Long.parseLong(getNextArgRequired());
break;
- case "--no-wait":
- waitForStagedSessionReady = false;
- break;
+ default:
+ throw new IllegalArgumentException("Unknown option: " + opt);
}
}
final int sessionId = Integer.parseInt(getNextArg());
@@ -1403,11 +1410,11 @@
}
final PackageInstaller.SessionInfo si = mInterface.getPackageInstaller()
.getSessionInfo(sessionId);
- if (si == null || !si.isStaged() || !waitForStagedSessionReady) {
- pw.println("Success");
- return 0;
+ if (si != null && si.isStaged() && stagedReadyTimeoutMs > 0) {
+ return doWaitForStagedSessionReady(sessionId, stagedReadyTimeoutMs, pw);
}
- return doWaitForStagedSessionRead(sessionId, timeoutMs, pw);
+ pw.println("Success");
+ return 0;
}
private int runInstallCreate() throws RemoteException {
@@ -2738,8 +2745,7 @@
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 @@
}
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 @@
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 @@
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");
diff --git a/tests/StagedInstallTest/Android.bp b/tests/StagedInstallTest/Android.bp
index 229a9aa..f55d4d4 100644
--- a/tests/StagedInstallTest/Android.bp
+++ b/tests/StagedInstallTest/Android.bp
@@ -26,7 +26,7 @@
java_test_host {
name: "StagedInstallInternalTest",
srcs: ["src/**/*.java"],
- libs: ["tradefed"],
+ libs: ["tradefed", "cts-shim-host-lib"],
static_libs: [
"testng",
"compatibility-tradefed",
diff --git a/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java b/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
index d7b0796..f50d2e1 100644
--- a/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
+++ b/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
@@ -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 @@
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 @@
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();