summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-02-01 00:45:43 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-02-01 00:45:43 +0000
commitb6fcae297c78d3e1628bf9be6490447bdb9b8643 (patch)
tree10a3941dcdeba92f5ab5232ee456df8205dda3a0
parent439332edc6894c3e48d6fad04aa29bd0e5c8160a (diff)
parent702910c9d91c8eb9fd39738d178dbc9250e3b920 (diff)
downloadcts-b6fcae297c78d3e1628bf9be6490447bdb9b8643.tar.gz
Merge cherrypicks of [16762925] into sc-d2-release.
Change-Id: I2baa3856accd607065df3a517f1872807cf6af81
-rw-r--r--common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/packages/Packages.java57
-rw-r--r--common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/utils/ShellCommandUtils.java30
2 files changed, 40 insertions, 47 deletions
diff --git a/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/packages/Packages.java b/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/packages/Packages.java
index 61692249a26..f6ce364628d 100644
--- a/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/packages/Packages.java
+++ b/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/packages/Packages.java
@@ -20,7 +20,6 @@ import static android.Manifest.permission.INSTALL_PACKAGES;
import static android.Manifest.permission.INSTALL_TEST_ONLY_PACKAGE;
import static android.Manifest.permission.INTERACT_ACROSS_USERS;
import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
-import static android.Manifest.permission.MANAGE_EXTERNAL_STORAGE;
import static android.content.pm.PackageInstaller.EXTRA_STATUS;
import static android.content.pm.PackageInstaller.EXTRA_STATUS_MESSAGE;
import static android.content.pm.PackageInstaller.STATUS_FAILURE;
@@ -39,7 +38,6 @@ import android.content.pm.FeatureInfo;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
import android.os.Build;
-import android.os.Environment;
import android.util.Log;
import androidx.annotation.CheckResult;
@@ -58,11 +56,8 @@ import com.android.bedstead.nene.utils.ShellCommandUtils;
import com.android.bedstead.nene.utils.Versions;
import com.android.compatibility.common.util.BlockingBroadcastReceiver;
-import org.junit.AssumptionViolatedException;
-
import java.io.File;
import java.io.FileInputStream;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -71,7 +66,6 @@ import java.util.Collection;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
-import java.util.UUID;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
@@ -328,8 +322,8 @@ public final class Packages {
*
* <p>If the package is marked testOnly, it will still be installed.
*
- * <p>On versions of Android prior to Q, or when running as an instant app, this will return
- * null. On other versions it will return the installed package.
+ * <p>When running as an instant app, this will return null. On other versions it will return
+ * the installed package.
*/
@Nullable
public Package install(UserReference user, byte[] apkFile) {
@@ -337,10 +331,6 @@ public final class Packages {
throw new NullPointerException();
}
- if (!Versions.meetsMinimumSdkVersionRequirement(Build.VERSION_CODES.S)) {
- return installPreS(user, apkFile);
- }
-
if (!user.exists() || !user.isUnlocked()) {
throw new NeneException("Packages can not be installed in non-started users "
+ "(Trying to install into user " + user + ")");
@@ -371,6 +361,10 @@ public final class Packages {
return null;
}
+ if (!Versions.meetsMinimumSdkVersionRequirement(Build.VERSION_CODES.S)) {
+ return installPreS(user, apkFile);
+ }
+
// This is not inside the try because if the install is unsuccessful we don't want to await
// the broadcast
BlockingBroadcastReceiver broadcastReceiver =
@@ -428,30 +422,25 @@ public final class Packages {
@Nullable
private Package installPreS(UserReference user, byte[] apkFile) {
- // Prior to S we cannot pass bytes to stdin so we write it to a temp file first
- File outputDir = Environment.getExternalStorageDirectory();
- File outputFile = null;
-
- if (TestApis.packages().instrumented().isInstantApp()) {
- // We can't manage files as an instant app, so we must skip this test
- throw new AssumptionViolatedException("Cannot install packages as instant app");
- }
-
- try (PermissionContext p =
- TestApis.permissions().withPermissionOnVersion(R, MANAGE_EXTERNAL_STORAGE)) {
- // TODO(b/202705721): Replace this with fixed name
- outputFile = new File(outputDir, UUID.randomUUID() + ".apk");
- outputFile.getParentFile().mkdirs();
- try (FileOutputStream output = new FileOutputStream(outputFile)) {
- output.write(apkFile);
- }
+ // This is not in the try because if the install fails we don't want to await the broadcast
+ BlockingBroadcastReceiver broadcastReceiver =
+ registerPackageInstalledBroadcastReceiver(user);
- return install(user, outputFile);
- } catch (IOException e) {
- throw new NeneException("Error when writing bytes to temp file", e);
+ // We should install using stdin with the byte array
+ try {
+ ShellCommand.builderForUser(user, "pm install")
+ .addOperand("-t") // Allow installing test apks
+ .addOperand("-r") // Replace existing apps
+ .addOption("-S", apkFile.length) // Install from stdin
+ .writeToStdIn(apkFile)
+ .validate(ShellCommandUtils::startsWithSuccess)
+ .execute();
+ return waitForPackageAddedBroadcast(broadcastReceiver);
+ } catch (AdbException e) {
+ throw new NeneException("Error installing package", e);
} finally {
- if (outputFile != null) {
- outputFile.delete();
+ if (broadcastReceiver != null) {
+ broadcastReceiver.unregisterQuietly();
}
}
}
diff --git a/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/utils/ShellCommandUtils.java b/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/utils/ShellCommandUtils.java
index e61fed06c2d..3a624f33964 100644
--- a/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/utils/ShellCommandUtils.java
+++ b/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/utils/ShellCommandUtils.java
@@ -83,10 +83,7 @@ public final class ShellCommandUtils {
logCommand(command, allowEmptyOutput, stdInBytes);
if (!Versions.meetsMinimumSdkVersionRequirement(S)) {
- if (stdInBytes != null && stdInBytes.length > 0) {
- throw new IllegalStateException("Cannot write to stdIn prior to S");
- }
- return executeCommandPreS(command, allowEmptyOutput);
+ return executeCommandPreS(command, allowEmptyOutput, stdInBytes);
}
// TODO(scottjonathan): Add argument to force errors to stderr
@@ -124,11 +121,7 @@ public final class ShellCommandUtils {
logCommand(command, /* allowEmptyOutput= */ false, stdInBytes);
if (!Versions.meetsMinimumSdkVersionRequirement(S)) {
- if (stdInBytes != null && stdInBytes.length > 0) {
- throw new IllegalStateException("Cannot write to stdIn prior to S");
- }
-
- return executeCommandForBytesPreS(command);
+ return executeCommandForBytesPreS(command, stdInBytes);
}
// TODO(scottjonathan): Add argument to force errors to stderr
@@ -217,10 +210,14 @@ public final class ShellCommandUtils {
}
private static String executeCommandPreS(
- String command, boolean allowEmptyOutput) throws AdbException {
- ParcelFileDescriptor fdOut = uiAutomation().executeShellCommand(command);
+ String command, boolean allowEmptyOutput, byte[] stdIn) throws AdbException {
+ ParcelFileDescriptor[] fds = uiAutomation().executeShellCommandRw(command);
+ ParcelFileDescriptor fdOut = fds[OUT_DESCRIPTOR_INDEX];
+ ParcelFileDescriptor fdIn = fds[IN_DESCRIPTOR_INDEX];
try {
+ writeStdInAndClose(fdIn, stdIn);
+
try (FileInputStream fis = new ParcelFileDescriptor.AutoCloseInputStream(fdOut)) {
String out = new String(FileUtils.readInputStreamFully(fis));
@@ -242,10 +239,17 @@ public final class ShellCommandUtils {
}
}
- private static byte[] executeCommandForBytesPreS(String command) throws AdbException {
- ParcelFileDescriptor fdOut = uiAutomation().executeShellCommand(command);
+ // This is warned for executeShellCommandRw which did exist as TestApi
+ @SuppressWarnings("NewApi")
+ private static byte[] executeCommandForBytesPreS(
+ String command, byte[] stdInBytes) throws AdbException {
+ ParcelFileDescriptor[] fds = uiAutomation().executeShellCommandRw(command);
+ ParcelFileDescriptor fdOut = fds[OUT_DESCRIPTOR_INDEX];
+ ParcelFileDescriptor fdIn = fds[IN_DESCRIPTOR_INDEX];
try {
+ writeStdInAndClose(fdIn, stdInBytes);
+
try (FileInputStream fis = new ParcelFileDescriptor.AutoCloseInputStream(fdOut)) {
return FileUtils.readInputStreamFully(fis);
}