/** * Looks through filtered drawables for files not of the target density and replaces them with * scaled versions. * * <p>Any drawables found by this step didn't have equivalents in the target density. If they are * of a higher density, we can replicate what Android does and downscale them at compile-time. */ private void scaleUnmatchedDrawables(ExecutionContext context) throws IOException, InterruptedException { ResourceFilters.Density targetDensity = ResourceFilters.Density.ORDERING.max(targetDensities); // Go over all the images that remain after filtering. Preconditions.checkNotNull(drawableFinder); Collection<Path> drawables = drawableFinder.findDrawables(inResDirToOutResDirMap.values(), filesystem); for (Path drawable : drawables) { if (drawable.toString().endsWith(".9.png")) { // Skip nine-patch for now. continue; } ResourceFilters.Qualifiers qualifiers = new ResourceFilters.Qualifiers(drawable); ResourceFilters.Density density = qualifiers.density; // If the image has a qualifier but it's not the right one. Preconditions.checkNotNull(targetDensities); if (!targetDensities.contains(density)) { // Replace density qualifier with target density using regular expression to match // the qualifier in the context of a path to a drawable. String fromDensity = (density == ResourceFilters.Density.NO_QUALIFIER ? "" : "-") + density.toString(); Path destination = Paths.get( MorePaths.pathWithUnixSeparators(drawable) .replaceFirst( "((?:^|/)drawable[^/]*)" + Pattern.quote(fromDensity) + "(-|$|/)", "$1-" + targetDensity + "$2")); double factor = targetDensity.value() / density.value(); if (factor >= 1.0) { // There is no point in up-scaling, or converting between drawable and drawable-mdpi. continue; } // Make sure destination folder exists and perform downscaling. filesystem.createParentDirs(destination); Preconditions.checkNotNull(imageScaler); imageScaler.scale(factor, drawable, destination, context); // Delete source file. filesystem.deleteFileAtPath(drawable); // Delete newly-empty directories to prevent missing resources errors in apkbuilder. Path parent = drawable.getParent(); if (filesystem.listFiles(parent).length == 0) { filesystem.deleteFileAtPath(parent); } } } }
@Test public void testDeleteFiles() throws IOException { ProjectFilesystem projectFilesystem = new ProjectFilesystem(tmpDir.getRoot().toPath()); String tracePath = String.format("%s/build.trace", BuckConstant.BUCK_TRACE_DIR); File traceFile = new File(tmpDir.getRoot(), tracePath); projectFilesystem.createParentDirs(tracePath); traceFile.createNewFile(); traceFile.setLastModified(0); for (int i = 0; i < 10; ++i) { File oldResult = new File( tmpDir.getRoot(), String.format("%s/build.100%d.trace", BuckConstant.BUCK_TRACE_DIR, i)); oldResult.createNewFile(); oldResult.setLastModified(TimeUnit.SECONDS.toMillis(i)); } ChromeTraceBuildListener listener = new ChromeTraceBuildListener( projectFilesystem, new FakeClock(1409702151000000000L), new ObjectMapper(), Locale.US, TimeZone.getTimeZone("America/Los_Angeles"), /* tracesToKeep */ 3, false); listener.deleteOldTraces(); ImmutableList<String> files = FluentIterable.from(Arrays.asList(projectFilesystem.listFiles(BuckConstant.BUCK_TRACE_DIR))) .transform( new Function<File, String>() { @Override public String apply(File input) { return input.getName(); } }) .toList(); assertEquals(4, files.size()); assertEquals( ImmutableSortedSet.of( "build.trace", "build.1009.trace", "build.1008.trace", "build.1007.trace"), ImmutableSortedSet.copyOf(files)); }