From 8a3de6b03e52d694cb6d5a3cc88b0efd6d617f56 Mon Sep 17 00:00:00 2001 From: lastverb Date: Thu, 5 Aug 2021 11:59:06 +0200 Subject: [PATCH] Flag to use pm install to grant permissions --- .../commands/InstallApksCommand.java | 17 ++++++++++ .../build/bundletool/device/DdmlibDevice.java | 5 +++ .../tools/build/bundletool/device/Device.java | 7 +++- .../bundletool/device/DdmlibDeviceTest.java | 32 +++++++++++++++++++ 4 files changed, 60 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/android/tools/build/bundletool/commands/InstallApksCommand.java b/src/main/java/com/android/tools/build/bundletool/commands/InstallApksCommand.java index 0f4c38b8..4d9b7abd 100644 --- a/src/main/java/com/android/tools/build/bundletool/commands/InstallApksCommand.java +++ b/src/main/java/com/android/tools/build/bundletool/commands/InstallApksCommand.java @@ -69,6 +69,8 @@ public abstract class InstallApksCommand { private static final Flag> MODULES_FLAG = Flag.stringSet("modules"); private static final Flag ALLOW_DOWNGRADE_FLAG = Flag.booleanFlag("allow-downgrade"); private static final Flag ALLOW_TEST_ONLY_FLAG = Flag.booleanFlag("allow-test-only"); + private static final Flag GRANT_ALL_PERMISSIONS_FLAG = + Flag.booleanFlag("grant-all-permissions"); private static final Flag DEVICE_TIER_FLAG = Flag.nonNegativeInteger("device-tier"); private static final Flag> DEVICE_GROUPS_FLAG = Flag.stringSet("device-groups"); @@ -91,6 +93,8 @@ public abstract class InstallApksCommand { public abstract boolean getAllowTestOnly(); + public abstract boolean getGrantAllPermissions(); + public abstract Optional getDeviceTier(); public abstract Optional> getDeviceGroups(); @@ -105,6 +109,7 @@ public static Builder builder() { return new AutoValue_InstallApksCommand.Builder() .setAllowDowngrade(false) .setAllowTestOnly(false) + .setGrantAllPermissions(false) .setTimeout(Device.DEFAULT_ADB_TIMEOUT); } @@ -126,6 +131,8 @@ public abstract static class Builder { public abstract Builder setAllowTestOnly(boolean allowTestOnly); + public abstract Builder setGrantAllPermissions(boolean grantAllPermissions); + public abstract Builder setDeviceTier(Integer deviceTier); public abstract Builder setDeviceGroups(ImmutableSet deviceGroups); @@ -152,6 +159,7 @@ public static InstallApksCommand fromFlags( Optional> modules = MODULES_FLAG.getValue(flags); Optional allowDowngrade = ALLOW_DOWNGRADE_FLAG.getValue(flags); Optional allowTestOnly = ALLOW_TEST_ONLY_FLAG.getValue(flags); + Optional grantAllPermissions = GRANT_ALL_PERMISSIONS_FLAG.getValue(flags); Optional deviceTier = DEVICE_TIER_FLAG.getValue(flags); Optional> deviceGroups = DEVICE_GROUPS_FLAG.getValue(flags); Optional> additionalLocalTestingFiles = @@ -166,6 +174,7 @@ public static InstallApksCommand fromFlags( modules.ifPresent(command::setModules); allowDowngrade.ifPresent(command::setAllowDowngrade); allowTestOnly.ifPresent(command::setAllowTestOnly); + grantAllPermissions.ifPresent(command::setGrantAllPermissions); deviceTier.ifPresent(command::setDeviceTier); deviceGroups.ifPresent(command::setDeviceGroups); additionalLocalTestingFiles.ifPresent(command::setAdditionalLocalTestingFiles); @@ -204,6 +213,7 @@ public void execute() { InstallOptions.builder() .setAllowDowngrade(getAllowDowngrade()) .setAllowTestOnly(getAllowTestOnly()) + .setGrantAllPermissions(getGrantAllPermissions()) .setTimeout(getTimeout()) .build(); @@ -430,6 +440,13 @@ public static CommandHelp help() { "If set, apps with 'android:testOnly=true' set in their manifest can also be" + " deployed") .build()) + .addFlag( + FlagDescription.builder() + .setFlagName(GRANT_ALL_PERMISSIONS_FLAG.getName()) + .setOptional(true) + .setDescription( + "If set, all permissions listed in the app manifest will be granted") + .build()) .addFlag( FlagDescription.builder() .setFlagName(DEVICE_TIER_FLAG.getName()) diff --git a/src/main/java/com/android/tools/build/bundletool/device/DdmlibDevice.java b/src/main/java/com/android/tools/build/bundletool/device/DdmlibDevice.java index b8653460..b8fb355c 100644 --- a/src/main/java/com/android/tools/build/bundletool/device/DdmlibDevice.java +++ b/src/main/java/com/android/tools/build/bundletool/device/DdmlibDevice.java @@ -58,6 +58,7 @@ public class DdmlibDevice extends Device { private static final int ADB_TIMEOUT_MS = 60000; private static final String DEVICE_FEATURES_COMMAND = "pm list features"; private static final String GL_EXTENSIONS_COMMAND = "dumpsys SurfaceFlinger"; + private static final int MIN_INSTALL_WITH_PERMISSIONS_API_LEVEL = 23; private final DeviceFeaturesParser deviceFeaturesParser = new DeviceFeaturesParser(); private final GlExtensionsParser glExtensionsParser = new GlExtensionsParser(); @@ -169,6 +170,10 @@ public void installApks(ImmutableList apks, InstallOptions installOptions) if (installOptions.getAllowTestOnly()) { extraArgs.add("-t"); } + if (installOptions.getGrantAllPermissions() && + getVersion().isGreaterOrEqualThan(MIN_INSTALL_WITH_PERMISSIONS_API_LEVEL)) { + extraArgs.add("-g"); + } try { if (getVersion() diff --git a/src/main/java/com/android/tools/build/bundletool/device/Device.java b/src/main/java/com/android/tools/build/bundletool/device/Device.java index 26b91973..61569661 100644 --- a/src/main/java/com/android/tools/build/bundletool/device/Device.java +++ b/src/main/java/com/android/tools/build/bundletool/device/Device.java @@ -87,6 +87,8 @@ public abstract static class InstallOptions { public abstract boolean getAllowTestOnly(); + public abstract boolean getGrantAllPermissions(); + public abstract Duration getTimeout(); public static Builder builder() { @@ -94,7 +96,8 @@ public static Builder builder() { .setTimeout(DEFAULT_ADB_TIMEOUT) .setAllowReinstall(true) .setAllowDowngrade(false) - .setAllowTestOnly(false); + .setAllowTestOnly(false) + .setGrantAllPermissions(false); } /** Builder for {@link InstallOptions}. */ @@ -108,6 +111,8 @@ public abstract static class Builder { public abstract Builder setAllowTestOnly(boolean allowTestOnly); + public abstract Builder setGrantAllPermissions(boolean grantAllPermissions); + public abstract InstallOptions build(); } } diff --git a/src/test/java/com/android/tools/build/bundletool/device/DdmlibDeviceTest.java b/src/test/java/com/android/tools/build/bundletool/device/DdmlibDeviceTest.java index c8d3efb0..824fd600 100644 --- a/src/test/java/com/android/tools/build/bundletool/device/DdmlibDeviceTest.java +++ b/src/test/java/com/android/tools/build/bundletool/device/DdmlibDeviceTest.java @@ -122,6 +122,38 @@ public void allowTestOnly() throws Exception { verify(mockDevice).installPackage(eq(APK_PATH.toString()), anyBoolean(), eq("-t")); } + @Test + public void grantAllPermissionsPreM() throws Exception { + when(mockDevice.getVersion()).thenReturn(new AndroidVersion(VersionCodes.KITKAT)); + DdmlibDevice ddmlibDevice = new DdmlibDevice(mockDevice); + + ddmlibDevice.installApks( + ImmutableList.of(APK_PATH), InstallOptions.builder().setGrantAllPermissions(true).build()); + + verify(mockDevice).installPackage(eq(APK_PATH.toString()), anyBoolean()); + } + + @SuppressWarnings("unchecked") + @Test + public void grantAllPermissionsPostM() throws Exception { + when(mockDevice.getVersion()).thenReturn(new AndroidVersion(VersionCodes.M)); + DdmlibDevice ddmlibDevice = new DdmlibDevice(mockDevice); + + ddmlibDevice.installApks( + ImmutableList.of(APK_PATH), InstallOptions.builder().setGrantAllPermissions(true).build()); + + ArgumentCaptor> extraArgsCaptor = ArgumentCaptor.forClass(List.class); + verify(mockDevice) + .installPackages( + eq(ImmutableList.of(APK_PATH.toFile())), + anyBoolean(), + extraArgsCaptor.capture(), + anyLong(), + any(TimeUnit.class)); + + assertThat(extraArgsCaptor.getValue()).contains("-g"); + } + @Test public void pushFiles_targetLocation() throws Exception { String destinationPath = "/destination/path";