Merge "Remove the default java tasks and fix packaging java res"
diff --git a/builder/src/main/java/com/android/builder/AndroidBuilder.java b/builder/src/main/java/com/android/builder/AndroidBuilder.java
index fb91ca6..8eaa18a 100644
--- a/builder/src/main/java/com/android/builder/AndroidBuilder.java
+++ b/builder/src/main/java/com/android/builder/AndroidBuilder.java
@@ -35,9 +35,9 @@
 import com.android.prefs.AndroidLocation.AndroidLocationException;
 import com.android.sdklib.IAndroidTarget;
 import com.android.sdklib.IAndroidTarget.IOptionalLibrary;
-import com.android.sdklib.io.FileOp;
 import com.android.utils.ILogger;
 import com.google.common.collect.Lists;
+import com.google.common.io.Files;
 
 import java.io.File;
 import java.io.FileNotFoundException;
@@ -292,7 +292,7 @@
 
                     mergeLibraryManifests(
                             generatedTestManifest,
-                            mVariant.getFullDirectDependencies(),
+                            mVariant.getDirectLibraries(),
                             new File(outManifestLocation));
                 } catch (IOException e) {
                     throw new RuntimeException(e);
@@ -320,53 +320,71 @@
 
     private void mergeManifest(VariantConfiguration config, String outManifestLocation) {
         try {
-            File mainLocation = config.getDefaultSourceSet().getAndroidManifest();
+            // gather the app manifests: main + buildType and Flavors.
+            File mainManifest = config.getDefaultSourceSet().getAndroidManifest();
+
+            List<File> subManifests = Lists.newArrayList();
+
             File typeLocation = config.getBuildTypeSourceSet().getAndroidManifest();
-            if (typeLocation != null && typeLocation.isFile() == false) {
-                typeLocation = null;
+            if (typeLocation != null && typeLocation.isFile()) {
+                subManifests.add(typeLocation);
             }
 
-            List<File> flavorManifests = Lists.newArrayList();
             for (SourceSet sourceSet : config.getFlavorSourceSets()) {
                 File f = sourceSet.getAndroidManifest();
                 if (f != null && f.isFile()) {
-                    flavorManifests.add(f);
+                    subManifests.add(f);
                 }
             }
 
             // if no manifest to merge, just copy to location
-            if (typeLocation == null && flavorManifests.isEmpty() && !config.hasLibraries()) {
-                new FileOp().copyFile(mainLocation, new File(outManifestLocation));
+            if (subManifests.isEmpty() && !config.hasLibraries()) {
+                Files.copy(mainManifest, new File(outManifestLocation));
             } else {
-                if (!config.hasLibraries()) {
+                File outManifest = new File(outManifestLocation);
 
-                    File appMergeOut = new File(outManifestLocation);
+                // first merge the app manifest.
+                if (!subManifests.isEmpty()) {
+                    File mainManifestOut = outManifest;
 
-                    List<File> manifests = Lists.newArrayList();
-                    if (typeLocation != null) {
-                        manifests.add(typeLocation);
+                    // if there is also libraries, put this in a temp file.
+                    if (config.hasLibraries()) {
+                        // TODO find better way of storing intermediary file?
+                        mainManifestOut = File.createTempFile("manifestMerge", ".xml");
+                        mainManifestOut.deleteOnExit();
                     }
-                    manifests.addAll(flavorManifests);
 
                     ManifestMerger merger = new ManifestMerger(MergerLog.wrapSdkLog(mLogger));
                     if (merger.process(
-                            appMergeOut,
-                            mainLocation,
-                            manifests.toArray(new File[manifests.size()])) == false) {
+                            mainManifestOut,
+                            mainManifest,
+                            subManifests.toArray(new File[subManifests.size()])) == false) {
                         throw new RuntimeException();
                     }
-                } else {
+
+                    // now the main manifest is the newly merged one
+                    mainManifest = mainManifestOut;
+                }
+
+                if (config.hasLibraries()) {
                     // recursively merge all manifests starting with the leaves and up toward the
                     // root (the app)
-                    mergeLibraryManifests(mainLocation, config.getDirectLibraries(),
+                    mergeLibraryManifests(mainManifest, config.getDirectLibraries(),
                             new File(outManifestLocation));
-                    }
+                }
             }
         } catch (IOException e) {
             throw new RuntimeException(e);
         }
     }
 
+    /**
+     * Merges library manifests into a main manifest.
+     * @param mainManifest the main manifest
+     * @param directLibraries the libraries to merge
+     * @param outManifest the output file
+     * @throws IOException
+     */
     private void mergeLibraryManifests(
             File mainManifest,
             Iterable<AndroidDependency> directLibraries,
@@ -806,6 +824,18 @@
                 }
             }
 
+            // add the resources from the jar files.
+            List<JarDependency> jars = mVariant.getJars();
+            if (jars != null) {
+                for (JarDependency jar : jars) {
+                    packager.addResourcesFromJar(new File(jar.getLocation()));
+                }
+            }
+
+            // add the resources from the libs jar files
+            List<AndroidDependency> libs = mVariant.getDirectLibraries();
+            addLibJavaResourcesToPackager(packager, libs);
+
             // also add resources from library projects and jars
             if (jniLibsLocation != null) {
                 packager.addNativeLibraries(jniLibsLocation);
@@ -818,4 +848,16 @@
             throw new RuntimeException(e);
         }
     }
+
+    private void addLibJavaResourcesToPackager(Packager packager, List<AndroidDependency> libs)
+            throws PackagerException, SealedPackageException, DuplicateFileException {
+        if (libs != null) {
+            for (AndroidDependency lib : libs) {
+                packager.addResourcesFromJar(lib.getJarFile());
+
+                // recursively add the dependencies of this library.
+                addLibJavaResourcesToPackager(packager, lib.getDependencies());
+            }
+        }
+    }
 }
diff --git a/builder/src/main/java/com/android/builder/VariantConfiguration.java b/builder/src/main/java/com/android/builder/VariantConfiguration.java
index 8a5e392..aac7e79 100644
--- a/builder/src/main/java/com/android/builder/VariantConfiguration.java
+++ b/builder/src/main/java/com/android/builder/VariantConfiguration.java
@@ -57,13 +57,13 @@
 
     private List<JarDependency> mJars;
 
-    /** List of direct library project dependencies. Each object defines its own dependencies. */
-    private final List<AndroidDependency> mDirectLibraryProjects = Lists.newArrayList();
+    /** List of direct library dependencies. Each object defines its own dependencies. */
+    private final List<AndroidDependency> mDirectLibraries = Lists.newArrayList();
 
-    /** list of all library project dependencies in the flat list.
+    /** list of all library dependencies in a flat list.
      * The order is based on the order needed to call aapt: earlier libraries override resources
      * of latter ones. */
-    private final List<AndroidDependency> mFlatLibraryProjects = Lists.newArrayList();
+    private final List<AndroidDependency> mFlatLibraries = Lists.newArrayList();
 
     public static enum Type {
         DEFAULT, LIBRARY, TEST;
@@ -128,6 +128,12 @@
 
         mMergedFlavor = mDefaultConfig;
 
+        if (testedConfig != null &&
+                testedConfig.mType == Type.LIBRARY &&
+                testedConfig.mOutput != null) {
+            mDirectLibraries.add(testedConfig.mOutput);
+        }
+
         validate();
     }
 
@@ -151,47 +157,31 @@
         mJars = jars;
     }
 
-    /**
-     * Set the Library Project dependencies.
-     * @param directLibraryProjects list of direct dependencies. Each library object should contain
-     *            its own dependencies.
-     */
-    public void setAndroidDependencies(@NonNull List<AndroidDependency> directLibraryProjects) {
-        if (directLibraryProjects != null) {
-            mDirectLibraryProjects.addAll(directLibraryProjects);
-        }
-
-        resolveIndirectLibraryDependencies(getFullDirectDependencies(), mFlatLibraryProjects);
+    public List<JarDependency> getJars() {
+        return mJars;
     }
 
     /**
-     * Returns all direct dependencies, including the tested config if it's a library itself.
-     * @return
+     * Set the Library Project dependencies.
+     * @param directLibraries list of direct dependencies. Each library object should contain
+     *            its own dependencies.
      */
-    public List<AndroidDependency> getFullDirectDependencies() {
-        if (mTestedConfig != null && mTestedConfig.getType() == Type.LIBRARY) {
-            // in case of a library we merge all the dependencies together.
-            List<AndroidDependency> list = Lists.newArrayListWithExpectedSize(
-                    mDirectLibraryProjects.size() +
-                            mTestedConfig.mDirectLibraryProjects.size() + 1);
-            list.addAll(mDirectLibraryProjects);
-            list.add(mTestedConfig.mOutput);
-            list.addAll(mTestedConfig.mDirectLibraryProjects);
-
-            return list;
+    public void setAndroidDependencies(@NonNull List<AndroidDependency> directLibraries) {
+        if (directLibraries != null) {
+            mDirectLibraries.addAll(directLibraries);
         }
 
-        return mDirectLibraryProjects;
+        resolveIndirectLibraryDependencies(mDirectLibraries, mFlatLibraries);
     }
 
     public String getLibraryPackages() {
-        if (mFlatLibraryProjects.isEmpty()) {
+        if (mFlatLibraries.isEmpty()) {
             return null;
         }
 
         StringBuilder sb = new StringBuilder();
 
-        for (AndroidDependency dep : mFlatLibraryProjects) {
+        for (AndroidDependency dep : mFlatLibraries) {
             File manifest = dep.getManifest();
             String packageName = sManifestParser.getPackage(manifest);
             if (sb.length() > 0) {
@@ -244,15 +234,11 @@
     }
 
     public boolean hasLibraries() {
-        return !mDirectLibraryProjects.isEmpty();
+        return !mDirectLibraries.isEmpty();
     }
 
     public List<AndroidDependency> getDirectLibraries() {
-        return mDirectLibraryProjects;
-    }
-
-    public List<AndroidDependency> getFlatLibraries() {
-        return mFlatLibraryProjects;
+        return mDirectLibraries;
     }
 
     public Type getType() {
@@ -383,7 +369,7 @@
         list.add(mBuildType);
         list.addAll(mFlavorConfigs);
         // TODO: figure out the deps in here.
-//        list.addAll(mFlatLibraryProjects);
+//        list.addAll(mFlatLibraries);
 
         return list;
     }
@@ -411,7 +397,7 @@
             }
         }
 
-        List<AndroidDependency> libs = getFullDirectDependencies();
+        List<AndroidDependency> libs = mDirectLibraries;
         for (AndroidDependency lib : libs) {
             File manifest = lib.getManifest();
             if (manifest != null && manifest.isFile()) {
@@ -449,7 +435,7 @@
             inputs.add(mainResLocation);
         }
 
-        for (AndroidDependency dependency : mFlatLibraryProjects) {
+        for (AndroidDependency dependency : mFlatLibraries) {
             File resFolder = dependency.getResFolder();
             if (resFolder != null) {
                 inputs.add(resFolder);
@@ -467,7 +453,7 @@
     public List<File> getAidlImports() {
         List<File> list = Lists.newArrayList();
 
-        for (AndroidDependency lib : mFlatLibraryProjects) {
+        for (AndroidDependency lib : mFlatLibraries) {
             File aidlLib = lib.getAidlFolder();
             if (aidlLib != null && aidlLib.isDirectory()) {
                 list.add(aidlLib);
@@ -501,7 +487,7 @@
             }
         }
 
-        for (AndroidDependency lib : mFlatLibraryProjects) {
+        for (AndroidDependency lib : mFlatLibraries) {
             classpath.add(lib.getJarFile());
         }
 
diff --git a/gradle/src/main/groovy/com/android/build/gradle/AndroidBasePlugin.groovy b/gradle/src/main/groovy/com/android/build/gradle/AndroidBasePlugin.groovy
index 9dbe187..baac813 100644
--- a/gradle/src/main/groovy/com/android/build/gradle/AndroidBasePlugin.groovy
+++ b/gradle/src/main/groovy/com/android/build/gradle/AndroidBasePlugin.groovy
@@ -73,6 +73,14 @@
         mainSourceSet = project.sourceSets.add("main")
         testSourceSet = project.sourceSets.add("test")
 
+        // TODO remove when moving to custom source sets
+        project.tasks.remove(project.tasks.getByName("classes"))
+        project.tasks.remove(project.tasks.getByName("compileJava"))
+        project.tasks.remove(project.tasks.getByName("processResources"))
+        project.tasks.remove(project.tasks.getByName("testClasses"))
+        project.tasks.remove(project.tasks.getByName("compileTestJava"))
+        project.tasks.remove(project.tasks.getByName("processTestResources"))
+
         project.tasks.assemble.description =
             "Assembles all variants of all applications and secondary packages."
 
diff --git a/gradle/src/main/groovy/com/android/build/gradle/AndroidLibraryPlugin.groovy b/gradle/src/main/groovy/com/android/build/gradle/AndroidLibraryPlugin.groovy
index 3b6155d..3217612 100644
--- a/gradle/src/main/groovy/com/android/build/gradle/AndroidLibraryPlugin.groovy
+++ b/gradle/src/main/groovy/com/android/build/gradle/AndroidLibraryPlugin.groovy
@@ -51,6 +51,14 @@
         def debugSourceSet = project.sourceSets.add(BuildType.DEBUG)
         def releaseSourceSet = project.sourceSets.add(BuildType.RELEASE)
 
+        // TODO remove when moving to custom source sets
+        project.tasks.remove(project.tasks.getByName("debugClasses"))
+        project.tasks.remove(project.tasks.getByName("compileDebugJava"))
+        project.tasks.remove(project.tasks.getByName("processDebugResources"))
+        project.tasks.remove(project.tasks.getByName("releaseClasses"))
+        project.tasks.remove(project.tasks.getByName("compileReleaseJava"))
+        project.tasks.remove(project.tasks.getByName("processReleaseResources"))
+
         debugBuildTypeData = new BuildTypeData(extension.debug, debugSourceSet, project)
         releaseBuildTypeData = new BuildTypeData(extension.release, releaseSourceSet, project)
         project.tasks.assemble.dependsOn debugBuildTypeData.assembleTask
@@ -120,6 +128,10 @@
         // jar the classes.
         Jar jar = project.tasks.add("${buildTypeData.buildType.name}Jar", Jar);
         jar.from(variant.compileTask.outputs);
+        // TODO: replace with proper ProcessResources task with properly configured SourceDirectorySet
+        jar.from(defaultConfigData.androidSourceSet.javaResources);
+        jar.from(buildTypeData.androidSourceSet.javaResources);
+
         jar.destinationDir = project.file("$project.buildDir/$DIR_BUNDLES/${variant.dirName}")
         jar.archiveName = "classes.jar"
         String packageName = variantConfig.getPackageFromManifest().replace('.', '/');
@@ -165,7 +177,7 @@
 
             @Override
             List<AndroidDependency> getDependencies() {
-                return []
+                return variantConfig.directLibraries
             }
         };
 
diff --git a/gradle/src/main/groovy/com/android/build/gradle/AndroidPlugin.groovy b/gradle/src/main/groovy/com/android/build/gradle/AndroidPlugin.groovy
index 7d31e86..7eff8ed 100644
--- a/gradle/src/main/groovy/com/android/build/gradle/AndroidPlugin.groovy
+++ b/gradle/src/main/groovy/com/android/build/gradle/AndroidPlugin.groovy
@@ -81,6 +81,11 @@
 
         def sourceSet = project.sourceSets.add(buildType.name)
 
+        // TODO remove when moving to custom source sets
+        project.tasks.remove(project.tasks.getByName("${buildType.name}Classes"))
+        project.tasks.remove(project.tasks.getByName("compile${buildType.name.capitalize()}Java"))
+        project.tasks.remove(project.tasks.getByName("process${buildType.name.capitalize()}Resources"))
+
         BuildTypeData buildTypeData = new BuildTypeData(buildType, sourceSet, project)
         project.tasks.assemble.dependsOn buildTypeData.assembleTask
 
@@ -96,7 +101,16 @@
         }
 
         def mainSourceSet = project.sourceSets.add(productFlavor.name)
-        def testSourceSet = project.sourceSets.add("test${productFlavor.name.capitalize()}")
+        String testName = "test${productFlavor.name.capitalize()}"
+        def testSourceSet = project.sourceSets.add(testName)
+
+        // TODO remove when moving to custom source sets
+        project.tasks.remove(project.tasks.getByName("${productFlavor.name}Classes"))
+        project.tasks.remove(project.tasks.getByName("compile${productFlavor.name.capitalize()}Java"))
+        project.tasks.remove(project.tasks.getByName("process${productFlavor.name.capitalize()}Resources"))
+        project.tasks.remove(project.tasks.getByName("${testName}Classes"))
+        project.tasks.remove(project.tasks.getByName("compile${testName.capitalize()}Java"))
+        project.tasks.remove(project.tasks.getByName("process${testName.capitalize()}Resources"))
 
         ProductFlavorData productFlavorData = new ProductFlavorData(
                 productFlavor, mainSourceSet, testSourceSet, project)
diff --git a/testapps/libsTest/app/src/main/java/com/android/tests/libstest/app/App.txt b/testapps/libsTest/app/src/main/resources/com/android/tests/libstest/app/App.txt
similarity index 100%
rename from testapps/libsTest/app/src/main/java/com/android/tests/libstest/app/App.txt
rename to testapps/libsTest/app/src/main/resources/com/android/tests/libstest/app/App.txt
diff --git a/testapps/libsTest/lib1/src/main/java/com/android/tests/libstest/lib1/Lib1.txt b/testapps/libsTest/lib1/src/main/resources/com/android/tests/libstest/lib1/Lib1.txt
similarity index 100%
rename from testapps/libsTest/lib1/src/main/java/com/android/tests/libstest/lib1/Lib1.txt
rename to testapps/libsTest/lib1/src/main/resources/com/android/tests/libstest/lib1/Lib1.txt
diff --git a/testapps/libsTest/lib2/src/main/java/com/android/tests/libstest/lib2/Lib2.txt b/testapps/libsTest/lib2/src/main/resources/com/android/tests/libstest/lib2/Lib2.txt
similarity index 100%
rename from testapps/libsTest/lib2/src/main/java/com/android/tests/libstest/lib2/Lib2.txt
rename to testapps/libsTest/lib2/src/main/resources/com/android/tests/libstest/lib2/Lib2.txt