@Override protected void checkDeviceCompatibleInternal(SdkVersionTargeting targeting) { SdkVersion sdkValue = targeting.getValueCount() == 0 ? SdkVersion.getDefaultInstance() : targeting.getValue(0); boolean anyMatch = Stream.concat(Stream.of(sdkValue), targeting.getAlternativesList().stream()) .anyMatch(sdkVal -> matchesDeviceSdk(sdkVal, deviceSdkVersion)); if (!anyMatch) { throw CommandExecutionException.builder() .withMessage( "The app doesn't support SDK version of the device: (%d).", getDeviceSpec().getSdkVersion()) .build(); } }
@Test public void simpleMatching() { SdkVersionMatcher sdkMatcher = new SdkVersionMatcher(deviceWithSdk(21)); assertThat( sdkMatcher.matchesTargeting( sdkVersionTargeting(SdkVersion.getDefaultInstance(), ImmutableSet.of()))) .isTrue(); assertThat( sdkMatcher.matchesTargeting(sdkVersionTargeting(sdkVersionFrom(21), ImmutableSet.of()))) .isTrue(); }
@Override public boolean matchesTargeting(SdkVersionTargeting targeting) { checkArgument( targeting.getValueCount() <= 1, "Found more than one SDK version value in the variant targeting."); SdkVersion sdkValue = targeting.getValueCount() == 0 ? SdkVersion.getDefaultInstance() : targeting.getValue(0); if (!matchesDeviceSdk(sdkValue, deviceSdkVersion)) { return false; } // Check if there is a better match among alternatives. for (SdkVersion alternativeSdkValue : targeting.getAlternativesList()) { if (isBetterSdkMatch( /* candidate= */ alternativeSdkValue, /* contestedValue= */ sdkValue, deviceSdkVersion)) { return false; } } return true; }
SdkVersion lPlusVersion = sdkVersionFrom(Versions.ANDROID_L_API_VERSION); VariantTargeting lPlusTargeting = variantSdkTargeting(lPlusVersion); VariantTargeting emptySdkTargeting = variantSdkTargeting(SdkVersion.getDefaultInstance()); .containsExactly( mergeVariantTargeting( variantSdkTargeting(SdkVersion.getDefaultInstance(), ImmutableSet.of(lPlusVersion)), variantDensityTargeting( DensityAlias.MDPI, ImmutableSet.of(DensityAlias.HDPI, DensityAlias.XHDPI))), mergeVariantTargeting( variantSdkTargeting(SdkVersion.getDefaultInstance(), ImmutableSet.of(lPlusVersion)), variantDensityTargeting( DensityAlias.HDPI, ImmutableSet.of(DensityAlias.MDPI, DensityAlias.XHDPI))), mergeVariantTargeting( variantSdkTargeting(SdkVersion.getDefaultInstance(), ImmutableSet.of(lPlusVersion)), variantDensityTargeting( DensityAlias.XHDPI, ImmutableSet.of(DensityAlias.MDPI, DensityAlias.HDPI))));
createVariant( variantSdkTargeting( sdkVersionFrom(21), ImmutableSet.of(SdkVersion.getDefaultInstance())), createInstantApkSet( "base", ApkTargeting.getDefaultInstance(), ZipPath.create("base-master.apk")), createVariant( variantSdkTargeting( sdkVersionFrom(21), ImmutableSet.of(SdkVersion.getDefaultInstance())), createSplitApkSet( "other",
createVariantForSingleSplitApk( variantSdkTargeting( SdkVersion.getDefaultInstance(), ImmutableSet.of(sdkVersionFrom(21), sdkVersionFrom(23))), ApkTargeting.getDefaultInstance(), variantSdkTargeting( sdkVersionFrom(21), ImmutableSet.of(SdkVersion.getDefaultInstance(), sdkVersionFrom(23))), ApkTargeting.getDefaultInstance(), apkL)) variantSdkTargeting( sdkVersionFrom(23), ImmutableSet.of(SdkVersion.getDefaultInstance(), sdkVersionFrom(21))), ApkTargeting.getDefaultInstance(), apkM))
createVariant( variantSdkTargeting( sdkVersionFrom(21), ImmutableSet.of(SdkVersion.getDefaultInstance())), createSplitApkSet( /* moduleName= */ "base",
createVariant( variantSdkTargeting( sdkVersionFrom(21), ImmutableSet.of(SdkVersion.getDefaultInstance())), createStandaloneApkSet(ApkTargeting.getDefaultInstance(), apkPreL))) .addVariant( createVariant( variantSdkTargeting( sdkVersionFrom(21), ImmutableSet.of(SdkVersion.getDefaultInstance())), createInstantApkSet("base", ApkTargeting.getDefaultInstance(), apkLBase), createInstantApkSet("feature", ApkTargeting.getDefaultInstance(), apkLFeature),
createVariant( variantSdkTargeting( sdkVersionFrom(21), ImmutableSet.of(SdkVersion.getDefaultInstance())), createStandaloneApkSet(ApkTargeting.getDefaultInstance(), apkPreL))) .addVariant( createVariant( variantSdkTargeting( sdkVersionFrom(21), ImmutableSet.of(SdkVersion.getDefaultInstance())), createSplitApkSet( "base",
createVariant( variantSdkTargeting( sdkVersionFrom(21), ImmutableSet.of(SdkVersion.getDefaultInstance())), createInstantApkSet("base", ApkTargeting.getDefaultInstance(), apkBase), createInstantApkSet("instant", ApkTargeting.getDefaultInstance(), apkInstant))) createVariant( variantSdkTargeting( sdkVersionFrom(21), ImmutableSet.of(SdkVersion.getDefaultInstance())), createSplitApkSet( "other",
VariantTargeting lPlusTargeting = variantSdkTargeting(sdkVersionFrom(21)); VariantTargeting mPlusTargeting = variantSdkTargeting(sdkVersionFrom(23)); VariantTargeting defaultSdkTargeting = variantSdkTargeting(SdkVersion.getDefaultInstance()); variantSdkTargeting( sdkVersionFrom(21), ImmutableSet.of(SdkVersion.getDefaultInstance(), sdkVersionFrom(23)))); ModuleSplit mPlusVariantNew = outputVariants.get(1); assertThat(mPlusVariantNew.getVariantTargeting()) variantSdkTargeting( sdkVersionFrom(23), ImmutableSet.of(SdkVersion.getDefaultInstance(), sdkVersionFrom(21)))); ModuleSplit defaultSdkVariantNew = outputVariants.get(2); assertThat(defaultSdkVariantNew.getVariantTargeting()) .isEqualTo( variantSdkTargeting( SdkVersion.getDefaultInstance(), ImmutableSet.of(sdkVersionFrom(21), sdkVersionFrom(23))));
createVariant( variantSdkTargeting( sdkVersionFrom(21), ImmutableSet.of(SdkVersion.getDefaultInstance())), createInstantApkSet("base", ApkTargeting.getDefaultInstance(), apkBase), createInstantApkSet("instant", ApkTargeting.getDefaultInstance(), apkInstant),
SdkVersion lPlusVersion = sdkVersionFrom(Versions.ANDROID_L_API_VERSION); VariantTargeting lPlusTargeting = variantSdkTargeting(lPlusVersion); VariantTargeting emptySdkTargeting = variantSdkTargeting(SdkVersion.getDefaultInstance());
@Test public void betterAlternative() { SdkVersionMatcher sdkMatcher = new SdkVersionMatcher(deviceWithSdk(25)); assertThat( sdkMatcher.matchesTargeting( sdkVersionTargeting( SdkVersion.getDefaultInstance(), ImmutableSet.of(sdkVersionFrom(25))))) .isFalse(); assertThat( sdkMatcher.matchesTargeting( sdkVersionTargeting( SdkVersion.getDefaultInstance(), ImmutableSet.of(sdkVersionFrom(21))))) .isFalse(); assertThat( sdkMatcher.matchesTargeting( sdkVersionTargeting( sdkVersionFrom(21), ImmutableSet.of(sdkVersionFrom(23), SdkVersion.getDefaultInstance())))) .isFalse(); assertThat( sdkMatcher.matchesTargeting( sdkVersionTargeting( sdkVersionFrom(27), ImmutableSet.of(sdkVersionFrom(23), SdkVersion.getDefaultInstance())))) .isFalse(); } }
@Test public void extractInstant_withBaseOnly() throws Exception { Path apkLBase = ZipPath.create("apkL-base.apk"); BuildApksResult tableOfContentsProto = BuildApksResult.newBuilder() .addVariant( createVariant( variantSdkTargeting( sdkVersionFrom(21), ImmutableSet.of(SdkVersion.getDefaultInstance())), createInstantApkSet("base", ApkTargeting.getDefaultInstance(), apkLBase))) .build(); Path apksArchiveFile = createApksArchiveFile(tableOfContentsProto, tmpDir.resolve("bundle.apks")); DeviceSpec deviceSpec = deviceWithSdk(21); ImmutableList<Path> matchedApks = ExtractApksCommand.builder() .setApksArchivePath(apksArchiveFile) .setDeviceSpec(deviceSpec) .setOutputDirectory(tmpDir) .setInstant(true) .build() .execute(); assertThat(matchedApks).containsExactly(inOutputDirectory(apkLBase)); for (Path matchedApk : matchedApks) { checkFileExistsAndReadable(tmpDir.resolve(matchedApk)); } }
@Test public void worseAlternatives() { SdkVersionMatcher sdkMatcher = new SdkVersionMatcher(deviceWithSdk(23)); assertThat( sdkMatcher.matchesTargeting( sdkVersionTargeting( sdkVersionFrom(21), ImmutableSet.of(SdkVersion.getDefaultInstance())))) .isTrue(); assertThat( sdkMatcher.matchesTargeting( sdkVersionTargeting(sdkVersionFrom(23), ImmutableSet.of(sdkVersionFrom(21))))) .isTrue(); assertThat( sdkMatcher.matchesTargeting( sdkVersionTargeting( sdkVersionFrom(23), ImmutableSet.of(sdkVersionFrom(21), SdkVersion.getDefaultInstance())))) .isTrue(); }
@Test public void systemApksPassThrough() { VariantTargeting emptySdkTargeting = variantSdkTargeting(SdkVersion.getDefaultInstance()); ImmutableList<ModuleSplit> systemSplits = ImmutableList.of( createModuleSplit( mergeVariantTargeting( emptySdkTargeting, variantDensityTargeting(DensityAlias.LDPI)), SplitType.SYSTEM)); GeneratedApks generatedApks = GeneratedApks.builder().setSystemApks(systemSplits).build(); GeneratedApks processedApks = AlternativeVariantTargetingPopulator.populateAlternativeVariantTargeting(generatedApks); assertThat(processedApks.size()).isEqualTo(1); assertThat(processedApks.getInstantApks()).isEmpty(); assertThat(processedApks.getStandaloneApks()).isEmpty(); assertThat(processedApks.getSplitApks()).isEmpty(); assertThat(processedApks.getSystemApks()).isEqualTo(systemSplits); }
private Variant createSystemVariant() { Path systemApk = ZipPath.create("system.apk"); return createVariant( variantSdkTargeting(sdkVersionFrom(15), ImmutableSet.of(SdkVersion.getDefaultInstance())), createSystemApkSet(ApkTargeting.getDefaultInstance(), systemApk)); } }
private Variant createInstantVariant() { Path apkLBase = ZipPath.create("instant/apkL-base.apk"); Path apkLFeature = ZipPath.create("instant/apkL-feature.apk"); Path apkLOther = ZipPath.create("instant/apkL-other.apk"); return createVariant( variantSdkTargeting(sdkVersionFrom(21), ImmutableSet.of(SdkVersion.getDefaultInstance())), createInstantApkSet("base", ApkTargeting.getDefaultInstance(), apkLBase), createInstantApkSet("feature", ApkTargeting.getDefaultInstance(), apkLFeature), createInstantApkSet("other", ApkTargeting.getDefaultInstance(), apkLOther)); }
private Variant createStandaloneVariant() { Path apkPreL = ZipPath.create("apkPreL.apk"); return createVariant( variantSdkTargeting(sdkVersionFrom(15), ImmutableSet.of(SdkVersion.getDefaultInstance())), createStandaloneApkSet(ApkTargeting.getDefaultInstance(), apkPreL)); }