@Override public AndroidVersion getVersion() { return device.getVersion(); }
@Test public void allowDowngrade_preL() throws Exception { when(mockDevice.getVersion()).thenReturn(new AndroidVersion(VersionCodes.KITKAT)); DdmlibDevice ddmlibDevice = new DdmlibDevice(mockDevice); ddmlibDevice.installApks( ImmutableList.of(APK_PATH), InstallOptions.builder().setAllowDowngrade(true).build()); verify(mockDevice).installPackage(eq(APK_PATH.toString()), anyBoolean(), eq("-d")); }
@SuppressWarnings("unchecked") @Test public void allowDowngrade_postL() throws Exception { when(mockDevice.getVersion()).thenReturn(new AndroidVersion(VersionCodes.LOLLIPOP)); DdmlibDevice ddmlibDevice = new DdmlibDevice(mockDevice); ddmlibDevice.installApks( ImmutableList.of(APK_PATH), InstallOptions.builder().setAllowDowngrade(true).build()); ArgumentCaptor<List<String>> extraArgsCaptor = ArgumentCaptor.forClass((Class) List.class); verify(mockDevice) .installPackages( eq(ImmutableList.of(APK_PATH.toFile())), anyBoolean(), extraArgsCaptor.capture(), anyLong(), any(TimeUnit.class)); assertThat(extraArgsCaptor.getValue()).contains("-d"); } }
@Test public void doesNotAllowDowngrade() throws Exception { when(mockDevice.getVersion()).thenReturn(new AndroidVersion(VersionCodes.KITKAT)); DdmlibDevice ddmlibDevice = new DdmlibDevice(mockDevice); ddmlibDevice.installApks( ImmutableList.of(APK_PATH), InstallOptions.builder().setAllowDowngrade(false).build()); // -d should *not* be passed as extra arg. verify(mockDevice).installPackage(eq(APK_PATH.toString()), anyBoolean(), (String) isNull()); }
/** * Returns the API level of the device. * * @return the API level if it can be determined, {@link AndroidVersion#DEFAULT} otherwise. */ @Override public AndroidVersion getVersion() { return device.getVersion(); }
private boolean isMarshmallowOrMore(@Nonnull IDevice device){ return device.getVersion().getApiLevel() >= 23; }
private static boolean deviceApiLevelInRange(@Nonnull IDevice device, @Nonnull Permission permission) { int featureLevel = device.getVersion().getFeatureLevel(); return permission.getMaxSdkVersion() >= featureLevel && permission.getMinSdkVersion() <= featureLevel; }
private static void validateArguments(@NonNull IDevice device, @NonNull List<File> apks) { if (apks.isEmpty()) { throw new IllegalArgumentException( "List of APKs is empty: the main APK must be specified."); } for (File apk: apks) { if (!apk.isFile()) { throw new IllegalArgumentException("Invalid File: " + apk.getPath()); } } int apiWithSplitApk = AndroidVersion.ALLOW_SPLIT_APK_INSTALLATION.getApiLevel(); if (!device.getVersion().isGreaterOrEqualThan(apiWithSplitApk)) { throw new IllegalArgumentException( "Cannot install split APKs on device with API level < " + apiWithSplitApk); } }
private SplitApkInstaller(@NonNull IDevice device, @NonNull List<File> apks, @NonNull String options) { mDevice = device; mApks = apks; mOptions = options; // Use "cmd package" when possible to avoid starting up a new VM mPrefix = mDevice.getVersion().isGreaterOrEqualThan( AndroidVersion.BINDER_CMD_AVAILABLE.getApiLevel()) ? "cmd package" : "pm"; }