aboutsummaryrefslogtreecommitdiff
path: root/builder
diff options
context:
space:
mode:
authorXavier Ducrohet <xav@android.com>2012-12-07 18:50:44 -0800
committerXavier Ducrohet <xav@android.com>2012-12-10 17:01:07 -0800
commitcd3aa604316fa5c6c9486f2cb9caa3eaccd74476 (patch)
tree38455d4e69fb7dd84b1a8647b8f6289a61c60486 /builder
parent3b49b176fcbfe1bbae0f63f769a39a3cb41c79ef (diff)
downloadbuild-cd3aa604316fa5c6c9486f2cb9caa3eaccd74476.tar.gz
Use the ResourceMerger to handle overlay.
This creates a merged res folder that is then fed to aapt. Right now the merged folder does not have its image crunched, nor is it incremental. This means the build will be slower (previously crunching was incremental). Next step is to change aapt to be able to crunch single images and then make the merging itself incremental. Details: The processImage task is replaced by mergeResourceTask. It is also used for library project that had to merge their resources before bundling, so the previous copy task is removed and the merge is done directly in the bundle folder. The API for AndroidBuilder is changed to reflect those changes. processResource now only takes one res folder which is meant to be the merged one. The getResourceInputs on VariantConfig is changed to return a list of ResourceSets (except not actual ResourceSet since this would load the resources, so instead a list of list of files). Also changed build.gradle for the gradle plugin to have the integration test first deploy the plugin locally in order to use the right one. Change-Id: Ide96f733be835d94518b831baee7ee77b9a61dec
Diffstat (limited to 'builder')
-rw-r--r--builder/src/main/java/com/android/builder/AndroidBuilder.java99
-rw-r--r--builder/src/main/java/com/android/builder/VariantConfiguration.java53
-rw-r--r--builder/src/main/java/com/android/builder/resources/ResourceSet.java9
-rw-r--r--builder/src/main/java/com/android/builder/resources/ValueResourceParser.java10
-rw-r--r--builder/src/test/resources/testData/baseResourceSet/values/values.xml4
5 files changed, 85 insertions, 90 deletions
diff --git a/builder/src/main/java/com/android/builder/AndroidBuilder.java b/builder/src/main/java/com/android/builder/AndroidBuilder.java
index 1ceccdc..55bacb8 100644
--- a/builder/src/main/java/com/android/builder/AndroidBuilder.java
+++ b/builder/src/main/java/com/android/builder/AndroidBuilder.java
@@ -35,6 +35,9 @@ import com.android.builder.internal.signing.SigningInfo;
import com.android.builder.packaging.DuplicateFileException;
import com.android.builder.packaging.PackagerException;
import com.android.builder.packaging.SealedPackageException;
+import com.android.builder.resources.DuplicateResourceException;
+import com.android.builder.resources.ResourceMerger;
+import com.android.builder.resources.ResourceSet;
import com.android.manifmerger.ManifestMerger;
import com.android.manifmerger.MergerLog;
import com.android.prefs.AndroidLocation.AndroidLocationException;
@@ -69,7 +72,7 @@ import static com.google.common.base.Preconditions.checkState;
* {@link #generateBuildConfig(String, boolean, java.util.List, String)}
* {@link #processManifest(java.io.File, java.util.List, java.util.List, int, String, int, int, String)}
* {@link #processTestManifest(String, int, String, String, java.util.List, String)}
- * {@link #processResources(java.io.File, java.io.File, Iterable, java.io.File, java.util.List, String, String, String, String, String, com.android.builder.VariantConfiguration.Type, boolean, AaptOptions)}
+ * {@link #processResources(java.io.File, java.io.File, java.io.File, java.util.List, String, String, String, String, String, com.android.builder.VariantConfiguration.Type, boolean, AaptOptions)}
* {@link #compileAidl(java.util.List, java.io.File, java.util.List)}
* {@link #convertByteCode(Iterable, Iterable, String, DexOptions)}
* {@link #packageApk(String, String, java.util.List, String, String, boolean, boolean, String, String, String, String, String)}
@@ -192,56 +195,48 @@ public class AndroidBuilder {
}
/**
- * Process the images. This optimize the bitmaps and pre-processes the 9-patch files before
- * they can be packaged.
+ * Merge resources together so that they can be fed to aapt.
+ *
+ * This also pre-processes the images (crunches the pngs and processes the 9 patch files)
* This is incremental.
*
* @param resOutputDir where the processed resources are stored.
- * @param inputs the input res folders
+ * @param inputFolders the input resource folders
+ * @throws DuplicateResourceException
* @throws IOException
- * @throws InterruptedException
*/
- public void processImages(@NonNull String resOutputDir, List<File> inputs)
- throws IOException, InterruptedException {
+ public void mergeResources(@NonNull String resOutputDir, @Nullable List<List<File>> inputFolders)
+ throws DuplicateResourceException, IOException {
checkState(mTarget != null, "Target not set.");
checkNotNull(resOutputDir, "resOutputDir cannot be null.");
- if (inputs == null || inputs.isEmpty()) {
+ if (inputFolders == null || inputFolders.isEmpty()) {
return;
}
- // launch aapt: create the command line
- ArrayList<String> command = Lists.newArrayList();
+ ResourceMerger merger = new ResourceMerger();
- @SuppressWarnings("deprecation")
- String aaptPath = mTarget.getPath(IAndroidTarget.AAPT);
+ boolean runMerger = false;
- command.add(aaptPath);
- command.add("crunch");
-
- if (mVerboseExec) {
- command.add("-v");
- }
+ for (List<File> setFolders : inputFolders) {
+ // create a set and add all the folders from the list to it.
+ ResourceSet set = new ResourceSet();
+ for (File folder : setFolders) {
+ if (folder.isDirectory()) {
+ set.addSource(folder);
+ }
+ }
- boolean runCommand = false;
- for (File input : inputs) {
- if (input.isDirectory()) {
- command.add("-S");
- command.add(input.getAbsolutePath());
- runCommand = true;
+ if (!set.isEmpty()) {
+ merger.addResourceSet(set);
+ runMerger = true;
}
}
- if (!runCommand) {
- return;
+ if (runMerger) {
+ ResourceSet mergedSet = merger.getMergedSet();
+ mergedSet.writeTo(new File(resOutputDir));
}
-
- command.add("-C");
- command.add(resOutputDir);
-
- mLogger.info("processImages command: %s", command.toString());
-
- mCmdLineRunner.runCmdLine(command);
}
/**
@@ -497,9 +492,8 @@ public class AndroidBuilder {
* TODO support 2+ assets folders.
*
* @param manifestFile the location of the manifest file
- * @param preprocessResDir the pre-processed folder
- * @param resInputs the res folder inputs
- * @param assetsDir the main asset folder
+ * @param resFolder the merged res folder
+ * @param assetsDir the merged asset folder
* @param libraries the flat list of libraries
* @param sourceOutputDir optional source folder to generate R.java
* @param resPackageOutput optional filepath for packaged resources
@@ -514,8 +508,7 @@ public class AndroidBuilder {
*/
public void processResources(
@NonNull File manifestFile,
- @Nullable File preprocessResDir,
- @NonNull Iterable<File> resInputs,
+ @NonNull File resFolder,
@Nullable File assetsDir,
@NonNull List<SymbolFileProvider> libraries,
@Nullable String packageOverride,
@@ -530,7 +523,7 @@ public class AndroidBuilder {
checkState(mTarget != null, "Target not set.");
checkNotNull(manifestFile, "manifestFile cannot be null.");
- checkNotNull(resInputs, "resInputs cannot be null.");
+ checkNotNull(resFolder, "resFolder cannot be null.");
checkNotNull(libraries, "libraries cannot be null.");
checkNotNull(options, "options cannot be null.");
// if both output types are empty, then there's nothing to do and this is an error
@@ -551,7 +544,9 @@ public class AndroidBuilder {
}
command.add("-f");
- command.add("--no-crunch");
+
+ //TODO: reenable when we can crunch per-file in the ResourceMerger
+ // command.add("--no-crunch");
// inputs
command.add("-I");
@@ -560,31 +555,11 @@ public class AndroidBuilder {
command.add("-M");
command.add(manifestFile.getAbsolutePath());
- if (preprocessResDir != null && preprocessResDir.isDirectory()) {
+ if (resFolder.isDirectory()) {
command.add("-S");
- command.add(preprocessResDir.getAbsolutePath());
+ command.add(resFolder.getAbsolutePath());
}
- for (File resFolder : resInputs) {
- if (resFolder.isDirectory()) {
- command.add("-S");
- command.add(resFolder.getAbsolutePath());
- }
- }
-
- command.add("--auto-add-overlay");
-
-
-// if (typeAssetsLocation != null) {
-// command.add("-A");
-// command.add(typeAssetsLocation);
-// }
-//
-// if (flavorAssetsLocation != null) {
-// command.add("-A");
-// command.add(flavorAssetsLocation);
-// }
-
if (assetsDir != null && assetsDir.isDirectory()) {
command.add("-A");
command.add(assetsDir.getAbsolutePath());
diff --git a/builder/src/main/java/com/android/builder/VariantConfiguration.java b/builder/src/main/java/com/android/builder/VariantConfiguration.java
index 7088f6c..d7bcf86 100644
--- a/builder/src/main/java/com/android/builder/VariantConfiguration.java
+++ b/builder/src/main/java/com/android/builder/VariantConfiguration.java
@@ -24,6 +24,7 @@ import com.google.common.collect.Sets;
import java.io.File;
import java.util.Collection;
+import java.util.Collections;
import java.util.List;
import java.util.Set;
@@ -475,36 +476,50 @@ public class VariantConfiguration {
}
/**
- * Returns the dynamic list of resource folders based on the configuration, its dependencies,
+ * Returns the dynamic list of resource sets based on the configuration, its dependencies,
* as well as tested config if applicable (test of a library).
- * @return a list of input resource folders.
+ *
+ * The list is a list of folders. Each list of folder represents a
+ * {@link com.android.builder.resources.ResourceSet}.
+ *
+ * The list is ordered in ascending order of importance, meaning the first set is meant to be
+ * overridden by the 2nd one and so on. This is meant to facilitate usage of the list in a
+ * {@link com.android.builder.resources.ResourceMerger}.
+ *
+ * @return a list of list of resource folders.
*/
- public List<File> getResourceInputs() {
- List<File> inputs = Lists.newArrayList();
+ @NonNull public List<List<File>> getResourceSets() {
+ List<List<File>> inputs = Lists.newArrayList();
- if (mBuildTypeSourceProvider != null) {
- File typeResLocation = mBuildTypeSourceProvider.getResourcesDir();
- if (typeResLocation != null) {
- inputs.add(typeResLocation);
+ // the list of dependency must be reversed to use the right overlay order.
+ for (int n = mFlatLibraries.size() - 1 ; n >= 0 ; n--) {
+ AndroidDependency dependency = mFlatLibraries.get(n);
+ File resFolder = dependency.getResFolder();
+ if (resFolder != null) {
+ inputs.add(Collections.singletonList(resFolder));
}
}
- for (SourceProvider sourceProvider : mFlavorSourceProviders) {
+ // TODO: fix when flavors and types have more than one folder.
+ File mainResLocation = mDefaultSourceProvider.getResourcesDir();
+ if (mainResLocation != null) {
+ inputs.add(Collections.singletonList(mainResLocation));
+ }
+
+ // the list of flavor must be reversed to use the right overlay order.
+ for (int n = mFlavorSourceProviders.size() - 1; n >= 0 ; n--) {
+ SourceProvider sourceProvider = mFlavorSourceProviders.get(n);
+
File flavorResLocation = sourceProvider.getResourcesDir();
if (flavorResLocation != null) {
- inputs.add(flavorResLocation);
+ inputs.add(Collections.singletonList(flavorResLocation));
}
}
- File mainResLocation = mDefaultSourceProvider.getResourcesDir();
- if (mainResLocation != null) {
- inputs.add(mainResLocation);
- }
-
- for (AndroidDependency dependency : mFlatLibraries) {
- File resFolder = dependency.getResFolder();
- if (resFolder != null) {
- inputs.add(resFolder);
+ if (mBuildTypeSourceProvider != null) {
+ File typeResLocation = mBuildTypeSourceProvider.getResourcesDir();
+ if (typeResLocation != null) {
+ inputs.add(Collections.singletonList(typeResLocation));
}
}
diff --git a/builder/src/main/java/com/android/builder/resources/ResourceSet.java b/builder/src/main/java/com/android/builder/resources/ResourceSet.java
index 7fd7cb5..dcc2a93 100644
--- a/builder/src/main/java/com/android/builder/resources/ResourceSet.java
+++ b/builder/src/main/java/com/android/builder/resources/ResourceSet.java
@@ -51,11 +51,6 @@ import java.util.Map;
public class ResourceSet {
/**
- * Resource files
- */
- //private final List<ResourceFile> mFiles = Lists.newArrayList();
-
- /**
* The key is the {@link com.android.builder.resources.Resource#getKey()}.
*/
private final Map<String, Resource> mItems = Maps.newHashMap();
@@ -81,6 +76,10 @@ public class ResourceSet {
return mItems.size();
}
+ public boolean isEmpty() {
+ return mItems.isEmpty();
+ }
+
public Collection<Resource> getResources() {
return mItems.values();
}
diff --git a/builder/src/main/java/com/android/builder/resources/ValueResourceParser.java b/builder/src/main/java/com/android/builder/resources/ValueResourceParser.java
index 2ff61df..99b8c7d 100644
--- a/builder/src/main/java/com/android/builder/resources/ValueResourceParser.java
+++ b/builder/src/main/java/com/android/builder/resources/ValueResourceParser.java
@@ -32,6 +32,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
+import java.util.Collections;
import java.util.List;
import static com.android.SdkConstants.ATTR_NAME;
@@ -51,11 +52,12 @@ class ValueResourceParser {
List<Resource> parseFile() throws FileNotFoundException {
Document document = parseDocument();
- NodeList nodes = document.getChildNodes();
-
// get the root node
- Node rootNode = nodes.item(0);
- nodes = rootNode.getChildNodes();
+ Node rootNode = document.getDocumentElement();
+ if (rootNode == null) {
+ return Collections.emptyList();
+ }
+ NodeList nodes = rootNode.getChildNodes();
List<Resource> resources = Lists.newArrayListWithExpectedSize(nodes.getLength());
diff --git a/builder/src/test/resources/testData/baseResourceSet/values/values.xml b/builder/src/test/resources/testData/baseResourceSet/values/values.xml
index ee38060..0da935f 100644
--- a/builder/src/test/resources/testData/baseResourceSet/values/values.xml
+++ b/builder/src/test/resources/testData/baseResourceSet/values/values.xml
@@ -1,4 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Some comment to throw off the XML parser if it doesn't properly handle
+ * Document.getDocumentElement().
+-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<drawable name="color_drawable">#ffffffff</drawable>