blob: e4b84351c4dce0292693a3bf683838d748a6be77 [file] [log] [blame]
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.builder.core;
import com.android.annotations.NonNull;
import com.android.builder.dependency.SymbolFileProvider;
import com.android.builder.model.AaptOptions;
import com.android.ide.common.process.ProcessInfo;
import com.android.sdklib.BuildToolInfo;
import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.SdkManager;
import com.android.sdklib.repository.FullRevision;
import com.android.utils.ILogger;
import com.android.utils.StdLogger;
import com.google.common.collect.ImmutableList;
import junit.framework.TestCase;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import java.io.File;
import java.util.List;
import java.util.Map;
/**
* Tests for {@link AaptPackageProcessBuilder} class
*/
public class AaptPackageProcessBuilderTest extends TestCase {
@Mock
AaptOptions mAaptOptions;
BuildToolInfo mBuildToolInfo;
IAndroidTarget mIAndroidTarget;
ILogger mLogger = new StdLogger(StdLogger.Level.VERBOSE);
@Override
public void setUp() throws Exception {
super.setUp();
MockitoAnnotations.initMocks(this);
SdkManager sdkManager = SdkManager.createManager(getSdkDir().getAbsolutePath(), mLogger);
assert sdkManager != null;
mBuildToolInfo = sdkManager.getBuildTool(FullRevision.parseRevision("21"));
if (mBuildToolInfo == null) {
throw new RuntimeException("Test requires build-tools 21");
}
for (IAndroidTarget iAndroidTarget : sdkManager.getTargets()) {
if (iAndroidTarget.getVersion().getApiLevel() == 21) {
mIAndroidTarget = iAndroidTarget;
}
}
if (mIAndroidTarget == null) {
throw new RuntimeException("Test requires android-21");
}
}
public void testAndroidManifestPackaging() {
File virtualAndroidManifestFile = new File("/path/to/non/existent/file");
AaptPackageProcessBuilder aaptPackageProcessBuilder =
new AaptPackageProcessBuilder(virtualAndroidManifestFile, mAaptOptions);
aaptPackageProcessBuilder.setResPackageOutput("/path/to/non/existent/dir");
ProcessInfo processInfo = aaptPackageProcessBuilder
.build(mBuildToolInfo, mIAndroidTarget, mLogger);
List<String> command = processInfo.getArgs();
assertTrue("/path/to/non/existent/file".equals(command.get(command.indexOf("-M") + 1)));
assertTrue("/path/to/non/existent/dir".equals(command.get(command.indexOf("-F") + 1)));
assertTrue(command.get(command.indexOf("-I") + 1).contains("android.jar"));
}
public void testResourcesPackaging() {
File virtualAndroidManifestFile = new File("/path/to/non/existent/file");
File assetsFolder = Mockito.mock(File.class);
Mockito.when(assetsFolder.isDirectory()).thenReturn(true);
Mockito.when(assetsFolder.getAbsolutePath()).thenReturn("/path/to/assets/folder");
File resFolder = Mockito.mock(File.class);
Mockito.when(resFolder.isDirectory()).thenReturn(true);
Mockito.when(resFolder.getAbsolutePath()).thenReturn("/path/to/res/folder");
AaptPackageProcessBuilder aaptPackageProcessBuilder =
new AaptPackageProcessBuilder(virtualAndroidManifestFile, mAaptOptions);
aaptPackageProcessBuilder.setResPackageOutput("/path/to/non/existent/dir")
.setAssetsFolder(assetsFolder)
.setResFolder(resFolder)
.setPackageForR("com.example.package.forR")
.setSourceOutputDir("path/to/source/output/dir")
.setLibraries(ImmutableList.of(Mockito.mock(SymbolFileProvider.class)))
.setType(VariantType.DEFAULT);
ProcessInfo processInfo = aaptPackageProcessBuilder
.build(mBuildToolInfo, mIAndroidTarget, mLogger);
List<String> command = processInfo.getArgs();
assertTrue("/path/to/non/existent/file".equals(command.get(command.indexOf("-M") + 1)));
assertTrue("/path/to/non/existent/dir".equals(command.get(command.indexOf("-F") + 1)));
assertTrue(command.get(command.indexOf("-I") + 1).contains("android.jar"));
assertTrue("/path/to/res/folder".equals(command.get(command.indexOf("-S") + 1)));
assertTrue("/path/to/assets/folder".equals(command.get(command.indexOf("-A") + 1)));
assertTrue("path/to/source/output/dir".equals(command.get(command.indexOf("-J") + 1)));
assertTrue("com.example.package.forR".equals(command.get(command.indexOf("--custom-package") + 1)));
assertTrue(command.indexOf("-f") != -1);
assertTrue(command.indexOf("--no-crunch") != -1);
assertTrue(command.indexOf("-0") != -1);
assertTrue(command.indexOf("apk") != -1);
}
public void testResourcesPackagingForTest() {
File virtualAndroidManifestFile = new File("/path/to/non/existent/file");
File assetsFolder = Mockito.mock(File.class);
Mockito.when(assetsFolder.isDirectory()).thenReturn(true);
Mockito.when(assetsFolder.getAbsolutePath()).thenReturn("/path/to/assets/folder");
File resFolder = Mockito.mock(File.class);
Mockito.when(resFolder.isDirectory()).thenReturn(true);
Mockito.when(resFolder.getAbsolutePath()).thenReturn("/path/to/res/folder");
AaptPackageProcessBuilder aaptPackageProcessBuilder =
new AaptPackageProcessBuilder(virtualAndroidManifestFile, mAaptOptions);
aaptPackageProcessBuilder.setResPackageOutput("/path/to/non/existent/dir")
.setAssetsFolder(assetsFolder)
.setResFolder(resFolder)
.setPackageForR("com.example.package.forR")
.setSourceOutputDir("path/to/source/output/dir")
.setLibraries(ImmutableList.of(Mockito.mock(SymbolFileProvider.class)))
.setType(VariantType.ANDROID_TEST);
ProcessInfo processInfo = aaptPackageProcessBuilder
.build(mBuildToolInfo, mIAndroidTarget, mLogger);
List<String> command = processInfo.getArgs();
assertTrue("/path/to/non/existent/file".equals(command.get(command.indexOf("-M") + 1)));
assertTrue("/path/to/non/existent/dir".equals(command.get(command.indexOf("-F") + 1)));
assertTrue(command.get(command.indexOf("-I") + 1).contains("android.jar"));
assertTrue("/path/to/res/folder".equals(command.get(command.indexOf("-S") + 1)));
assertTrue("/path/to/assets/folder".equals(command.get(command.indexOf("-A") + 1)));
assertTrue("path/to/source/output/dir".equals(command.get(command.indexOf("-J") + 1)));
assertTrue(command.indexOf("--custom-package") == -1);
assertTrue(command.indexOf("-f") != -1);
assertTrue(command.indexOf("--no-crunch") != -1);
assertTrue(command.indexOf("-0") != -1);
assertTrue(command.indexOf("apk") != -1);
}
public void testResourcesPackagingForLibrary() {
File virtualAndroidManifestFile = new File("/path/to/non/existent/file");
File assetsFolder = Mockito.mock(File.class);
Mockito.when(assetsFolder.isDirectory()).thenReturn(true);
Mockito.when(assetsFolder.getAbsolutePath()).thenReturn("/path/to/assets/folder");
File resFolder = Mockito.mock(File.class);
Mockito.when(resFolder.isDirectory()).thenReturn(true);
Mockito.when(resFolder.getAbsolutePath()).thenReturn("/path/to/res/folder");
AaptPackageProcessBuilder aaptPackageProcessBuilder =
new AaptPackageProcessBuilder(virtualAndroidManifestFile, mAaptOptions);
aaptPackageProcessBuilder.setResPackageOutput("/path/to/non/existent/dir")
.setAssetsFolder(assetsFolder)
.setResFolder(resFolder)
.setPackageForR("com.example.package.forR")
.setSourceOutputDir("path/to/source/output/dir")
.setLibraries(ImmutableList.of(Mockito.mock(SymbolFileProvider.class)))
.setType(VariantType.LIBRARY);
ProcessInfo processInfo = aaptPackageProcessBuilder
.build(mBuildToolInfo, mIAndroidTarget, mLogger);
List<String> command = processInfo.getArgs();
assertTrue("/path/to/non/existent/file".equals(command.get(command.indexOf("-M") + 1)));
assertTrue("/path/to/non/existent/dir".equals(command.get(command.indexOf("-F") + 1)));
assertTrue(command.get(command.indexOf("-I") + 1).contains("android.jar"));
assertTrue("/path/to/res/folder".equals(command.get(command.indexOf("-S") + 1)));
assertTrue("/path/to/assets/folder".equals(command.get(command.indexOf("-A") + 1)));
assertTrue("path/to/source/output/dir".equals(command.get(command.indexOf("-J") + 1)));
assertTrue(command.indexOf("--non-constant-id") != -1);
assertTrue(command.indexOf("-f") != -1);
assertTrue(command.indexOf("--no-crunch") != -1);
assertTrue(command.indexOf("-0") != -1);
assertTrue(command.indexOf("apk") != -1);
}
public void testSplitResourcesPackaging() {
File virtualAndroidManifestFile = new File("/path/to/non/existent/file");
File assetsFolder = Mockito.mock(File.class);
Mockito.when(assetsFolder.isDirectory()).thenReturn(true);
Mockito.when(assetsFolder.getAbsolutePath()).thenReturn("/path/to/assets/folder");
File resFolder = Mockito.mock(File.class);
Mockito.when(resFolder.isDirectory()).thenReturn(true);
Mockito.when(resFolder.getAbsolutePath()).thenReturn("/path/to/res/folder");
AaptPackageProcessBuilder aaptPackageProcessBuilder =
new AaptPackageProcessBuilder(virtualAndroidManifestFile, mAaptOptions);
aaptPackageProcessBuilder.setResPackageOutput("/path/to/non/existent/dir")
.setAssetsFolder(assetsFolder)
.setResFolder(resFolder)
.setPackageForR("com.example.package.forR")
.setSourceOutputDir("path/to/source/output/dir")
.setLibraries(ImmutableList.of(Mockito.mock(SymbolFileProvider.class)))
.setType(VariantType.DEFAULT)
.setSplits(ImmutableList.of("mdpi", "hdpi"));
ProcessInfo processInfo = aaptPackageProcessBuilder
.build(mBuildToolInfo, mIAndroidTarget, mLogger);
List<String> command = processInfo.getArgs();
assertTrue("/path/to/non/existent/file".equals(command.get(command.indexOf("-M") + 1)));
assertTrue("/path/to/non/existent/dir".equals(command.get(command.indexOf("-F") + 1)));
assertTrue(command.get(command.indexOf("-I") + 1).contains("android.jar"));
assertTrue("/path/to/res/folder".equals(command.get(command.indexOf("-S") + 1)));
assertTrue("/path/to/assets/folder".equals(command.get(command.indexOf("-A") + 1)));
assertTrue("path/to/source/output/dir".equals(command.get(command.indexOf("-J") + 1)));
assertTrue("com.example.package.forR".equals(command.get(command.indexOf("--custom-package") + 1)));
assertTrue(command.indexOf("-f") != -1);
assertTrue(command.indexOf("--no-crunch") != -1);
assertTrue(command.indexOf("-0") != -1);
assertTrue(command.indexOf("apk") != -1);
assertTrue("--split".equals(command.get(command.indexOf("mdpi") - 1)));
assertTrue("--split".equals(command.get(command.indexOf("hdpi") - 1)));
assertTrue(command.indexOf("--preferred-density") == -1);
}
public void testPre21ResourceConfigsAndPreferredDensity() {
File virtualAndroidManifestFile = new File("/path/to/non/existent/file");
File assetsFolder = Mockito.mock(File.class);
Mockito.when(assetsFolder.isDirectory()).thenReturn(true);
Mockito.when(assetsFolder.getAbsolutePath()).thenReturn("/path/to/assets/folder");
File resFolder = Mockito.mock(File.class);
Mockito.when(resFolder.isDirectory()).thenReturn(true);
Mockito.when(resFolder.getAbsolutePath()).thenReturn("/path/to/res/folder");
AaptPackageProcessBuilder aaptPackageProcessBuilder =
new AaptPackageProcessBuilder(virtualAndroidManifestFile, mAaptOptions);
aaptPackageProcessBuilder.setResPackageOutput("/path/to/non/existent/dir")
.setAssetsFolder(assetsFolder)
.setResFolder(resFolder)
.setPackageForR("com.example.package.forR")
.setSourceOutputDir("path/to/source/output/dir")
.setLibraries(ImmutableList.of(Mockito.mock(SymbolFileProvider.class)))
.setType(VariantType.DEFAULT)
.setResourceConfigs(ImmutableList.of("res1", "res2"))
.setPreferredDensity("xhdpi");
SdkManager sdkManager = SdkManager.createManager(getSdkDir().getAbsolutePath(), mLogger);
assert sdkManager != null;
BuildToolInfo buildToolInfo = sdkManager.getBuildTool(FullRevision.parseRevision("20"));
if (buildToolInfo == null) {
throw new RuntimeException("Test requires build-tools 20");
}
IAndroidTarget androidTarget = null;
for (IAndroidTarget iAndroidTarget : sdkManager.getTargets()) {
if (iAndroidTarget.getVersion().getApiLevel() < 20) {
androidTarget = iAndroidTarget;
break;
}
}
if (androidTarget == null) {
throw new RuntimeException("Test requires pre android-21");
}
ProcessInfo processInfo = aaptPackageProcessBuilder
.build(buildToolInfo, androidTarget, mLogger);
List<String> command = processInfo.getArgs();
assertTrue("res1,res2,xhdpi,nodpi".equals(command.get(command.indexOf("-c") + 1)));
assertTrue(command.indexOf("--preferred-density") == -1);
}
public void testPost21ResourceConfigsAndPreferredDensity() {
File virtualAndroidManifestFile = new File("/path/to/non/existent/file");
File assetsFolder = Mockito.mock(File.class);
Mockito.when(assetsFolder.isDirectory()).thenReturn(true);
Mockito.when(assetsFolder.getAbsolutePath()).thenReturn("/path/to/assets/folder");
File resFolder = Mockito.mock(File.class);
Mockito.when(resFolder.isDirectory()).thenReturn(true);
Mockito.when(resFolder.getAbsolutePath()).thenReturn("/path/to/res/folder");
AaptPackageProcessBuilder aaptPackageProcessBuilder =
new AaptPackageProcessBuilder(virtualAndroidManifestFile, mAaptOptions);
aaptPackageProcessBuilder.setResPackageOutput("/path/to/non/existent/dir")
.setAssetsFolder(assetsFolder)
.setResFolder(resFolder)
.setPackageForR("com.example.package.forR")
.setSourceOutputDir("path/to/source/output/dir")
.setLibraries(ImmutableList.of(Mockito.mock(SymbolFileProvider.class)))
.setType(VariantType.DEFAULT)
.setResourceConfigs(ImmutableList.of("res1", "res2"))
.setPreferredDensity("xhdpi");
SdkManager sdkManager = SdkManager.createManager(getSdkDir().getAbsolutePath(), mLogger);
assert sdkManager != null;
BuildToolInfo buildToolInfo = sdkManager.getBuildTool(FullRevision.parseRevision("21"));
if (buildToolInfo == null) {
throw new RuntimeException("Test requires build-tools 21");
}
IAndroidTarget androidTarget = null;
for (IAndroidTarget iAndroidTarget : sdkManager.getTargets()) {
if (iAndroidTarget.getVersion().getApiLevel() < 21) {
androidTarget = iAndroidTarget;
break;
}
}
if (androidTarget == null) {
throw new RuntimeException("Test requires pre android-21");
}
ProcessInfo processInfo = aaptPackageProcessBuilder
.build(buildToolInfo, androidTarget, mLogger);
List<String> command = processInfo.getArgs();
assertEquals("res1,res2", command.get(command.indexOf("-c") + 1));
assertEquals("xhdpi", command.get(command.indexOf("--preferred-density") + 1));
}
public void testResConfigAndSplitConflict() {
File virtualAndroidManifestFile = new File("/path/to/non/existent/file");
File assetsFolder = Mockito.mock(File.class);
Mockito.when(assetsFolder.isDirectory()).thenReturn(true);
Mockito.when(assetsFolder.getAbsolutePath()).thenReturn("/path/to/assets/folder");
File resFolder = Mockito.mock(File.class);
Mockito.when(resFolder.isDirectory()).thenReturn(true);
Mockito.when(resFolder.getAbsolutePath()).thenReturn("/path/to/res/folder");
AaptPackageProcessBuilder aaptPackageProcessBuilder =
new AaptPackageProcessBuilder(virtualAndroidManifestFile, mAaptOptions);
aaptPackageProcessBuilder.setResPackageOutput("/path/to/non/existent/dir")
.setAssetsFolder(assetsFolder)
.setResFolder(resFolder)
.setPackageForR("com.example.package.forR")
.setSourceOutputDir("path/to/source/output/dir")
.setLibraries(ImmutableList.of(Mockito.mock(SymbolFileProvider.class)))
.setType(VariantType.DEFAULT)
.setResourceConfigs(
ImmutableList.of("nodpi", "en", "fr", "mdpi", "hdpi", "xxhdpi", "xxxhdpi"))
.setSplits(ImmutableList.of("xhdpi"))
.setPreferredDensity("xhdpi");
SdkManager sdkManager = SdkManager.createManager(getSdkDir().getAbsolutePath(), mLogger);
assert sdkManager != null;
BuildToolInfo buildToolInfo = sdkManager.getBuildTool(FullRevision.parseRevision("21"));
if (buildToolInfo == null) {
throw new RuntimeException("Test requires build-tools 21");
}
IAndroidTarget androidTarget = null;
for (IAndroidTarget iAndroidTarget : sdkManager.getTargets()) {
if (iAndroidTarget.getVersion().getApiLevel() < 21) {
androidTarget = iAndroidTarget;
break;
}
}
if (androidTarget == null) {
throw new RuntimeException("Test requires pre android-21");
}
try {
aaptPackageProcessBuilder.build(buildToolInfo, androidTarget, mLogger);
} catch(Exception expected) {
assertEquals("Splits for densities \"xhdpi\" were configured, yet the resConfigs settings does not include such splits. The resulting split APKs would be empty.\n"
+ "Suggestion : exclude those splits in your build.gradle : \n"
+ "splits {\n"
+ " density {\n"
+ " enable true\n"
+ " exclude \"xhdpi\"\n"
+ " }\n"
+ "}\n"
+ "OR add them to the resConfigs list.", expected.getMessage());
}
}
public void testResConfigAndSplitConflict2() {
File virtualAndroidManifestFile = new File("/path/to/non/existent/file");
File assetsFolder = Mockito.mock(File.class);
Mockito.when(assetsFolder.isDirectory()).thenReturn(true);
Mockito.when(assetsFolder.getAbsolutePath()).thenReturn("/path/to/assets/folder");
File resFolder = Mockito.mock(File.class);
Mockito.when(resFolder.isDirectory()).thenReturn(true);
Mockito.when(resFolder.getAbsolutePath()).thenReturn("/path/to/res/folder");
AaptPackageProcessBuilder aaptPackageProcessBuilder =
new AaptPackageProcessBuilder(virtualAndroidManifestFile, mAaptOptions);
aaptPackageProcessBuilder.setResPackageOutput("/path/to/non/existent/dir")
.setAssetsFolder(assetsFolder)
.setResFolder(resFolder)
.setPackageForR("com.example.package.forR")
.setSourceOutputDir("path/to/source/output/dir")
.setLibraries(ImmutableList.of(Mockito.mock(SymbolFileProvider.class)))
.setType(VariantType.DEFAULT)
.setResourceConfigs(ImmutableList.of("xxxhdpi"))
.setSplits(ImmutableList.of("hdpi", "mdpi", "xxhdpi"))
.setPreferredDensity("xhdpi");
SdkManager sdkManager = SdkManager.createManager(getSdkDir().getAbsolutePath(), mLogger);
assert sdkManager != null;
BuildToolInfo buildToolInfo = sdkManager.getBuildTool(FullRevision.parseRevision("21"));
if (buildToolInfo == null) {
throw new RuntimeException("Test requires build-tools 21");
}
IAndroidTarget androidTarget = null;
for (IAndroidTarget iAndroidTarget : sdkManager.getTargets()) {
if (iAndroidTarget.getVersion().getApiLevel() < 21) {
androidTarget = iAndroidTarget;
break;
}
}
if (androidTarget == null) {
throw new RuntimeException("Test requires pre android-21");
}
try {
aaptPackageProcessBuilder.build(buildToolInfo, androidTarget, mLogger);
} catch(Exception expected) {
assertEquals("Splits for densities \"hdpi,mdpi,xxhdpi\" were configured, yet the "
+ "resConfigs settings does not include such splits. The resulting split APKs "
+ "would be empty.\n"
+ "Suggestion : exclude those splits in your build.gradle : \n"
+ "splits {\n"
+ " density {\n"
+ " enable true\n"
+ " exclude \"hdpi\",\"mdpi\",\"xxhdpi\"\n"
+ " }\n"
+ "}\n"
+ "OR add them to the resConfigs list.", expected.getMessage());
}
}
public void testResConfigAndSplitNoConflict() {
File virtualAndroidManifestFile = new File("/path/to/non/existent/file");
File assetsFolder = Mockito.mock(File.class);
Mockito.when(assetsFolder.isDirectory()).thenReturn(true);
Mockito.when(assetsFolder.getAbsolutePath()).thenReturn("/path/to/assets/folder");
File resFolder = Mockito.mock(File.class);
Mockito.when(resFolder.isDirectory()).thenReturn(true);
Mockito.when(resFolder.getAbsolutePath()).thenReturn("/path/to/res/folder");
AaptPackageProcessBuilder aaptPackageProcessBuilder =
new AaptPackageProcessBuilder(virtualAndroidManifestFile, mAaptOptions);
aaptPackageProcessBuilder.setResPackageOutput("/path/to/non/existent/dir")
.setAssetsFolder(assetsFolder)
.setResFolder(resFolder)
.setPackageForR("com.example.package.forR")
.setSourceOutputDir("path/to/source/output/dir")
.setLibraries(ImmutableList.of(Mockito.mock(SymbolFileProvider.class)))
.setType(VariantType.DEFAULT)
.setResourceConfigs(ImmutableList
.of("en", "fr", "es", "de", "it", "mdpi", "hdpi", "xhdpi", "xxhdpi"))
.setSplits(ImmutableList.of("mdpi", "hdpi", "xhdpi", "xxhdpi"));
SdkManager sdkManager = SdkManager.createManager(getSdkDir().getAbsolutePath(), mLogger);
assert sdkManager != null;
BuildToolInfo buildToolInfo = sdkManager.getBuildTool(FullRevision.parseRevision("20"));
if (buildToolInfo == null) {
throw new RuntimeException("Test requires build-tools 20");
}
IAndroidTarget androidTarget = null;
for (IAndroidTarget iAndroidTarget : sdkManager.getTargets()) {
if (iAndroidTarget.getVersion().getApiLevel() >= 20) {
androidTarget = iAndroidTarget;
break;
}
}
if (androidTarget == null) {
throw new RuntimeException("Test requires pre android 20");
}
ProcessInfo processInfo = aaptPackageProcessBuilder
.build(buildToolInfo, androidTarget, mLogger);
List<String> command = processInfo.getArgs();
assertEquals("en,fr,es,de,it,mdpi,hdpi,xhdpi,xxhdpi",
command.get(command.indexOf("-c") + 1));
assertTrue("--split".equals(command.get(command.indexOf("mdpi") - 1)));
assertTrue("--split".equals(command.get(command.indexOf("hdpi") - 1)));
assertTrue("--split".equals(command.get(command.indexOf("xhdpi") - 1)));
assertTrue("--split".equals(command.get(command.indexOf("xxhdpi") - 1)));
assertEquals(-1, command.indexOf("xxxhdpi"));
}
public void testResConfigWithPreferredDensityFlags() {
File virtualAndroidManifestFile = new File("/path/to/non/existent/file");
File assetsFolder = Mockito.mock(File.class);
Mockito.when(assetsFolder.isDirectory()).thenReturn(true);
Mockito.when(assetsFolder.getAbsolutePath()).thenReturn("/path/to/assets/folder");
File resFolder = Mockito.mock(File.class);
Mockito.when(resFolder.isDirectory()).thenReturn(true);
Mockito.when(resFolder.getAbsolutePath()).thenReturn("/path/to/res/folder");
AaptPackageProcessBuilder aaptPackageProcessBuilder =
new AaptPackageProcessBuilder(virtualAndroidManifestFile, mAaptOptions);
aaptPackageProcessBuilder.setResPackageOutput("/path/to/non/existent/dir")
.setAssetsFolder(assetsFolder)
.setResFolder(resFolder)
.setPackageForR("com.example.package.forR")
.setSourceOutputDir("path/to/source/output/dir")
.setLibraries(ImmutableList.of(Mockito.mock(SymbolFileProvider.class)))
.setType(VariantType.DEFAULT)
.setResourceConfigs(ImmutableList
.of("en", "fr", "es", "de", "it", "mdpi", "hdpi", "xhdpi", "xxhdpi"));
SdkManager sdkManager = SdkManager.createManager(getSdkDir().getAbsolutePath(), mLogger);
assert sdkManager != null;
BuildToolInfo buildToolInfo = sdkManager.getBuildTool(FullRevision.parseRevision("21"));
if (buildToolInfo == null) {
throw new RuntimeException("Test requires build-tools 21");
}
IAndroidTarget androidTarget = null;
for (IAndroidTarget iAndroidTarget : sdkManager.getTargets()) {
if (iAndroidTarget.getVersion().getApiLevel() >= 21) {
androidTarget = iAndroidTarget;
break;
}
}
if (androidTarget == null) {
throw new RuntimeException("Test requires pre android-21");
}
ProcessInfo processInfo = aaptPackageProcessBuilder
.build(buildToolInfo, androidTarget, mLogger);
List<String> command = processInfo.getArgs();
assertEquals("en,fr,es,de,it",
command.get(command.indexOf("-c") + 1));
assertTrue("--preferred-density".equals(command.get(command.indexOf("mdpi") - 1)));
assertTrue("--preferred-density".equals(command.get(command.indexOf("hdpi") -1 )));
assertTrue("--preferred-density".equals(command.get(command.indexOf("xhdpi") -1 )));
assertTrue("--preferred-density".equals(command.get(command.indexOf("xxhdpi") -1 )));
assertEquals(-1, command.indexOf("xxxhdpi"));
}
public void testResConfigAndPreferredDensityConflict() {
File virtualAndroidManifestFile = new File("/path/to/non/existent/file");
File assetsFolder = Mockito.mock(File.class);
Mockito.when(assetsFolder.isDirectory()).thenReturn(true);
Mockito.when(assetsFolder.getAbsolutePath()).thenReturn("/path/to/assets/folder");
File resFolder = Mockito.mock(File.class);
Mockito.when(resFolder.isDirectory()).thenReturn(true);
Mockito.when(resFolder.getAbsolutePath()).thenReturn("/path/to/res/folder");
AaptPackageProcessBuilder aaptPackageProcessBuilder =
new AaptPackageProcessBuilder(virtualAndroidManifestFile, mAaptOptions);
aaptPackageProcessBuilder.setResPackageOutput("/path/to/non/existent/dir")
.setAssetsFolder(assetsFolder)
.setResFolder(resFolder)
.setPackageForR("com.example.package.forR")
.setSourceOutputDir("path/to/source/output/dir")
.setLibraries(ImmutableList.of(Mockito.mock(SymbolFileProvider.class)))
.setType(VariantType.DEFAULT)
.setResourceConfigs(ImmutableList.of( "en", "fr", "es", "de", "it", "mdpi", "hdpi", "xhdpi", "xxhdpi"))
.setSplits(ImmutableList.of("mdpi", "hdpi", "xhdpi", "xxhdpi"))
.setPreferredDensity("hdpi");
SdkManager sdkManager = SdkManager.createManager(getSdkDir().getAbsolutePath(), mLogger);
assert sdkManager != null;
BuildToolInfo buildToolInfo = sdkManager.getBuildTool(FullRevision.parseRevision("21"));
if (buildToolInfo == null) {
throw new RuntimeException("Test requires build-tools 21");
}
IAndroidTarget androidTarget = null;
for (IAndroidTarget iAndroidTarget : sdkManager.getTargets()) {
if (iAndroidTarget.getVersion().getApiLevel() >= 21) {
androidTarget = iAndroidTarget;
break;
}
}
if (androidTarget == null) {
throw new RuntimeException("Test requires pre android-21");
}
try {
aaptPackageProcessBuilder.build(buildToolInfo, androidTarget, mLogger);
} catch (Exception expected) {
assertEquals("When using splits in tools 21 and above, resConfigs should not contain "
+ "any densities. Right now, it contains \"mdpi\",\"hdpi\",\"xhdpi\",\"xxhdpi\"\n"
+ "Suggestion: remove these from resConfigs from build.gradle", expected.getMessage());
}
}
public void testResConfigAndPreferredDensityNoConflict() {
File virtualAndroidManifestFile = new File("/path/to/non/existent/file");
File assetsFolder = Mockito.mock(File.class);
Mockito.when(assetsFolder.isDirectory()).thenReturn(true);
Mockito.when(assetsFolder.getAbsolutePath()).thenReturn("/path/to/assets/folder");
File resFolder = Mockito.mock(File.class);
Mockito.when(resFolder.isDirectory()).thenReturn(true);
Mockito.when(resFolder.getAbsolutePath()).thenReturn("/path/to/res/folder");
AaptPackageProcessBuilder aaptPackageProcessBuilder =
new AaptPackageProcessBuilder(virtualAndroidManifestFile, mAaptOptions);
aaptPackageProcessBuilder.setResPackageOutput("/path/to/non/existent/dir")
.setAssetsFolder(assetsFolder)
.setResFolder(resFolder)
.setPackageForR("com.example.package.forR")
.setSourceOutputDir("path/to/source/output/dir")
.setLibraries(ImmutableList.of(Mockito.mock(SymbolFileProvider.class)))
.setType(VariantType.DEFAULT)
// only languages, no density...
.setResourceConfigs(ImmutableList.of("en", "fr", "es", "de", "it"))
.setPreferredDensity("hdpi");
SdkManager sdkManager = SdkManager.createManager(getSdkDir().getAbsolutePath(), mLogger);
assert sdkManager != null;
BuildToolInfo buildToolInfo = sdkManager.getBuildTool(FullRevision.parseRevision("21"));
if (buildToolInfo == null) {
throw new RuntimeException("Test requires build-tools 21");
}
IAndroidTarget androidTarget = null;
for (IAndroidTarget iAndroidTarget : sdkManager.getTargets()) {
if (iAndroidTarget.getVersion().getApiLevel() >= 21) {
androidTarget = iAndroidTarget;
break;
}
}
if (androidTarget == null) {
throw new RuntimeException("Test requires pre android-21");
}
ProcessInfo processInfo = aaptPackageProcessBuilder
.build(buildToolInfo, androidTarget, mLogger);
List<String> command = processInfo.getArgs();
assertEquals("en,fr,es,de,it", command.get(command.indexOf("-c") + 1));
}
public void testEnvironment() {
File virtualAndroidManifestFile = new File("/path/to/non/existent/file");
AaptPackageProcessBuilder aaptPackageProcessBuilder =
new AaptPackageProcessBuilder(virtualAndroidManifestFile, mAaptOptions);
aaptPackageProcessBuilder.setResPackageOutput("/path/to/non/existent/dir");
// add an env to the builder
aaptPackageProcessBuilder.addEnvironment("foo", "bar");
ProcessInfo processInfo = aaptPackageProcessBuilder
.build(mBuildToolInfo, mIAndroidTarget, mLogger);
Map<String, Object> env = processInfo.getEnvironment();
assertEquals(1, env.size());
assertNotNull(env.get("foo"));
assertEquals("bar", env.get("foo"));
}
/**
* Returns the SDK folder as built from the Android source tree.
* @return the SDK
*/
@NonNull
protected File getSdkDir() {
String androidHome = System.getenv("ANDROID_HOME");
if (androidHome != null) {
File f = new File(androidHome);
if (f.isDirectory()) {
return f;
}
}
throw new IllegalStateException("SDK not defined with ANDROID_HOME");
}
}