AaptV1 extends AbstractProcessExecutionAapt { @NonNull @Override public ListenableFuture<File> compile(@NonNull File file, @NonNull File output) throws AaptException { ListenableFuture<File> compilationFuture; if (ResourceFolderType.getFolderType(file.getParentFile().getName()) == ResourceFolderType.RAW) { return Futures.immediateFuture(null); } if (mCruncher == null) { compilationFuture = super.compile(file, output); } else { Preconditions.checkArgument(file.isFile(), "!file.isFile()"); Preconditions.checkArgument(output.isDirectory(), "!output.isDirectory()"); SettableFuture<File> future = SettableFuture.create(); compilationFuture = future; if (!mProcessMode.shouldProcess(file)) { future.set(null); } else { File outputFile = compileOutputFor(file, output); try { Files.createParentDirs(outputFile); } catch (IOException e) { throw new AaptException(e, String.format( "Failed to create parent directories for file '%s'", output.getAbsolutePath())); } int key = mCruncher.start(); try { mCruncher.crunchPng(key, file, outputFile); } catch (PngException e) { throw new AaptException(e, String.format( "Failed to crunch file '%s' into '%s'", file.getAbsolutePath(), outputFile.getAbsolutePath())); } mWaitExecutor.execute(() -> { try { mCruncher.end(key); future.set(outputFile); } catch (Exception e) { future.setException(e); } }); } } if (file.getName().endsWith(SdkConstants.DOT_9PNG)) { return compilationFuture; } return Futures.transform(compilationFuture, (File result) -> { SettableFuture<File> returnFuture = SettableFuture.create(); try { if (result != null && file.length() < result.length()) { Files.copy(file, result); } returnFuture.set(result); } catch (Exception e) { returnFuture.setException(e); } return returnFuture; }); } AaptV1(
            @NonNull ProcessExecutor processExecutor,
            @NonNull ProcessOutputHandler processOutputHandler,
            @NonNull BuildToolInfo buildToolInfo,
            @NonNull ILogger logger,
            @NonNull PngProcessMode processMode,
            int cruncherProcesses); @NonNull @Override ListenableFuture<File> compile(@NonNull File file, @NonNull File output);  }
@Test public void compilePng() throws Exception { Aapt aapt = makeAapt(); Future<File> compiledFuture = aapt.compile( AaptTestUtils.getTestPng(mTemporaryFolder), AaptTestUtils.getOutputDir(mTemporaryFolder)); File compiled = compiledFuture.get(); assertNotNull(compiled); assertTrue(compiled.isFile()); }
@Test public void compileTxt() throws Exception { Aapt aapt = makeAapt(); Future<File> compiledFuture = aapt.compile( AaptTestUtils.getTestTxt(mTemporaryFolder), AaptTestUtils.getOutputDir(mTemporaryFolder)); File compiled = compiledFuture.get(); assertNull(compiled); }
@Test public void parallelInterface() throws Exception { Aapt aapt = makeAapt(); int parallel = 10; File[] imgs = new File[parallel]; for (int i = 0; i < parallel; i++) { imgs[i] = mTemporaryFolder.newFile("i" + i + ".png"); Files.copy(AaptTestUtils.getTestPng(mTemporaryFolder), imgs[i]); } @SuppressWarnings("unchecked") Future<File>[] futures = new Future[parallel]; for (int i = 0; i < parallel; i++) { futures[i] = aapt.compile(imgs[i], AaptTestUtils.getOutputDir(mTemporaryFolder)); assertFalse(futures[i].isDone()); } Set<File> results = new HashSet<>(); for (int i = 0; i < parallel; i++) { File f = futures[i].get(); assertTrue(results.add(f)); } }
@Test public void noCrunchPngIfBigger() throws Exception { Aapt aapt = makeAapt(); File originalFile = AaptTestUtils.getNonCrunchableTestPng(); Future<File> compiledFuture = aapt.compile(originalFile, AaptTestUtils.getOutputDir(mTemporaryFolder)); File compiled = compiledFuture.get(); assertNotNull(compiled); assertTrue(compiled.isFile()); assertTrue( "originalFile.length() [" + originalFile.length() + "] != compiled.length() [" + compiled.length() + "]", originalFile.length() == compiled.length()); }
@Test public void crunchPngIfSmaller() throws Exception { Aapt aapt = makeAapt(); File originalFile = AaptTestUtils.getCrunchableTestPng(); Future<File> compiledFuture = aapt.compile(originalFile, AaptTestUtils.getOutputDir(mTemporaryFolder)); File compiled = compiledFuture.get(); assertNotNull(compiled); assertTrue(compiled.isFile()); assertTrue( "originalFile.length() [" + originalFile.length() + "] < compiled.length() [" + compiled.length() + "]", originalFile.length() > compiled.length()); }
@Test public void ninePatchPngsAlwaysProcessedEvenIfBigger() throws Exception { Aapt aapt = makeAapt(); File originalFile = AaptTestUtils.getNinePatchTestPng(); Future<File> compiledFuture = aapt.compile(originalFile, AaptTestUtils.getOutputDir(mTemporaryFolder)); File compiled = compiledFuture.get(); assertNotNull(compiled); assertTrue(compiled.isFile()); assertTrue( "originalFile.length() [" + originalFile.length() + "] > compiled.length() [" + compiled.length() + "]", originalFile.length() < compiled.length()); }
@Test public void ninePatchPngsAreNotProcessedIfNotEnabledBeforeV22() throws Exception { Aapt aapt = makeAapt( AaptV1.PngProcessMode.NONE, new Revision(AaptV1.VERSION_FOR_SERVER_AAPT.getMajor() - 1, 0, 0)); File originalFile = AaptTestUtils.getNinePatchTestPng(); Future<File> compiledFuture = aapt.compile(originalFile, AaptTestUtils.getOutputDir(mTemporaryFolder)); File compiled = compiledFuture.get(); assertNull(compiled); }
@Test public void ninePatchPngsAreNotProcessedIfNotEnabledAfterV22() throws Exception { Aapt aapt = makeAapt( AaptV1.PngProcessMode.NONE, new Revision(AaptV1.VERSION_FOR_SERVER_AAPT.getMajor() + 1, 0, 0)); File originalFile = AaptTestUtils.getNinePatchTestPng(); Future<File> compiledFuture = aapt.compile(originalFile, AaptTestUtils.getOutputDir(mTemporaryFolder)); File compiled = compiledFuture.get(); assertNull(compiled); }
@Test public void generateRJavaInApplication() throws Exception { Aapt aapt = makeAapt(); File outputDir = AaptTestUtils.getOutputDir(mTemporaryFolder); File originalFile = AaptTestUtils.getTestPng(mTemporaryFolder); Future<File> compiledFuture = aapt.compile(originalFile, outputDir); if (compiledFuture.get() == null) { File ddir = new File(outputDir, "drawable"); assertTrue(ddir.mkdir()); Files.copy(originalFile, new File(ddir, originalFile.getName())); } File manifestFile = mTemporaryFolder.newFile("AndroidManifest.xml"); Files.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + "<manifest xmlns:android=\"http: + " package=\"com.example.aapt\"></manifest>", manifestFile, Charsets.US_ASCII); IAndroidTarget target23 = mTargetManager.getTargetOfAtLeastApiLevel(23, mProgressIndicator); File sourceOutput = mTemporaryFolder.newFolder("source-output"); AaptPackageConfig config = new AaptPackageConfig.Builder() .setAndroidTarget(target23) .setBuildToolInfo(getBuildToolInfo(AaptV1.VERSION_FOR_SERVER_AAPT)) .setLogger(mLogger) .setManifestFile(manifestFile) .setOptions(mDummyOptions) .setSourceOutputDir(sourceOutput) .setVariantType(VariantType.DEFAULT) .setResourceDir(outputDir) .build(); aapt.link(config).get(); File rJava = FileUtils.join(sourceOutput, "com", "example", "aapt", "R.java"); assertTrue(rJava.isFile()); String lenaResource = null; for (String line : Files.readLines(rJava, Charsets.US_ASCII)) { if (line.contains("int lena")) { lenaResource = line; break; } } assertNotNull(lenaResource); assertTrue(lenaResource.contains("public")); assertTrue(lenaResource.contains("static")); assertTrue(lenaResource.contains("final")); }
@Test public void generateRJavaInLibrary() throws Exception { Aapt aapt = makeAapt(); File outputDir = AaptTestUtils.getOutputDir(mTemporaryFolder); File originalFile = AaptTestUtils.getTestPng(mTemporaryFolder); Future<File> compiledFuture = aapt.compile(originalFile, outputDir); if (compiledFuture.get() == null) { File ddir = new File(outputDir, "drawable"); assertTrue(ddir.mkdir()); Files.copy(originalFile, new File(ddir, originalFile.getName())); } File manifestFile = mTemporaryFolder.newFile("AndroidManifest.xml"); Files.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + "<manifest xmlns:android=\"http: + " package=\"com.example.aapt\"></manifest>", manifestFile, Charsets.US_ASCII); IAndroidTarget target23 = mTargetManager.getTargetOfAtLeastApiLevel(23, mProgressIndicator); File sourceOutput = mTemporaryFolder.newFolder("source-output"); AaptPackageConfig config = new AaptPackageConfig.Builder() .setAndroidTarget(target23) .setBuildToolInfo(getBuildToolInfo(AaptV1.VERSION_FOR_SERVER_AAPT)) .setLogger(mLogger) .setManifestFile(manifestFile) .setOptions(mDummyOptions) .setSourceOutputDir(sourceOutput) .setVariantType(VariantType.LIBRARY) .setResourceDir(outputDir) .build(); aapt.link(config).get(); File rJava = FileUtils.join(sourceOutput, "com", "example", "aapt", "R.java"); assertTrue(rJava.isFile()); String lenaResource = null; for (String line : Files.readLines(rJava, Charsets.US_ASCII)) { if (line.contains("int lena")) { lenaResource = line; break; } } assertNotNull(lenaResource); assertTrue(lenaResource.contains("public")); assertTrue(lenaResource.contains("static")); assertFalse(lenaResource.contains("final")); }