public static GetSizeCommand fromFlags(ParsedFlags flags) { Path apksArchivePath = APKS_ARCHIVE_FILE_FLAG.getRequiredValue(flags); Optional<Path> deviceSpecPath = DEVICE_SPEC_FLAG.getValue(flags); Optional<ImmutableSet<String>> modules = MODULES_FLAG.getValue(flags); Optional<Boolean> instant = INSTANT_FLAG.getValue(flags); ImmutableSet<Dimension> dimensions = DIMENSIONS_FLAG.getValue(flags).orElse(ImmutableSet.of()); flags.checkNoUnknownFlags(); checkFileExistsAndReadable(apksArchivePath); deviceSpecPath.ifPresent(FilePreconditions::checkFileExistsAndReadable); DeviceSpec deviceSpec = deviceSpecPath .map(DeviceSpecParser::parsePartialDeviceSpec) .orElse(DeviceSpec.getDefaultInstance()); GetSizeCommand.Builder command = builder() .setApksArchivePath(apksArchivePath) .setDeviceSpec(deviceSpec) .setGetSizeSubCommand(parseGetSizeSubCommand(flags)); modules.ifPresent(command::setModules); instant.ifPresent(command::setInstant); if (dimensions.contains(Dimension.ALL)) { dimensions = SUPPORTED_DIMENSIONS; } command.setDimensions(dimensions); return command.build(); }
deviceId, deviceState, deviceSpec.getSdkVersion(), ImmutableList.copyOf(deviceSpec.getSupportedAbisList()), deviceSpec.getScreenDensity(), ImmutableList.copyOf(deviceSpec.getDeviceFeaturesList()), properties); device.injectShellCommandOutput( () -> LINE_JOINER.join( deviceSpec.getDeviceFeaturesList().stream() .map(feature -> "feature:" + feature) .collect(toImmutableList()))); LINE_JOINER.join( ImmutableList.of( "abi: " + COMMA_JOINER.join(deviceSpec.getSupportedAbisList()), "config: mcc234-mnc15-" + DASH_JOINER.join( deviceSpec.getSupportedLocalesList().stream() .map(FakeDevice::convertLocaleToResourceString) .collect(toImmutableList())))));
return DeviceSpec.newBuilder() .setSdkVersion(deviceSdkVersion) .addAllSupportedAbis(supportedAbis)
if (deviceSpec.get().getSdkVersion() >= Versions.ANDROID_L_API_VERSION) { generateStandaloneApks = false; if (!generateSplitApks) {
.setApksArchivePath(apksArchiveFile) .setDeviceSpec( DeviceSpec.newBuilder() .setSdkVersion(21) .setScreenDensity(125)
.setApksArchivePath(apksArchiveFile) .setDeviceSpec( DeviceSpec.newBuilder().setScreenDensity(124).addSupportedAbis("x86").build()) .setDimensions(ImmutableSet.of(Dimension.ABI, Dimension.SCREEN_DENSITY)) .build()
for (String abi : getDeviceSpec().getSupportedAbisList()) { AbiAlias abiAlias = AbiName.fromPlatformName(abi)
.setGetSizeSubCommand(GetSizeSubcommand.TOTAL) .setApksArchivePath(apksArchiveFile) .setDeviceSpec(DeviceSpec.newBuilder().setSdkVersion(21).build()) .build() .getSizeTotalInternal();
new VariantMatcher(DeviceSpec.getDefaultInstance()) .getAllMatchingVariants(buildApksResult)) .isEqualTo(variants);
@Test public void prefersAbisLocalesViaActivityManager() { FakeDevice fakeDevice = FakeDevice.fromDeviceSpec( "id1", DeviceState.ONLINE, mergeSpecs(sdkVersion(27), locales("en-US"), density(560), abis("armv64-v8a"))); fakeDevice.injectShellCommandOutput( "am get-config", () -> Joiner.on('\n') .join( ImmutableList.of( "abi: arm64-v8a,armeabi-v7a,armeabi", "config: mcc234-mnc15-en-rGB,in-rID,pl-rPL-ldltr-sw411dp-w411dp-h746dp-" + "normal-long-notround-lowdr-widecg-port-notnight-560dpi-finger-" + "keysexposed-nokeys-navhidden-nonav-v27"))); FakeAdbServer fakeAdbServer = new FakeAdbServer( /* hasInitialDeviceList= */ true, /* devices= */ ImmutableList.of(fakeDevice)); fakeAdbServer.init(Paths.get("path/to/adb")); DeviceAnalyzer analyzer = new DeviceAnalyzer(fakeAdbServer); DeviceSpec deviceSpec = analyzer.getDeviceSpec(Optional.empty()); assertThat(deviceSpec.getSupportedAbisList()) .containsExactly("arm64-v8a", "armeabi-v7a", "armeabi") .inOrder(); assertThat(deviceSpec.getSupportedLocalesList()) .containsExactly("en-GB", "in-ID", "pl-PL") .inOrder(); }
@Override protected void checkDeviceCompatibleInternal(AbiTargeting targeting) { if (targeting.equals(AbiTargeting.getDefaultInstance())) { return; } ImmutableSet<String> valuesAndAlternativesSet = Streams.concat( targeting.getValueList().stream() .map(Abi::getAlias) .map(AbiName::fromProto) .map(AbiName::getPlatformName), targeting.getAlternativesList().stream() .map(Abi::getAlias) .map(AbiName::fromProto) .map(AbiName::getPlatformName)) .collect(toImmutableSet()); ImmutableSet<String> deviceAbis = getDeviceSpec().getSupportedAbisList().stream().collect(toImmutableSet()); SetView<String> intersection = Sets.intersection(valuesAndAlternativesSet, deviceAbis); if (intersection.isEmpty()) { throw CommandExecutionException.builder() .withMessage( "The app doesn't support ABI architectures of the device. " + "Device ABIs: %s, app ABIs: %s.", getDeviceSpec().getSupportedAbisList(), valuesAndAlternativesSet) .build(); } }
@Test @Theory public void checkFlagsConstructionWithDeviceSpec( @FromDataPoints("deviceSpecs") String deviceSpecPath) throws Exception { DeviceSpec.Builder expectedDeviceSpecBuilder = DeviceSpec.newBuilder(); try (Reader reader = TestData.openReader(deviceSpecPath)) { JsonFormat.parser().merge(reader, expectedDeviceSpecBuilder); } DeviceSpec expectedDeviceSpec = expectedDeviceSpecBuilder.build(); BuildApksResult tableOfContentsProto = BuildApksResult.getDefaultInstance(); Path apksArchiveFile = createApksArchiveFile(tableOfContentsProto, tmpDir.resolve("bundle.apks")); Path deviceSpecFile = copyToTempDir(deviceSpecPath); GetSizeCommand command = GetSizeCommand.fromFlags( new FlagParser() .parse( "get-size", "total", "--device-spec=" + deviceSpecFile, "--apks=" + apksArchiveFile)); assertThat(command.getDeviceSpec()).isEqualTo(expectedDeviceSpec); }
private static void validateDeviceSpec(DeviceSpec deviceSpec, boolean canSkipFields) { if (deviceSpec.getSdkVersion() < 0 || (!canSkipFields && deviceSpec.getSdkVersion() == 0)) { throw ValidationException.builder() .withMessage( "Device spec SDK version (%d) should be set to a strictly positive number.", deviceSpec.getSdkVersion()) .build(); } if (deviceSpec.getScreenDensity() < 0 || (!canSkipFields && deviceSpec.getScreenDensity() == 0)) { throw ValidationException.builder() .withMessage( "Device spec screen density (%d) should be set to a strictly positive number.", deviceSpec.getScreenDensity()) .build(); } if (!canSkipFields) { if (deviceSpec.getSupportedAbisList().isEmpty()) { throw new ValidationException("Device spec supported ABI list is empty."); } if (deviceSpec.getSupportedLocalesList().isEmpty()) { throw new ValidationException("Device spec supported locales list is empty."); } } }
@Override public boolean matchesTargeting(ScreenDensityTargeting targeting) { ImmutableList<ScreenDensity> allDensities = ImmutableList.<ScreenDensity>builder() .addAll(targeting.getValueList()) .addAll(targeting.getAlternativesList()) .build(); if (allDensities.isEmpty()) { return true; } int bestMatchingDensity = new ScreenDensitySelector() .selectBestDensity( Iterables.transform(allDensities, ResourcesUtils::convertToDpi), getDeviceSpec().getScreenDensity()); return targeting .getValueList() .stream() .map(ResourcesUtils::convertToDpi) .anyMatch(isEqual(bestMatchingDensity)); }
@Test public void extractsDeviceFeatures() { FakeDevice fakeDevice = FakeDevice.fromDeviceSpec( "id1", DeviceState.ONLINE, mergeSpecs( density(240), locales("en-US"), abis("x86"), sdkVersion(21), deviceFeatures("com.feature1", "com.feature2"))); FakeAdbServer fakeAdbServer = new FakeAdbServer( /* hasInitialDeviceList= */ true, /* devices= */ ImmutableList.of(fakeDevice)); fakeAdbServer.init(Paths.get("path/to/adb")); DeviceAnalyzer analyzer = new DeviceAnalyzer(fakeAdbServer); DeviceSpec deviceSpec = analyzer.getDeviceSpec(Optional.empty()); assertThat(deviceSpec.getDeviceFeaturesList()).containsExactly("com.feature1", "com.feature2"); }
public static FakeDevice fromDeviceSpec( String deviceId, DeviceState deviceState, DeviceSpec deviceSpec) { if (deviceSpec.getSdkVersion() < Versions.ANDROID_M_API_VERSION) { Locale deviceLocale = Locale.forLanguageTag(deviceSpec.getSupportedLocales(0)); return fromDeviceSpecWithProperties( deviceId, deviceState, deviceSpec, ImmutableMap.of( "ro.product.locale.language", deviceLocale.getLanguage(), "ro.product.locale.region", deviceLocale.getCountry())); } else { return fromDeviceSpecWithProperties( deviceId, deviceState, deviceSpec, ImmutableMap.of("ro.product.locale", deviceSpec.getSupportedLocales(0))); } }
@Test public void deviceSpecFromTargetingBuilder_setScreenDensity() { assertThat( new DeviceSpecFromTargetingBuilder(DeviceSpec.getDefaultInstance()) .setScreenDensity(ScreenDensityTargeting.getDefaultInstance()) .build()) .isEqualToDefaultInstance(); assertThat( new DeviceSpecFromTargetingBuilder(DeviceSpec.getDefaultInstance()) .setScreenDensity(screenDensityTargeting(XXHDPI)) .build()) .isEqualTo(density(480)); assertThat( new DeviceSpecFromTargetingBuilder(DeviceSpec.getDefaultInstance()) .setScreenDensity(screenDensityTargeting(LDPI, ImmutableSet.of(MDPI))) .build()) .isEqualTo(density(120)); }
@Test public void deviceSpecFromTargetingBuilder_setSupportedAbis() { assertThat( new DeviceSpecFromTargetingBuilder(DeviceSpec.getDefaultInstance()) .setSupportedAbis(AbiTargeting.getDefaultInstance()) .build()) .isEqualToDefaultInstance(); assertThat( new DeviceSpecFromTargetingBuilder(DeviceSpec.getDefaultInstance()) .setSupportedAbis(abiTargeting(ARMEABI)) .build()) .isEqualTo(abis("armeabi")); assertThat( new DeviceSpecFromTargetingBuilder(DeviceSpec.getDefaultInstance()) .setSupportedAbis(abiTargeting(ARMEABI_V7A, ImmutableSet.of(X86))) .build()) .isEqualTo(abis("armeabi-v7a")); }
@Test public void deviceSpecFromTargetingBuilder_setSdkVersion() { assertThat( new DeviceSpecFromTargetingBuilder(DeviceSpec.getDefaultInstance()) .setSdkVersion(SdkVersionTargeting.getDefaultInstance()) .build()) .isEqualToDefaultInstance(); assertThat( new DeviceSpecFromTargetingBuilder(DeviceSpec.getDefaultInstance()) .setSdkVersion(sdkVersionTargeting(sdkVersionFrom(25))) .build()) .isEqualTo(sdkVersion(25)); assertThat( new DeviceSpecFromTargetingBuilder(DeviceSpec.getDefaultInstance()) .setSdkVersion( sdkVersionTargeting(sdkVersionFrom(21), ImmutableSet.of(sdkVersionFrom(23)))) .build()) .isEqualTo(sdkVersion(21)); }
@Test public void oneDevice_noDeviceId_works() throws Exception { DeviceSpec deviceSpec = mergeSpecs(sdkVersion(21), abis("x86_64", "x86"), locales("en-GB"), density(360)); Path outputPath = tmp.getRoot().toPath().resolve("device.json"); // We set up a fake ADB server because the real one won't work on Forge. GetDeviceSpecCommand command = GetDeviceSpecCommand.builder() .setAdbPath(adbPath) .setAdbServer(fakeServerOneDevice(deviceSpec)) .setOutputPath(outputPath) .build(); assertThat(command.execute()).isEqualTo(deviceSpec); try (Reader deviceSpecReader = BufferedIo.reader(outputPath)) { DeviceSpec.Builder writtenSpecBuilder = DeviceSpec.newBuilder(); JsonFormat.parser().merge(deviceSpecReader, writtenSpecBuilder); assertThat(writtenSpecBuilder.build()).isEqualTo(deviceSpec); } }