am 105fa073: am 6fb1677d: Merge changes I221533ec,I5a8d2ed2 into studio-1.3-dev automerge: 26d0c75 automerge: 815c49f
* commit '105fa073e81382d7911b05a7f79508a99cec486d':
Refactor most application tasks to use CollectionBuilder<Task>
Refactor a number to tasks to use AndroidTaskRegistry.
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/ApplicationTaskManager.groovy b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/ApplicationTaskManager.groovy
index 87f35cf..6f43460 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/ApplicationTaskManager.groovy
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/ApplicationTaskManager.groovy
@@ -25,6 +25,8 @@
import com.android.build.gradle.internal.variant.BaseVariantOutputData
import com.android.builder.core.AndroidBuilder
import com.android.builder.profile.ExecutionType
+import com.android.builder.profile.Recorder
+import com.android.builder.profile.ThreadRecorder
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
@@ -50,56 +52,57 @@
assert variantData instanceof ApplicationVariantData;
ApplicationVariantData appVariantData = (ApplicationVariantData) variantData;
- createAnchorTasks(variantData);
- createCheckManifestTask(variantData);
+ VariantScope variantScope = variantData.getScope()
- handleMicroApp(variantData);
+ createAnchorTasks(tasks, variantScope);
+ createCheckManifestTask(tasks, variantScope);
+
+ handleMicroApp(tasks, variantScope);
// Add a task to process the manifest(s)
SpanRecorders.record(ExecutionType.APP_TASK_MANAGER_CREATE_MERGE_MANIFEST_TASK) {
- createMergeAppManifestsTask(variantData)
+ createMergeAppManifestsTask(tasks, variantScope)
}
// Add a task to create the res values
SpanRecorders.record(ExecutionType.APP_TASK_MANAGER_CREATE_GENERATE_RES_VALUES_TASK) {
- createGenerateResValuesTask(variantData);
+ createGenerateResValuesTask(tasks, variantScope);
}
// Add a task to compile renderscript files.
SpanRecorders.record(ExecutionType.APP_TASK_MANAGER_CREATE_CREATE_RENDERSCRIPT_TASK) {
- createRenderscriptTask(variantData);
+ createRenderscriptTask(tasks, variantScope);
}
// Add a task to merge the resource folders
SpanRecorders.record(ExecutionType.APP_TASK_MANAGER_CREATE_MERGE_RESOURCES_TASK) {
- createMergeResourcesTask(variantData, true /*process9Patch*/);
+ createMergeResourcesTask(tasks, variantScope);
}
// Add a task to merge the asset folders
SpanRecorders.record(ExecutionType.APP_TASK_MANAGER_CREATE_MERGE_ASSETS_TASK) {
- createMergeAssetsTask(
- variantData, null /*default location*/, true /*includeDependencies*/);
+ createMergeAssetsTask(tasks, variantScope);
}
// Add a task to create the BuildConfig class
SpanRecorders.record(ExecutionType.APP_TASK_MANAGER_CREATE_BUILD_CONFIG_TASK) {
- createBuildConfigTask(variantData);
+ createBuildConfigTask(tasks, variantScope);
}
SpanRecorders.record(ExecutionType.APP_TASK_MANAGER_CREATE_PREPROCESS_RESOURCES_TASK) {
- createPreprocessResourcesTask(variantData)
+ createPreprocessResourcesTask(tasks, variantScope)
}
SpanRecorders.record(ExecutionType.APP_TASK_MANAGER_CREATE_PROCESS_RES_TASK) {
// Add a task to process the Android Resources and generate source files
- createProcessResTask(variantData, true /*generateResourcePackage*/);
+ createProcessResTask(tasks, variantScope, true /*generateResourcePackage*/);
// Add a task to process the java resources
- createProcessJavaResTask(variantData);
+ createProcessJavaResTask(tasks, variantScope);
}
SpanRecorders.record(ExecutionType.APP_TASK_MANAGER_CREATE_AIDL_TASK) {
- createAidlTask(variantData, null /*parcelableDir*/);
+ createAidlTask(tasks, variantScope);
}
// Add a compile task
@@ -107,9 +110,9 @@
if (variantData.getVariantConfiguration().getUseJack()) {
createJackTask(appVariantData, null /*testedVariant*/);
} else {
- createJavaCompileTask(variantData, null /*testedVariant*/);
- createJarTask(variantData);
- createPostCompilationTasks(appVariantData);
+ createJavaCompileTask(tasks, variantScope);
+ createJarTask(tasks, variantScope);
+ createPostCompilationTasks(tasks, variantScope);
}
}
@@ -119,11 +122,8 @@
createNdkTasks(variantData);
}
}
-
- // Variant scope should be created at the beginning of the function, but there is currently
- // a dependency on the NdkCompile tasks, and the scope mechanism does not support lazy
- // evaluation yet.
- VariantScope variantScope = createVariantScope(variantData);
+ variantScope.setNdkBuildable(getNdkBuildable(variantData))
+ variantScope.setNdkOutputDirectories(getNdkOutputDirectories(variantData))
if (variantData.getSplitHandlingPolicy() ==
BaseVariantData.SplitHandlingPolicy.RELEASE_21_AND_AFTER_POLICY) {
@@ -131,20 +131,27 @@
throw new RuntimeException("Pure splits can only be used with buildtools 21 and later")
}
SpanRecorders.record(ExecutionType.APP_TASK_MANAGER_CREATE_SPLIT_TASK) {
- createSplitResourcesTasks(appVariantData);
- createSplitAbiTasks(appVariantData);
+ createSplitResourcesTasks(variantScope);
+ createSplitAbiTasks(variantScope);
}
}
SpanRecorders.record(ExecutionType.APP_TASK_MANAGER_CREATE_PACKAGING_TASK) {
createPackagingTask(tasks, variantScope, true /*publishApk*/);
}
+
+ // create the lint tasks.
+ SpanRecorders.record(ExecutionType.APP_TASK_MANAGER_CREATE_LINT_TASK) {
+ createLintTasks(tasks, variantScope);
+ }
}
/**
* Configure variantData to generate embedded wear application.
*/
private void handleMicroApp(
- @NonNull BaseVariantData<? extends BaseVariantOutputData> variantData) {
+ @NonNull TaskFactory tasks,
+ @NonNull VariantScope scope) {
+ BaseVariantData<? extends BaseVariantOutputData> variantData = scope.variantData
if (variantData.getVariantConfiguration().getBuildType().isEmbedMicroApp()) {
// get all possible configurations for the variant. We'll take the highest priority
// of them that have a file.
@@ -162,7 +169,7 @@
int count = file.size();
if (count == 1) {
- createGenerateMicroApkDataTask(variantData, config);
+ createGenerateMicroApkDataTask(tasks, scope, config);
// found one, bail out.
return;
} else if (count > 1) {
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/DependencyManager.java b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/DependencyManager.java
index 65c1073..834a880 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/DependencyManager.java
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/DependencyManager.java
@@ -21,6 +21,7 @@
import com.android.build.gradle.internal.dependency.JarInfo;
import com.android.build.gradle.internal.dependency.LibInfo;
import com.android.build.gradle.internal.dependency.LibraryDependencyImpl;
+import com.android.build.gradle.internal.dependency.ManifestDependencyImpl;
import com.android.build.gradle.internal.dependency.VariantDependencies;
import com.android.build.gradle.internal.model.MavenCoordinatesImpl;
import com.android.build.gradle.internal.tasks.PrepareDependenciesTask;
@@ -973,6 +974,21 @@
JavaBasePlugin.BUILD_DEPENDENTS_TASK_NAME, "compile");
}
+ @NonNull
+ public static List<ManifestDependencyImpl> getManifestDependencies(
+ List<LibraryDependency> libraries) {
+
+ List<ManifestDependencyImpl> list = Lists.newArrayListWithCapacity(libraries.size());
+
+ for (LibraryDependency lib : libraries) {
+ // get the dependencies
+ List<ManifestDependencyImpl> children = getManifestDependencies(lib.getDependencies());
+ list.add(new ManifestDependencyImpl(lib.getName(), lib.getManifest(), children));
+ }
+
+ return list;
+ }
+
/**
* Adds a dependency on tasks with the specified name in other projects. The other projects
* are determined from project lib dependencies using the specified configuration name.
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/LibraryTaskManager.groovy b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/LibraryTaskManager.groovy
index 9bdd860..34664b9 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/LibraryTaskManager.groovy
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/LibraryTaskManager.groovy
@@ -22,6 +22,8 @@
import com.android.build.gradle.LibraryExtension
import com.android.build.gradle.internal.core.GradleVariantConfiguration
import com.android.build.gradle.internal.profile.SpanRecorders
+import com.android.build.gradle.internal.scope.AndroidTask
+import com.android.build.gradle.internal.scope.VariantScope
import com.android.build.gradle.internal.tasks.MergeFileTask
import com.android.build.gradle.internal.variant.BaseVariantData
import com.android.build.gradle.internal.variant.BaseVariantOutputData
@@ -33,6 +35,7 @@
import com.android.builder.core.AndroidBuilder
import com.android.builder.core.BuilderConstants
import com.android.builder.core.DefaultBuildType
+import com.android.builder.core.VariantType
import com.android.builder.dependency.LibraryBundle
import com.android.builder.dependency.LibraryDependency
import com.android.builder.dependency.ManifestDependency
@@ -81,91 +84,92 @@
GradleVariantConfiguration variantConfig = variantData.variantConfiguration
DefaultBuildType buildType = variantConfig.buildType
+ VariantScope variantScope = variantData.getScope()
+
String fullName = variantConfig.fullName
String dirName = variantConfig.dirName
- createAnchorTasks(variantData)
+ createAnchorTasks(tasks, variantScope)
- createCheckManifestTask(variantData)
+ createCheckManifestTask(tasks, variantScope)
// Add a task to create the res values
SpanRecorders.record(ExecutionType.LIB_TASK_MANAGER_CREATE_GENERATE_RES_VALUES_TASK) {
- createGenerateResValuesTask(variantData);
+ createGenerateResValuesTask(tasks, variantScope)
}
// Add a task to process the manifest(s)
SpanRecorders.record(ExecutionType.LIB_TASK_MANAGER_CREATE_MERGE_MANIFEST_TASK) {
- createMergeLibManifestsTask(variantData, DIR_BUNDLES)
+ createMergeLibManifestsTask(tasks, variantScope)
}
// Add a task to compile renderscript files.
SpanRecorders.record(ExecutionType.LIB_TASK_MANAGER_CREATE_CREATE_RENDERSCRIPT_TASK) {
- createRenderscriptTask(variantData)
+ createRenderscriptTask(tasks, variantScope)
}
- MergeResources packageRes = SpanRecorders.record(ExecutionType.LIB_TASK_MANAGER_CREATE_MERGE_RESOURCES_TASK) {
+ AndroidTask<MergeResources> packageRes = SpanRecorders.record(ExecutionType.LIB_TASK_MANAGER_CREATE_MERGE_RESOURCES_TASK) {
// Create a merge task to only merge the resources from this library and not
// the dependencies. This is what gets packaged in the aar.
- MergeResources packageRes = basicCreateMergeResourcesTask(variantData,
+ AndroidTask<MergeResources> mergeResourceTask = basicCreateMergeResourcesTask(
+ tasks,
+ variantScope,
"package",
- "$project.buildDir/${FD_INTERMEDIATES}/$DIR_BUNDLES/${dirName}/res",
+ new File(variantScope.getGlobalScope().getIntermediatesDir(),
+ "$DIR_BUNDLES/$variantScope.variantConfiguration.dirName/res"),
false /*includeDependencies*/,
- false /*process9Patch*/)
+ false /*process9Patch*/);
- if (variantData.variantDependency.androidDependencies.isEmpty()) {
- // if there is no android dependencies, then we should use the packageRes task above
- // as the only res merging task.
- variantData.mergeResourcesTask = packageRes
- } else {
+ if (!variantData.variantDependency.androidDependencies.isEmpty()) {
// Add a task to merge the resource folders, including the libraries, in order to
// generate the R.txt file with all the symbols, including the ones from
// the dependencies.
- createMergeResourcesTask(variantData, false /*process9Patch*/)
+ createMergeResourcesTask(tasks, variantScope)
}
- variantData.mergeResourcesTask.conventionMapping.publicFile = { project.file(
- "$project.buildDir/${FD_INTERMEDIATES}/$DIR_BUNDLES/${dirName}/${SdkConstants.FN_PUBLIC_TXT}")
+ mergeResourceTask.configure(tasks) { MergeResources task ->
+ task.conventionMapping.publicFile = {
+ new File(variantScope.globalScope.intermediatesDir,
+ "$DIR_BUNDLES/${dirName}/${SdkConstants.FN_PUBLIC_TXT}")
+ }
}
- return packageRes;
+ return mergeResourceTask;
}
// Add a task to merge the assets folders
SpanRecorders.record(ExecutionType.LIB_TASK_MANAGER_CREATE_MERGE_ASSETS_TASK) {
- createMergeAssetsTask(variantData,
- "$project.buildDir/${FD_INTERMEDIATES}/$DIR_BUNDLES/${dirName}/assets",
- false /*includeDependencies*/)
+ createMergeAssetsTask(tasks, variantScope)
}
// Add a task to create the BuildConfig class
SpanRecorders.record(ExecutionType.LIB_TASK_MANAGER_CREATE_BUILD_CONFIG_TASK) {
- createBuildConfigTask(variantData)
+ createBuildConfigTask(tasks, variantScope)
}
SpanRecorders.record(ExecutionType.LIB_TASK_MANAGER_CREATE_BACKPORT_RESOURCES_TASK) {
- createPreprocessResourcesTask(variantData)
+ createPreprocessResourcesTask(tasks, variantScope)
}
SpanRecorders.record(ExecutionType.LIB_TASK_MANAGER_CREATE_PROCESS_RES_TASK) {
// Add a task to generate resource source files, directing the location
// of the r.txt file to be directly in the bundle.
- createProcessResTask(variantData,
- "$project.buildDir/${FD_INTERMEDIATES}/$DIR_BUNDLES/${dirName}",
+ createProcessResTask(tasks, variantScope,
+ new File("$project.buildDir/${FD_INTERMEDIATES}/$DIR_BUNDLES/${dirName}"),
false /*generateResourcePackage*/,
)
// process java resources
- createProcessJavaResTask(variantData)
+ createProcessJavaResTask(tasks, variantScope)
}
SpanRecorders.record(ExecutionType.LIB_TASK_MANAGER_CREATE_AIDL_TASK) {
- createAidlTask(variantData, project.file(
- "$project.buildDir/${FD_INTERMEDIATES}/$DIR_BUNDLES/${dirName}/$SdkConstants.FD_AIDL"))
+ createAidlTask(tasks, variantScope)
}
// Add a compile task
SpanRecorders.record(ExecutionType.LIB_TASK_MANAGER_CREATE_COMPILE_TASK) {
- createJavaCompileTask(variantData, null /*testedVariant*/)
+ createJavaCompileTask(tasks, variantScope);
}
// package the prebuilt native libs into the bundle folder
@@ -217,7 +221,7 @@
Copy lintCopy = project.tasks.create(
"copy${fullName.capitalize()}Lint",
Copy)
- lintCopy.dependsOn lintCompile
+ lintCopy.dependsOn LINT_COMPILE
lintCopy.from("$project.buildDir/${FD_INTERMEDIATES}/lint/lint.jar")
lintCopy.into("$project.buildDir/${FD_INTERMEDIATES}/$DIR_BUNDLES/$dirName")
@@ -238,14 +242,14 @@
// post-compilation steps are inserted between the compilation and dx.
PostCompilationData pcData = new PostCompilationData()
SpanRecorders.record(ExecutionType.LIB_TASK_MANAGER_CREATE_POST_COMPILATION_TASK) {
- pcData.classGeneratingTask = Collections.singletonList(variantData.javaCompileTask)
+ pcData.classGeneratingTask = [variantScope.javaCompileTask.name]
pcData.libraryGeneratingTask = Collections.singletonList(
variantData.variantDependency.packageConfiguration.buildDependencies)
pcData.inputFiles = {
return variantData.javaCompileTask.outputs.files.files
}
pcData.inputDir = {
- return variantData.javaCompileTask.destinationDir
+ return variantScope.javaOutputDir
}
pcData.inputLibraries = {
return Collections.emptyList()
@@ -253,14 +257,14 @@
// if needed, instrument the code
if (instrumented) {
- pcData = createJacocoTask(variantConfig, variantData, pcData)
+ pcData = createJacocoTask(tasks, variantScope, pcData);
}
}
if (buildType.isMinifyEnabled()) {
// run proguard on output of compile task
SpanRecorders.record(ExecutionType.LIB_TASK_MANAGER_CREATE_PROGUARD_TASK) {
- File outFile = maybeCreateProguardTasks(variantData, null, pcData)
+ File outFile = maybeCreateProguardTasks(tasks, variantScope, pcData);
pcData.inputFiles = { [outFile] }
pcData.inputDir = null
pcData.inputLibraries = { [] }
@@ -286,14 +290,14 @@
// jar the classes.
Jar jar = project.tasks.create("package${fullName.capitalize()}Jar", Jar);
- jar.dependsOn variantData.processJavaResourcesTask
+ jar.dependsOn variantScope.processJavaResourcesTask.name
// add the class files (whether they are instrumented or not.
jar.from(pcData.inputDir)
TaskManager.optionalDependsOn(jar, pcData.classGeneratingTask)
pcData.classGeneratingTask = Collections.singletonList(jar)
- jar.from(variantData.processJavaResourcesTask.destinationDir)
+ jar.from(variantScope.getJavaResourcesDestinationDir())
jar.destinationDir = project.file(
"$project.buildDir/${FD_INTERMEDIATES}/$DIR_BUNDLES/${dirName}")
@@ -320,7 +324,7 @@
}
}
- bundle.dependsOn packageRes, packageRenderscript, lintCopy, packageJniLibs, mergeProGuardFileTask
+ bundle.dependsOn packageRes.name, packageRenderscript, lintCopy, packageJniLibs, mergeProGuardFileTask
TaskManager.optionalDependsOn(bundle, pcData.classGeneratingTask)
TaskManager.optionalDependsOn(bundle, pcData.libraryGeneratingTask)
@@ -404,6 +408,10 @@
return getFolder();
}
};
+
+ SpanRecorders.record(ExecutionType.LIB_TASK_MANAGER_CREATE_LINT_TASK) {
+ createLintTasks(tasks, variantScope);
+ }
}
public ExtractAnnotations createExtractAnnotations(
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/TaskManager.groovy b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/TaskManager.groovy
index 7923e47..3d860a3 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/TaskManager.groovy
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/TaskManager.groovy
@@ -21,15 +21,12 @@
import com.android.annotations.Nullable
import com.android.build.OutputFile
import com.android.build.gradle.BaseExtension
-import com.android.build.gradle.LibraryExtension
-import com.android.build.gradle.api.AndroidSourceSet
import com.android.build.gradle.internal.core.GradleVariantConfiguration
import com.android.build.gradle.internal.coverage.JacocoInstrumentTask
import com.android.build.gradle.internal.coverage.JacocoPlugin
import com.android.build.gradle.internal.coverage.JacocoReportTask
import com.android.build.gradle.internal.dependency.LibraryDependencyImpl
import com.android.build.gradle.internal.dependency.ManifestDependencyImpl
-import com.android.build.gradle.internal.dependency.SymbolFileProviderImpl
import com.android.build.gradle.internal.dependency.VariantDependencies
import com.android.build.gradle.internal.dsl.AbiSplitOptions
import com.android.build.gradle.internal.dsl.SigningConfig
@@ -38,6 +35,7 @@
import com.android.build.gradle.internal.publishing.MetadataPublishArtifact
import com.android.build.gradle.internal.scope.AndroidTask
import com.android.build.gradle.internal.scope.AndroidTaskRegistry
+import com.android.build.gradle.internal.scope.ConventionMappingHelper
import com.android.build.gradle.internal.scope.GlobalScope
import com.android.build.gradle.internal.scope.VariantOutputScope
import com.android.build.gradle.internal.scope.VariantScope
@@ -68,13 +66,13 @@
import com.android.build.gradle.internal.variant.BaseVariantOutputData
import com.android.build.gradle.internal.variant.LibraryVariantData
import com.android.build.gradle.internal.variant.TestVariantData
+import com.android.build.gradle.internal.variant.TestedVariantData
import com.android.build.gradle.tasks.AidlCompile
import com.android.build.gradle.tasks.AndroidJarTask
import com.android.build.gradle.tasks.AndroidProGuardTask
import com.android.build.gradle.tasks.CompatibleScreensManifest
import com.android.build.gradle.tasks.Dex
import com.android.build.gradle.tasks.GenerateBuildConfig
-import com.android.build.gradle.tasks.PreprocessResourcesTask
import com.android.build.gradle.tasks.GenerateResValues
import com.android.build.gradle.tasks.GenerateSplitAbiRes
import com.android.build.gradle.tasks.JackTask
@@ -89,20 +87,23 @@
import com.android.build.gradle.tasks.PackageSplitRes
import com.android.build.gradle.tasks.PreCompilationVerificationTask
import com.android.build.gradle.tasks.PreDex
+import com.android.build.gradle.tasks.PreprocessResourcesTask
import com.android.build.gradle.tasks.ProcessAndroidResources
import com.android.build.gradle.tasks.ProcessManifest
import com.android.build.gradle.tasks.ProcessTestManifest
import com.android.build.gradle.tasks.RenderscriptCompile
+import com.android.build.gradle.tasks.ShrinkResources
import com.android.build.gradle.tasks.SplitZipAlign
import com.android.build.gradle.tasks.ZipAlign
+import com.android.build.gradle.tasks.factory.JavaCompileConfigAction
+import com.android.build.gradle.tasks.factory.ProGuardTaskConfigAction
+import com.android.build.gradle.tasks.factory.ProcessJavaResConfigAction
import com.android.builder.core.AndroidBuilder
import com.android.builder.core.VariantConfiguration
import com.android.builder.core.VariantType
import com.android.builder.dependency.LibraryDependency
import com.android.builder.internal.testing.SimpleTestCallable
-import com.android.builder.model.ApiVersion
-import com.android.builder.model.ProductFlavor
-import com.android.builder.model.SourceProvider
+import com.android.builder.model.AndroidProject
import com.android.builder.testing.ConnectedDeviceProvider
import com.android.builder.testing.TestData
import com.android.builder.testing.api.DeviceProvider
@@ -111,8 +112,6 @@
import com.android.sdklib.AndroidTargetHash
import com.android.sdklib.BuildToolInfo
import com.android.sdklib.IAndroidTarget
-import com.android.sdklib.SdkVersionInfo
-import com.android.sdklib.repository.FullRevision
import com.google.common.base.CharMatcher
import com.google.common.collect.ImmutableList
import com.google.common.collect.ImmutableSet
@@ -121,13 +120,13 @@
import com.google.common.collect.Sets
import groovy.transform.CompileDynamic
import groovy.transform.CompileStatic
+import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.JavaVersion
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.artifacts.Configuration
import org.gradle.api.execution.TaskExecutionGraph
-import org.gradle.api.file.FileCollection
import org.gradle.api.internal.ConventionMapping
import org.gradle.api.logging.LogLevel
import org.gradle.api.logging.Logger
@@ -142,12 +141,10 @@
import org.gradle.api.tasks.compile.JavaCompile
import org.gradle.api.tasks.testing.Test
import org.gradle.api.tasks.testing.TestTaskReports
-import org.gradle.language.jvm.tasks.ProcessResources
-import org.gradle.tooling.BuildException
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
import proguard.gradle.ProGuardTask
-import static com.android.SdkConstants.FN_ANDROID_MANIFEST_XML
+import static com.android.build.OutputFile.DENSITY
import static com.android.builder.core.BuilderConstants.CONNECTED
import static com.android.builder.core.BuilderConstants.DEVICE
import static com.android.builder.core.BuilderConstants.FD_ANDROID_RESULTS
@@ -157,14 +154,12 @@
import static com.android.builder.core.BuilderConstants.FD_REPORTS
import static com.android.builder.core.VariantType.ANDROID_TEST
import static com.android.builder.core.VariantType.DEFAULT
-import static com.android.builder.core.VariantType.LIBRARY
import static com.android.builder.core.VariantType.UNIT_TEST
import static com.android.builder.model.AndroidProject.FD_GENERATED
import static com.android.builder.model.AndroidProject.FD_INTERMEDIATES
import static com.android.builder.model.AndroidProject.FD_OUTPUTS
import static com.android.builder.model.AndroidProject.PROPERTY_APK_LOCATION
import static com.android.sdklib.BuildToolInfo.PathId.ZIP_ALIGN
-import static com.google.common.base.Preconditions.checkNotNull
/**
* Manages tasks creation.
@@ -178,11 +173,11 @@
public final static String DIR_BUNDLES = "bundles";
- private static final String INSTALL_GROUP = "Install"
+ public static final String INSTALL_GROUP = "Install"
- private static final String BUILD_GROUP = BasePlugin.BUILD_GROUP
+ public static final String BUILD_GROUP = BasePlugin.BUILD_GROUP
- private static final String ANDROID_GROUP = "Android"
+ public static final String ANDROID_GROUP = "Android"
protected Project project
@@ -194,7 +189,7 @@
protected BaseExtension extension
- private ToolingModelBuilderRegistry toolingRegistry
+ protected ToolingModelBuilderRegistry toolingRegistry
private final GlobalScope globalScope
@@ -205,6 +200,7 @@
protected boolean isNdkTaskNeeded = true
// Task names
+ // TODO: Convert to AndroidTask.
private static final String MAIN_PREBUILD = "preBuild"
private static final String UNINSTALL_ALL = "uninstallAll"
@@ -217,13 +213,13 @@
private static final String SOURCE_SETS = "sourceSets"
+ private static final String LINT = "lint"
+
+ protected static final String LINT_COMPILE = "compileLint"
+
// Tasks
private Copy jacocoAgentTask
- public Task lintCompile
-
- protected Task lintAll
-
public MockableAndroidJarTask createMockableJar
public TaskManager(
@@ -245,7 +241,9 @@
project,
androidBuilder,
getArchivesBaseName(project),
- extension);
+ extension,
+ sdkHandler,
+ toolingRegistry);
}
private boolean isVerbose() {
@@ -265,6 +263,10 @@
@NonNull TaskFactory tasks,
@NonNull BaseVariantData<? extends BaseVariantOutputData> variantData)
+ public GlobalScope getGlobalScope() {
+ return globalScope
+ }
+
/**
* Returns a collection of buildables that creates native object.
*
@@ -323,6 +325,18 @@
it.setGroup(BasePlugin.BUILD_GROUP);
it.setDescription("Assembles all the Test applications.");
}
+
+ tasks.create(LINT, Lint) {
+ it.description = "Runs lint on all variants."
+ it.group = JavaBasePlugin.VERIFICATION_GROUP
+ it.setLintOptions(getExtension().lintOptions)
+ it.setSdkHome(sdkHandler.getSdkFolder())
+ it.setToolingRegistry(toolingRegistry)
+ }
+ tasks.named(JavaBasePlugin.CHECK_TASK_NAME) {
+ it.dependsOn LINT
+ }
+ createLintCompileTask(tasks)
}
public void createMockableJarTask() {
@@ -348,125 +362,36 @@
}
public void createMergeAppManifestsTask(
- @NonNull BaseVariantData<? extends BaseVariantOutputData> variantData) {
+ @NonNull TaskFactory tasks,
+ @NonNull VariantScope variantScope) {
- VariantConfiguration config = variantData.variantConfiguration
- ProductFlavor mergedFlavor = config.mergedFlavor
-
- ApplicationVariantData appVariantData = variantData as ApplicationVariantData
+ ApplicationVariantData appVariantData = variantScope.variantData as ApplicationVariantData
Set<String> screenSizes = appVariantData.getCompatibleScreens()
// loop on all outputs. The only difference will be the name of the task, and location
// of the generated manifest
- for (BaseVariantOutputData vod : variantData.outputs) {
- final CompatibleScreensManifest csmTask =
- (vod.getMainOutputFile().getFilter(OutputFile.DENSITY) != null
- && !screenSizes.isEmpty()) ?
- createCompatibleScreensManifest(vod, screenSizes) :
- null
-
+ for (BaseVariantOutputData vod : appVariantData.outputs) {
// create final var inside the loop to ensure the closures will work.
final BaseVariantOutputData variantOutputData = vod
- String outputName = variantOutputData.fullName.capitalize()
- String outputDirName = variantOutputData.dirName
+ VariantOutputScope scope = variantOutputData.getScope()
- def processManifestTask = project.tasks.create(
- "process${outputName}Manifest",
- MergeManifests)
-
- variantOutputData.manifestProcessorTask = processManifestTask
-
- processManifestTask.androidBuilder = androidBuilder
-
- processManifestTask.dependsOn variantData.prepareDependenciesTask
- if (variantData.generateApkDataTask != null) {
- processManifestTask.dependsOn variantData.generateApkDataTask
+ AndroidTask<CompatibleScreensManifest> csmTask = null;
+ if (vod.getMainOutputFile().getFilter(DENSITY) != null) {
+ csmTask = androidTasks.create(tasks,
+ new CompatibleScreensManifest.ConfigAction(scope, screenSizes));
+ scope.compatibleScreensManifestTask = csmTask
}
+
+ scope.manifestProcessorTask = androidTasks.create(tasks,
+ new MergeManifests.ConfigAction(scope))
+
if (csmTask != null) {
- processManifestTask.dependsOn csmTask
- }
-
- processManifestTask.variantConfiguration = config
- if (variantOutputData instanceof ApkVariantOutputData) {
- processManifestTask.variantOutputData = variantOutputData as ApkVariantOutputData
- }
-
- conventionMapping(processManifestTask).map("libraries") {
- List<ManifestDependencyImpl> manifests =
- getManifestDependencies(config.directLibraries)
-
- if (variantData.generateApkDataTask != null &&
- variantData.getVariantConfiguration().getBuildType().isEmbedMicroApp()) {
- manifests.add(new ManifestDependencyImpl(
- variantData.generateApkDataTask.getManifestFile(), []))
- }
-
- if (csmTask != null) {
- manifests.add(
- new ManifestDependencyImpl(csmTask.getManifestFile(), []))
- }
-
- return manifests
- }
-
- conventionMapping(processManifestTask).map("minSdkVersion") {
- if (androidBuilder.isPreviewTarget()) {
- return androidBuilder.getTargetCodename()
- }
-
- mergedFlavor.minSdkVersion?.apiString
- }
-
- conventionMapping(processManifestTask).map("targetSdkVersion") {
- if (androidBuilder.isPreviewTarget()) {
- return androidBuilder.getTargetCodename()
- }
-
- return mergedFlavor.targetSdkVersion?.apiString
- }
-
- conventionMapping(processManifestTask).map("maxSdkVersion") {
- if (androidBuilder.isPreviewTarget()) {
- return null
- }
-
- return mergedFlavor.maxSdkVersion
- }
-
- conventionMapping(processManifestTask).map("manifestOutputFile") {
- project.file(
- "$project.buildDir/${FD_INTERMEDIATES}/manifests/full/" +
- "${outputDirName}/AndroidManifest.xml")
- }
-
- conventionMapping(processManifestTask).map("reportFile") {
- project.file(
- "$project.buildDir/${FD_OUTPUTS}/logs/manifest-merger-${config.baseName}-report.txt")
+ scope.manifestProcessorTask.dependsOn(tasks, csmTask)
}
}
}
- private CompatibleScreensManifest createCompatibleScreensManifest(
- @NonNull BaseVariantOutputData variantOutputData,
- @NonNull Set<String> screenSizes) {
-
- CompatibleScreensManifest csmTask = project.tasks.create(
- "create${variantOutputData.fullName.capitalize()}CompatibleScreensManifest",
- CompatibleScreensManifest)
-
- csmTask.screenDensity = variantOutputData.getMainOutputFile().getFilter(OutputFile.DENSITY)
- csmTask.screenSizes = screenSizes
-
- conventionMapping(csmTask).map("manifestFile") {
- project.file(
- "$project.buildDir/${FD_INTERMEDIATES}/manifests/density/" +
- "${variantOutputData.dirName}/AndroidManifest.xml")
- }
-
- return csmTask;
- }
-
@CompileDynamic
private static ConventionMapping conventionMapping(Task task) {
task.conventionMapping
@@ -482,526 +407,198 @@
}
public void createMergeLibManifestsTask(
- @NonNull BaseVariantData<? extends BaseVariantOutputData> variantData,
- @NonNull String manifestOutDir) {
- VariantConfiguration config = variantData.variantConfiguration
+ @NonNull TaskFactory tasks,
+ @NonNull VariantScope scope) {
- // get single output for now.
- BaseVariantOutputData variantOutputData = variantData.outputs.get(0)
+ AndroidTask<ProcessManifest> processManifest = androidTasks.create(tasks,
+ new ProcessManifest.ConfigAction(scope));
- def processManifest = project.tasks.create(
- "process${variantData.variantConfiguration.fullName.capitalize()}Manifest",
- ProcessManifest)
- variantOutputData.manifestProcessorTask = processManifest
- processManifest.androidBuilder = androidBuilder
+ processManifest.dependsOn(tasks, scope.variantData.prepareDependenciesTask)
- processManifest.dependsOn variantData.prepareDependenciesTask
- processManifest.variantConfiguration = config
-
- ProductFlavor mergedFlavor = config.mergedFlavor
-
- conventionMapping(processManifest).map("minSdkVersion") {
- if (androidBuilder.isPreviewTarget()) {
- return androidBuilder.getTargetCodename()
- }
- return mergedFlavor.minSdkVersion?.apiString
- }
-
- conventionMapping(processManifest).map("targetSdkVersion") {
- if (androidBuilder.isPreviewTarget()) {
- return androidBuilder.getTargetCodename()
- }
-
- return mergedFlavor.targetSdkVersion?.apiString
- }
-
- conventionMapping(processManifest).map("maxSdkVersion") {
- if (androidBuilder.isPreviewTarget()) {
- return null
- }
-
- return mergedFlavor.maxSdkVersion
- }
-
- conventionMapping(processManifest).map("manifestOutputFile") {
- project.file(
- "$project.buildDir/${FD_INTERMEDIATES}/${manifestOutDir}/" +
- "${variantData.variantConfiguration.dirName}/AndroidManifest.xml")
- }
-
- conventionMapping(processManifest).map("aaptFriendlyManifestOutputFile") {
- project.file(
- "$project.buildDir/${FD_INTERMEDIATES}/${manifestOutDir}/" +
- "${variantData.variantConfiguration.dirName}/aapt/AndroidManifest.xml")
- }
+ BaseVariantOutputData variantOutputData = scope.variantData.outputs.get(0)
+ variantOutputData.scope.manifestProcessorTask = processManifest
}
protected void createProcessTestManifestTask(
- @NonNull BaseVariantData<? extends BaseVariantOutputData> variantData,
- @NonNull String manifestOurDir) {
- def processTestManifestTask;
- VariantConfiguration config = variantData.variantConfiguration
- processTestManifestTask = project.tasks.create(
- "process${variantData.variantConfiguration.fullName.capitalize()}Manifest",
- ProcessTestManifest)
- conventionMapping(processTestManifestTask).map("testManifestFile") {
- config.getMainManifest()
- }
- conventionMapping(processTestManifestTask).map("tmpDir") {
- project.file(
- "$project.buildDir/${FD_INTERMEDIATES}/${manifestOurDir}/tmp")
- }
+ @NonNull TaskFactory tasks,
+ @NonNull VariantScope scope) {
- // get single output for now.
- BaseVariantOutputData variantOutputData = variantData.outputs.get(0)
+ AndroidTask<ProcessTestManifest> processTestManifestTask = androidTasks.create(tasks,
+ new ProcessTestManifest.ConfigAction(scope));
- variantOutputData.manifestProcessorTask = processTestManifestTask
- processTestManifestTask.dependsOn variantData.prepareDependenciesTask
+ processTestManifestTask.dependsOn(tasks, scope.variantData.prepareDependenciesTask)
- processTestManifestTask.androidBuilder = androidBuilder
-
- conventionMapping(processTestManifestTask).map("testApplicationId") {
- config.applicationId
- }
- conventionMapping(processTestManifestTask).map("minSdkVersion") {
- if (androidBuilder.isPreviewTarget()) {
- return androidBuilder.getTargetCodename()
- }
-
- config.minSdkVersion?.apiString
- }
- conventionMapping(processTestManifestTask).map("targetSdkVersion") {
- if (androidBuilder.isPreviewTarget()) {
- return androidBuilder.getTargetCodename()
- }
-
- return config.targetSdkVersion?.apiString
- }
- conventionMapping(processTestManifestTask).map("testedApplicationId") {
- config.testedApplicationId
- }
- conventionMapping(processTestManifestTask).map("instrumentationRunner") {
- config.instrumentationRunner
- }
- conventionMapping(processTestManifestTask).map("handleProfiling") {
- config.handleProfiling
- }
- conventionMapping(processTestManifestTask).map("functionalTest") {
- config.functionalTest
- }
- conventionMapping(processTestManifestTask).map("libraries") {
- getManifestDependencies(config.directLibraries)
- }
- conventionMapping(processTestManifestTask).map("manifestOutputFile") {
- project.file(
- "$project.buildDir/${FD_INTERMEDIATES}/${manifestOurDir}/${variantData.variantConfiguration.dirName}/AndroidManifest.xml")
- }
- conventionMapping(processTestManifestTask).map("placeholdersValues") {
- variantData.getVariantConfiguration().getManifestPlaceholders()
- }
+ BaseVariantOutputData variantOutputData = scope.variantData.outputs.get(0)
+ variantOutputData.scope.manifestProcessorTask = processTestManifestTask
}
public void createRenderscriptTask(
- @NonNull BaseVariantData<? extends BaseVariantOutputData> variantData) {
- GradleVariantConfiguration config = variantData.variantConfiguration
+ @NonNull TaskFactory tasks,
+ @NonNull VariantScope scope) {
+ scope.renderscriptCompileTask = androidTasks.create(tasks,
+ new RenderscriptCompile.ConfigAction(scope))
+ BaseVariantData<? extends BaseVariantOutputData> variantData = scope.variantData
+ GradleVariantConfiguration config = variantData.variantConfiguration
// get single output for now.
BaseVariantOutputData variantOutputData = variantData.outputs.get(0)
- def renderscriptTask = project.tasks.create(
- "compile${variantData.variantConfiguration.fullName.capitalize()}Renderscript",
- RenderscriptCompile)
- variantData.renderscriptCompileTask = renderscriptTask
+ scope.renderscriptCompileTask.dependsOn(tasks, variantData.prepareDependenciesTask)
if (config.type.isForTesting()) {
- renderscriptTask.dependsOn variantOutputData.manifestProcessorTask
+ scope.renderscriptCompileTask.dependsOn(tasks, variantOutputData.scope.manifestProcessorTask)
} else {
- renderscriptTask.dependsOn variantData.checkManifestTask
+ scope.renderscriptCompileTask.dependsOn(tasks, scope.checkManifestTask)
}
- ProductFlavor mergedFlavor = config.mergedFlavor
- boolean ndkMode = config.renderscriptNdkModeEnabled
- variantData.resourceGenTask.dependsOn renderscriptTask
+ scope.resourceGenTask.dependsOn(tasks, scope.renderscriptCompileTask)
// only put this dependency if rs will generate Java code
- if (!ndkMode) {
- variantData.sourceGenTask.dependsOn renderscriptTask
+ if (!config.renderscriptNdkModeEnabled) {
+ scope.sourceGenTask.dependsOn(tasks, scope.renderscriptCompileTask)
}
-
- renderscriptTask.dependsOn variantData.prepareDependenciesTask
- renderscriptTask.androidBuilder = androidBuilder
-
- conventionMapping(renderscriptTask).map("targetApi") {
- int targetApi = mergedFlavor.renderscriptTargetApi != null ?
- mergedFlavor.renderscriptTargetApi : -1
- ApiVersion apiVersion = config.getMinSdkVersion()
- if (apiVersion != null) {
- int minSdk = apiVersion.apiLevel
- if (apiVersion.codename != null) {
- minSdk = SdkVersionInfo.getApiByBuildCode(apiVersion.codename, true)
- }
-
- return targetApi > minSdk ? targetApi : minSdk
- }
-
- return targetApi
- }
-
- renderscriptTask.supportMode = config.renderscriptSupportModeEnabled
- renderscriptTask.ndkMode = ndkMode
- renderscriptTask.debugBuild = config.buildType.renderscriptDebuggable
- renderscriptTask.optimLevel = config.buildType.renderscriptOptimLevel
-
- conventionMapping(renderscriptTask).map("sourceDirs") { config.renderscriptSourceList }
- conventionMapping(renderscriptTask).map("importDirs") { config.renderscriptImports }
-
- conventionMapping(renderscriptTask).map("sourceOutputDir") {
- project.file(
- "$project.buildDir/${FD_GENERATED}/source/rs/${variantData.variantConfiguration.dirName}")
- }
- conventionMapping(renderscriptTask).map("resOutputDir") {
- project.file(
- "$project.buildDir/${FD_GENERATED}/res/rs/${variantData.variantConfiguration.dirName}")
- }
- conventionMapping(renderscriptTask).map("objOutputDir") {
- project.file(
- "$project.buildDir/${FD_INTERMEDIATES}/rs/${variantData.variantConfiguration.dirName}/obj")
- }
- conventionMapping(renderscriptTask).map("libOutputDir") {
- project.file(
- "$project.buildDir/${FD_INTERMEDIATES}/rs/${variantData.variantConfiguration.dirName}/lib")
- }
- conventionMapping(renderscriptTask).map("ndkConfig") { config.ndkConfig }
}
- public void createMergeResourcesTask(
- @NonNull BaseVariantData<? extends BaseVariantOutputData> variantData,
- final boolean process9Patch) {
- MergeResources mergeResourcesTask = basicCreateMergeResourcesTask(
- variantData,
+ public AndroidTask<MergeResources> createMergeResourcesTask(
+ @NonNull TaskFactory tasks,
+ @NonNull VariantScope scope) {
+ return basicCreateMergeResourcesTask(
+ tasks,
+ scope,
"merge",
- "$project.buildDir/${FD_INTERMEDIATES}/res/merged/${variantData.variantConfiguration.dirName}",
+ null /*outputLocation*/,
true /*includeDependencies*/,
- process9Patch)
- variantData.mergeResourcesTask = mergeResourcesTask
+ true /*process9patch*/)
}
- public MergeResources basicCreateMergeResourcesTask(
- @NonNull BaseVariantData<? extends BaseVariantOutputData> variantData,
+ public AndroidTask<MergeResources> basicCreateMergeResourcesTask(
+ @NonNull TaskFactory tasks,
+ @NonNull VariantScope scope,
@NonNull String taskNamePrefix,
- @NonNull String outputLocation,
+ @Nullable File outputLocation,
final boolean includeDependencies,
final boolean process9Patch) {
- MergeResources mergeResourcesTask = project.tasks.create(
- "$taskNamePrefix${variantData.variantConfiguration.fullName.capitalize()}Resources",
- MergeResources)
-
- mergeResourcesTask.dependsOn variantData.prepareDependenciesTask,
- variantData.resourceGenTask
- mergeResourcesTask.androidBuilder = androidBuilder
- mergeResourcesTask.incrementalFolder = project.file(
- "$project.buildDir/${FD_INTERMEDIATES}/incremental/${taskNamePrefix}Resources/${variantData.variantConfiguration.dirName}")
-
- mergeResourcesTask.process9Patch = process9Patch
- mergeResourcesTask.crunchPng = extension.aaptOptions.getCruncherEnabled()
- mergeResourcesTask.normalizeResources = extension.buildToolsRevision.compareTo(new FullRevision(21, 0, 0)) < 0
-
- conventionMapping(mergeResourcesTask).
- map("useNewCruncher") { getExtension().aaptOptions.useNewCruncher }
-
- conventionMapping(mergeResourcesTask).map("inputResourceSets") {
- List<File> generatedResFolders = Lists.newArrayList(
- variantData.renderscriptCompileTask.getResOutputDir(),
- variantData.generateResValuesTask.getResOutputDir())
- if (variantData.extraGeneratedResFolders != null) {
- generatedResFolders += variantData.extraGeneratedResFolders
- }
- if (variantData.generateApkDataTask != null &&
- variantData.getVariantConfiguration().getBuildType().isEmbedMicroApp()) {
- generatedResFolders.add(variantData.generateApkDataTask.getResOutputDir())
- }
- variantData.variantConfiguration.getResourceSets(generatedResFolders,
- includeDependencies)
- }
-
- conventionMapping(mergeResourcesTask).map("outputDir") { project.file(outputLocation) }
-
- return mergeResourcesTask
+ scope.mergeResourcesTask = androidTasks.create(tasks,
+ new MergeResources.ConfigAction(
+ scope,
+ taskNamePrefix,
+ outputLocation,
+ includeDependencies,
+ process9Patch));
+ scope.mergeResourcesTask.dependsOn(tasks,
+ scope.variantData.prepareDependenciesTask,
+ scope.resourceGenTask)
+ return scope.mergeResourcesTask;
}
- public void createMergeAssetsTask(
- @NonNull BaseVariantData<? extends BaseVariantOutputData> variantData,
- @Nullable String outputLocation,
- final boolean includeDependencies) {
- if (outputLocation == null) {
- outputLocation =
- "$project.buildDir/${FD_INTERMEDIATES}/assets/${variantData.variantConfiguration.dirName}"
- }
- VariantConfiguration variantConfig = variantData.variantConfiguration
-
- def mergeAssetsTask = project.tasks.create(
- "merge${variantConfig.fullName.capitalize()}Assets",
- MergeAssets)
- variantData.mergeAssetsTask = mergeAssetsTask
-
- mergeAssetsTask.dependsOn variantData.prepareDependenciesTask, variantData.assetGenTask
- mergeAssetsTask.androidBuilder = androidBuilder
- mergeAssetsTask.incrementalFolder =
- project.file(
- "$project.buildDir/${FD_INTERMEDIATES}/incremental/mergeAssets/${variantConfig.dirName}")
-
- conventionMapping(mergeAssetsTask).map("inputAssetSets") {
- def generatedAssets = []
- if (variantData.copyApkTask != null) {
- generatedAssets.add(variantData.copyApkTask.destinationDir)
- }
- variantConfig.getAssetSets(generatedAssets, includeDependencies)
- }
- conventionMapping(mergeAssetsTask).map("outputDir") { project.file(outputLocation) }
+ public void createMergeAssetsTask(TaskFactory tasks, VariantScope scope) {
+ scope.mergeAssetsTask = androidTasks.create(tasks, new MergeAssets.ConfigAction(scope))
+ scope.mergeAssetsTask.dependsOn(tasks,
+ scope.variantData.prepareDependenciesTask,
+ scope.assetGenTask)
}
- public void createBuildConfigTask(
- @NonNull BaseVariantData<? extends BaseVariantOutputData> variantData) {
- def generateBuildConfigTask = project.tasks.create(
- "generate${variantData.variantConfiguration.fullName.capitalize()}BuildConfig",
- GenerateBuildConfig)
+ public void createBuildConfigTask(@NonNull TaskFactory tasks, @NonNull VariantScope scope) {
+ scope.generateBuildConfigTask = androidTasks.create(tasks, new GenerateBuildConfig.ConfigAction(scope))
- variantData.generateBuildConfigTask = generateBuildConfigTask
-
- VariantConfiguration variantConfiguration = variantData.variantConfiguration
-
- variantData.sourceGenTask.dependsOn generateBuildConfigTask
- if (variantConfiguration.type.isForTesting()) {
+ scope.sourceGenTask.dependsOn(tasks, scope.generateBuildConfigTask.name);
+ if (scope.variantConfiguration.type.isForTesting()) {
// in case of a test project, the manifest is generated so we need to depend
// on its creation.
// For test apps there should be a single output, so we get it.
- BaseVariantOutputData variantOutputData = variantData.outputs.get(0)
+ BaseVariantOutputData variantOutputData = scope.variantData.outputs.get(0)
- generateBuildConfigTask.dependsOn variantOutputData.manifestProcessorTask
+ scope.generateBuildConfigTask.dependsOn(tasks, variantOutputData.scope.manifestProcessorTask)
} else {
- generateBuildConfigTask.dependsOn variantData.checkManifestTask
- }
-
- generateBuildConfigTask.androidBuilder = androidBuilder
-
- conventionMapping(generateBuildConfigTask).map("buildConfigPackageName") {
- variantConfiguration.originalApplicationId
- }
-
- conventionMapping(generateBuildConfigTask).map("appPackageName") {
- variantConfiguration.applicationId
- }
-
- conventionMapping(generateBuildConfigTask).map("versionName") {
- variantConfiguration.versionName
- }
-
- conventionMapping(generateBuildConfigTask).map("versionCode") {
- variantConfiguration.versionCode
- }
-
- conventionMapping(generateBuildConfigTask).map("debuggable") {
- variantConfiguration.buildType.isDebuggable()
- }
-
- conventionMapping(generateBuildConfigTask).map("buildTypeName") {
- variantConfiguration.buildType.name
- }
-
- conventionMapping(generateBuildConfigTask).map("flavorName") {
- variantConfiguration.flavorName
- }
-
- conventionMapping(generateBuildConfigTask).map("flavorNamesWithDimensionNames") {
- variantConfiguration.flavorNamesWithDimensionNames
- }
-
- conventionMapping(generateBuildConfigTask).map("items") {
- variantConfiguration.buildConfigItems
- }
-
- conventionMapping(generateBuildConfigTask).map("sourceOutputDir") {
- project.file(
- "$project.buildDir/${FD_GENERATED}/source/buildConfig/${variantData.variantConfiguration.dirName}")
+ scope.generateBuildConfigTask.dependsOn(tasks, scope.checkManifestTask)
}
}
public void createGenerateResValuesTask(
- @NonNull BaseVariantData<? extends BaseVariantOutputData> variantData) {
- GenerateResValues generateResValuesTask = project.tasks.create(
- "generate${variantData.variantConfiguration.fullName.capitalize()}ResValues",
- GenerateResValues)
- variantData.generateResValuesTask = generateResValuesTask
- variantData.resourceGenTask.dependsOn generateResValuesTask
-
- VariantConfiguration variantConfiguration = variantData.variantConfiguration
-
- generateResValuesTask.androidBuilder = androidBuilder
-
- conventionMapping(generateResValuesTask).map("items") {
- variantConfiguration.resValues
- }
-
- conventionMapping(generateResValuesTask).map("resOutputDir") {
- project.file(
- "$project.buildDir/${FD_GENERATED}/res/resValues/${variantData.variantConfiguration.dirName}")
- }
+ @NonNull TaskFactory tasks,
+ @NonNull VariantScope scope) {
+ AndroidTask<GenerateResValues> generateResValuesTask = androidTasks.create(
+ tasks, new GenerateResValues.ConfigAction(scope))
+ scope.resourceGenTask.dependsOn(tasks, generateResValuesTask)
}
public void createPreprocessResourcesTask(
- @NonNull BaseVariantData<? extends BaseVariantOutputData> variantData) {
+ @NonNull TaskFactory tasks,
+ @NonNull VariantScope scope) {
+ BaseVariantData<? extends BaseVariantOutputData> variantData = scope.variantData
String variantName = variantData.variantConfiguration.fullName.capitalize()
int minSdk = variantData.variantConfiguration.minSdkVersion.getApiLevel()
if (extension.preprocessResources && minSdk < PreprocessResourcesTask.MIN_SDK) {
- PreprocessResourcesTask preprocessResourcesTask = project.tasks.create(
+ scope.preprocessResourcesTask = androidTasks.create(
+ tasks,
"preprocess${variantName}Resources",
- PreprocessResourcesTask)
- variantData.preprocessResourcesTask = preprocessResourcesTask
+ PreprocessResourcesTask) { PreprocessResourcesTask preprocessResourcesTask ->
+ variantData.preprocessResourcesTask = preprocessResourcesTask
- preprocessResourcesTask.dependsOn variantData.mergeResourcesTask
+ preprocessResourcesTask.dependsOn variantData.mergeResourcesTask
- preprocessResourcesTask.mergedResDirectory =
- variantData.mergeResourcesTask.outputDir
- preprocessResourcesTask.generatedResDirectory =
- project.file("$project.buildDir/${FD_GENERATED}/res/pngs/${variantData.variantConfiguration.dirName}")
- preprocessResourcesTask.outputResDirectory =
- project.file("$project.buildDir/${FD_INTERMEDIATES}/res/preprocessed/${variantData.variantConfiguration.dirName}")
- preprocessResourcesTask.incrementalFolder =
- project.file("$project.buildDir/${FD_INTERMEDIATES}/incremental/preprocessResourcesTask/${variantData.variantConfiguration.dirName}")
+ preprocessResourcesTask.mergedResDirectory =
+ scope.getMergeResourcesOutputDir()
+ preprocessResourcesTask.generatedResDirectory =
+ project.file(
+ "$project.buildDir/${FD_GENERATED}/res/pngs/${variantData.variantConfiguration.dirName}")
+ preprocessResourcesTask.outputResDirectory =
+ project.file(
+ "$project.buildDir/${FD_INTERMEDIATES}/res/preprocessed/${variantData.variantConfiguration.dirName}")
+ preprocessResourcesTask.incrementalFolder =
+ project.file(
+ "$project.buildDir/${FD_INTERMEDIATES}/incremental/preprocessResourcesTask/${variantData.variantConfiguration.dirName}")
- // TODO: configure this in the extension.
- preprocessResourcesTask.densitiesToGenerate = [Density.HIGH, Density.XHIGH]
+ // TODO: configure this in the extension.
+ preprocessResourcesTask.densitiesToGenerate = [Density.HIGH, Density.XHIGH]
+ }
}
}
-
public void createProcessResTask(
- @NonNull BaseVariantData<? extends BaseVariantOutputData> variantData,
+ @NonNull TaskFactory tasks,
+ @NonNull VariantScope scope,
boolean generateResourcePackage) {
- createProcessResTask(variantData,
- "$project.buildDir/${FD_INTERMEDIATES}/symbols/${variantData.variantConfiguration.dirName}",
- generateResourcePackage)
+ createProcessResTask(
+ tasks,
+ scope,
+ new File(globalScope.getBuildDir(), FD_INTERMEDIATES + "/symbols/" +
+ scope.variantData.getVariantConfiguration().getDirName()),
+ generateResourcePackage);
}
public void createProcessResTask(
- @NonNull BaseVariantData<? extends BaseVariantOutputData> variantData,
- @NonNull final String symbolLocation,
+ @NonNull TaskFactory tasks,
+ @NonNull VariantScope scope,
+ @Nullable File symbolLocation,
boolean generateResourcePackage) {
+ BaseVariantData<? extends BaseVariantOutputData> variantData = scope.getVariantData()
- VariantConfiguration config = variantData.variantConfiguration
+ variantData.calculateFilters(scope.getGlobalScope().getExtension().getSplits());
// loop on all outputs. The only difference will be the name of the task, and location
// of the generated data.
- for (BaseVariantOutputData vod : variantData.outputs) {
+ for (BaseVariantOutputData vod : (List<? extends BaseVariantOutputData>)variantData.outputs) {
// create final var inside the loop to ensure the closures will work.
- final BaseVariantOutputData variantOutputData = vod
+ final VariantOutputScope variantOutputScope = vod.scope;
- String outputName = variantOutputData.fullName.capitalize()
- String outputBaseName = variantOutputData.baseName
+ variantOutputScope.processResourcesTask = androidTasks.create(tasks,
+ new ProcessAndroidResources.ConfigAction(variantOutputScope, symbolLocation, generateResourcePackage));
+ variantOutputScope.processResourcesTask.dependsOn(tasks,
+ variantOutputScope.manifestProcessorTask,
+ scope.mergeResourcesTask,
+ scope.mergeAssetsTask)
- ProcessAndroidResources processResources = project.tasks.create(
- "process${outputName}Resources",
- ProcessAndroidResources)
-
- variantOutputData.processResourcesTask = processResources
-
- processResources.dependsOn variantOutputData.manifestProcessorTask,
- variantData.mergeResourcesTask, variantData.mergeAssetsTask
// TODO: Make it non-optional once this is not behind a flag.
- optionalDependsOn(processResources, variantData.preprocessResourcesTask)
- processResources.androidBuilder = androidBuilder
+ variantOutputScope.processResourcesTask.optionalDependsOn(tasks,
+ scope.preprocessResourcesTask)
- if (variantData.getSplitHandlingPolicy() ==
- BaseVariantData.SplitHandlingPolicy.RELEASE_21_AND_AFTER_POLICY) {
-
- variantData.calculateFilters(getExtension().getSplits());
- Set<String> allFilters = new HashSet<>();
- allFilters.addAll(variantData.getFilters(OutputFile.FilterType.DENSITY))
- allFilters.addAll(variantData.getFilters(OutputFile.FilterType.LANGUAGE))
- processResources.splits = allFilters;
+ if (vod.getMainOutputFile().getFilter(DENSITY) == null) {
+ scope.generateRClassTask = variantOutputScope.processResourcesTask
+ scope.sourceGenTask.optionalDependsOn(tasks, variantOutputScope.processResourcesTask)
}
-
- // only generate code if the density filter is null, and if we haven't generated
- // it yet (if you have abi + density splits, then several abi output will have no
- // densityFilter)
- if (variantOutputData.getMainOutputFile().getFilter(OutputFile.DENSITY) == null
- && variantData.generateRClassTask == null) {
- variantData.generateRClassTask = processResources
- variantData.sourceGenTask.dependsOn processResources
- processResources.enforceUniquePackageName = getExtension().getEnforceUniquePackageName()
-
- conventionMapping(processResources).map("libraries") {
- getTextSymbolDependencies(config.allLibraries)
- }
- conventionMapping(processResources).map("packageForR") {
- config.originalApplicationId
- }
-
- // TODO: unify with generateBuilderConfig, compileAidl, and library packaging somehow?
- conventionMapping(processResources).map("sourceOutputDir") {
- project.file(
- "$project.buildDir/${FD_GENERATED}/source/r/${config.dirName}")
- }
-
- conventionMapping(processResources).map("textSymbolOutputDir") {
- project.file(symbolLocation)
- }
-
- if (config.buildType.isMinifyEnabled()) {
- if (config.buildType.shrinkResources && config.useJack) {
- LoggingUtil.displayWarning(logger, project,
- "shrinkResources does not yet work with useJack=true")
- }
- conventionMapping(processResources).map("proguardOutputFile") {
- project.file(
- "$project.buildDir/${FD_INTERMEDIATES}/proguard-rules/${config.dirName}/aapt_rules.txt")
- }
- } else if (config.buildType.shrinkResources) {
- LoggingUtil.displayWarning(logger, project,
- "To shrink resources you must also enable ProGuard")
- }
- }
-
- conventionMapping(processResources).map("manifestFile") {
- variantOutputData.manifestProcessorTask.getOutputFile()
- }
-
- conventionMapping(processResources).map("resDir") {
- variantData.finalResourcesDir
- }
-
- conventionMapping(processResources).map("assetsDir") {
- variantData.mergeAssetsTask.outputDir
- }
-
- if (generateResourcePackage) {
- conventionMapping(processResources).map("packageOutputFile") {
- project.file(
- "$project.buildDir/${FD_INTERMEDIATES}/res/resources-${outputBaseName}.ap_")
- }
- }
-
- conventionMapping(processResources).map("type") { config.type }
- conventionMapping(processResources).map("debuggable") { config.buildType.debuggable }
- conventionMapping(processResources).map("aaptOptions") { getExtension().aaptOptions }
- conventionMapping(processResources).
- map("pseudoLocalesEnabled") { config.buildType.pseudoLocalesEnabled }
-
- conventionMapping(processResources).map("resourceConfigs") {
- Collection<String> resConfigs = config.mergedFlavor.resourceConfigurations;
- if (resConfigs != null && resConfigs.size() == 1
- && Iterators.getOnlyElement(resConfigs.iterator()).equals("auto")) {
-
- return variantData.discoverListOfResourceConfigs();
- }
- return config.mergedFlavor.resourceConfigurations
- }
- conventionMapping(processResources).map("preferredDensity") {
- variantOutputData.getMainOutputFile().getFilter(OutputFile.DENSITY)
- }
-
}
}
@@ -1011,8 +608,8 @@
* unchanged to the APK build output directory.
* @param variantData the variant configuration.
*/
- public void createSplitResourcesTasks(
- @NonNull BaseVariantData<? extends BaseVariantOutputData> variantData) {
+ public void createSplitResourcesTasks(@NonNull VariantScope scope) {
+ BaseVariantData<? extends BaseVariantOutputData> variantData = scope.variantData
assert variantData.getSplitHandlingPolicy() ==
BaseVariantData.SplitHandlingPolicy.RELEASE_21_AND_AFTER_POLICY;
@@ -1029,11 +626,12 @@
}
BaseVariantOutputData variantOutputData = outputs.get(0);
+ VariantOutputScope variantOutputScope = variantOutputData.scope
variantOutputData.packageSplitResourcesTask =
project.tasks.create("package${config.fullName.capitalize()}SplitResources",
PackageSplitRes);
variantOutputData.packageSplitResourcesTask.inputDirectory =
- variantOutputData.processResourcesTask.packageOutputFile.getParentFile()
+ variantOutputScope.getProcessResourcePackageOutputFile().getParentFile()
variantOutputData.packageSplitResourcesTask.densitySplits = densityFilters
variantOutputData.packageSplitResourcesTask.languageSplits = languageFilters
variantOutputData.packageSplitResourcesTask.outputBaseName = config.baseName
@@ -1042,7 +640,7 @@
variantOutputData.packageSplitResourcesTask.outputDirectory =
new File("$project.buildDir/${FD_INTERMEDIATES}/splits/${config.dirName}")
variantOutputData.packageSplitResourcesTask.androidBuilder = androidBuilder
- variantOutputData.packageSplitResourcesTask.dependsOn variantOutputData.processResourcesTask
+ variantOutputData.packageSplitResourcesTask.dependsOn variantOutputScope.processResourcesTask.name
SplitZipAlign zipAlign = project.tasks.
create("zipAlign${config.fullName.capitalize()}SplitPackages", SplitZipAlign)
@@ -1069,7 +667,8 @@
zipAlign.dependsOn(variantOutputData.packageSplitResourcesTask)
}
- public void createSplitAbiTasks(@NonNull ApplicationVariantData variantData) {
+ public void createSplitAbiTasks(@NonNull VariantScope scope) {
+ ApplicationVariantData variantData = (ApplicationVariantData) scope.getVariantData()
assert variantData.getSplitHandlingPolicy() ==
BaseVariantData.SplitHandlingPolicy.RELEASE_21_AND_AFTER_POLICY;
@@ -1106,7 +705,7 @@
conventionMapping(generateSplitAbiRes).map("aaptOptions") {
getExtension().aaptOptions
}
- generateSplitAbiRes.dependsOn variantOutputData.processResourcesTask
+ generateSplitAbiRes.dependsOn variantOutputData.scope.processResourcesTask.name
// then package those resources with the appropriate JNI libraries.
variantOutputData.packageSplitAbiTask =
@@ -1164,62 +763,17 @@
}
public void createProcessJavaResTask(
- @NonNull BaseVariantData<? extends BaseVariantOutputData> variantData) {
- VariantConfiguration variantConfiguration = variantData.variantConfiguration
-
- Copy processResources = project.tasks.create(
- "process${variantData.variantConfiguration.fullName.capitalize()}JavaRes",
- ProcessResources);
- variantData.processJavaResourcesTask = processResources
-
- // set the input
- processResources.from(((AndroidSourceSet) variantConfiguration.defaultSourceSet).resources.
- getSourceFiles())
-
- if (variantConfiguration.type != ANDROID_TEST) {
- processResources.from(
- ((AndroidSourceSet) variantConfiguration.buildTypeSourceSet).resources.
- getSourceFiles())
- }
- if (variantConfiguration.hasFlavors()) {
- for (SourceProvider flavorSourceSet : variantConfiguration.flavorSourceProviders) {
- processResources.
- from(((AndroidSourceSet) flavorSourceSet).resources.getSourceFiles())
- }
- }
-
- conventionMapping(processResources).map("destinationDir") {
- project.file(
- "$project.buildDir/${FD_INTERMEDIATES}/javaResources/${variantData.variantConfiguration.dirName}")
- }
+ @NonNull TaskFactory tasks,
+ @NonNull VariantScope scope) {
+ scope.processJavaResourcesTask = androidTasks.create(
+ tasks, new ProcessJavaResConfigAction(scope));
}
- public void createAidlTask(
- @NonNull BaseVariantData<? extends BaseVariantOutputData> variantData,
- @Nullable File parcelableDir) {
- VariantConfiguration variantConfiguration = variantData.variantConfiguration
-
- def compileTask = project.tasks.create(
- "compile${variantData.variantConfiguration.fullName.capitalize()}Aidl",
- AidlCompile)
- variantData.aidlCompileTask = compileTask
-
- variantData.sourceGenTask.dependsOn compileTask
- variantData.aidlCompileTask.dependsOn variantData.prepareDependenciesTask
-
- compileTask.androidBuilder = androidBuilder
- compileTask.incrementalFolder =
- project.file(
- "$project.buildDir/${FD_INTERMEDIATES}/incremental/aidl/${variantData.variantConfiguration.dirName}")
-
- conventionMapping(compileTask).map("sourceDirs") { variantConfiguration.aidlSourceList }
- conventionMapping(compileTask).map("importDirs") { variantConfiguration.aidlImports }
-
- conventionMapping(compileTask).map("sourceOutputDir") {
- project.file(
- "$project.buildDir/${FD_GENERATED}/source/aidl/${variantData.variantConfiguration.dirName}")
- }
- compileTask.aidlParcelableDir = parcelableDir
+ public void createAidlTask(@NonNull TaskFactory tasks, @NonNull VariantScope scope) {
+ scope.aidlCompileTask = androidTasks.create(tasks,
+ new AidlCompile.ConfigAction(scope));
+ scope.sourceGenTask.dependsOn(tasks, scope.aidlCompileTask)
+ scope.aidlCompileTask.dependsOn(tasks, scope.variantData.prepareDependenciesTask)
}
public void createJackAndUnitTestVerificationTask(
@@ -1235,124 +789,59 @@
}
public void createJavaCompileTask(
- @NonNull BaseVariantData<? extends BaseVariantOutputData> variantData,
- @Nullable BaseVariantData<? extends BaseVariantOutputData> testedVariantData) {
- def javaCompileTask = project.tasks.create(
- "compile${variantData.variantConfiguration.fullName.capitalize()}Java",
- JavaCompile)
+ @NonNull final TaskFactory tasks,
+ @NonNull final VariantScope scope) {
+ BaseVariantData<? extends BaseVariantOutputData> variantData = scope.variantData;
+ AndroidTask<JavaCompile> javaCompileTask = androidTasks.create(tasks,
+ new JavaCompileConfigAction(scope));
+ scope.javaCompileTask = javaCompileTask;
- variantData.javaCompileTask = javaCompileTask
- variantData.compileTask.dependsOn variantData.javaCompileTask
- optionalDependsOn(
- variantData.javaCompileTask, variantData.sourceGenTask)
+ scope.compileTask.dependsOn(tasks, javaCompileTask);
- javaCompileTask.source = variantData.getJavaSources()
-
- conventionMapping(javaCompileTask).map("classpath") {
- FileCollection classpath = project.files(
- androidBuilder.getCompileClasspath(variantData.variantConfiguration))
-
- if (testedVariantData) {
- // For libraries, the classpath from androidBuilder includes the library output
- // (bundle/classes.jar) as a normal dependency. In unit tests we don't want to package
- // the jar at every run, so we use the *.class files instead.
- if (testedVariantData.type != LIBRARY || variantData.type == UNIT_TEST) {
- classpath = classpath +
- testedVariantData.javaCompileTask.classpath +
- testedVariantData.javaCompileTask.outputs.files
- }
-
- if (variantData.type == UNIT_TEST && testedVariantData.type == LIBRARY) {
- // The bundled classes.jar may exist, but it's probably old. Don't use it, we
- // already have the *.class files in the classpath.
- classpath -= project.files(testedVariantData.variantConfiguration.output.jarFile)
- }
- }
-
- return classpath
- }
-
- javaCompileTask.dependsOn variantData.prepareDependenciesTask
- javaCompileTask.dependsOn variantData.processJavaResourcesTask
+ javaCompileTask.optionalDependsOn(tasks, scope.sourceGenTask)
+ javaCompileTask.dependsOn(tasks,
+ scope.getVariantData().prepareDependenciesTask,
+ scope.processJavaResourcesTask);
// TODO - dependency information for the compile classpath is being lost.
// Add a temporary approximation
- javaCompileTask.dependsOn variantData.variantDependency.compileConfiguration.buildDependencies
+ javaCompileTask.dependsOn(tasks,
+ scope.getVariantData().getVariantDependency().getCompileConfiguration()
+ .getBuildDependencies());
- conventionMapping(javaCompileTask).map("destinationDir") {
- project.file(
- "$project.buildDir/${FD_INTERMEDIATES}/classes/${variantData.variantConfiguration.dirName}")
- }
- conventionMapping(javaCompileTask).map("dependencyCacheDir") {
- project.file(
- "$project.buildDir/${FD_INTERMEDIATES}/dependency-cache/${variantData.variantConfiguration.dirName}")
+ if (variantData.getType().isForTesting()) {
+ BaseVariantData testedVariantData =
+ ((TestVariantData) variantData).getTestedVariantData() as BaseVariantData
+ javaCompileTask.dependsOn(tasks,
+ testedVariantData.javaCompileTask ?: testedVariantData.scope.javaCompileTask)
}
- configureLanguageLevel(javaCompileTask)
- javaCompileTask.options.encoding = getExtension().compileOptions.encoding
-
- // setup the boot classpath just before the task actually runs since this will
- // force the sdk to be parsed.
- javaCompileTask.doFirst {
- javaCompileTask.options.bootClasspath =
- androidBuilder.getBootClasspathAsStrings().join(File.pathSeparator)
- }
// Create jar task for uses by external modules.
if (variantData.variantDependency.classesConfiguration != null) {
- Jar jar = project.tasks.create(
- "package${variantData.variantConfiguration.fullName.capitalize()}JarArtifact",
- Jar);
- variantData.classesJarTask = jar
- jar.dependsOn javaCompileTask
+ tasks.create("package${variantData.variantConfiguration.fullName.capitalize()}JarArtifact", Jar) { Jar jar ->
+ variantData.classesJarTask = jar
+ jar.dependsOn javaCompileTask.name
- // add the class files (whether they are instrumented or not.
- jar.from({ variantData.javaCompileTask.destinationDir })
+ // add the class files (whether they are instrumented or not.
+ jar.from({ scope.getJavaOutputDir() })
- jar.destinationDir = project.file(
- "$project.buildDir/${FD_INTERMEDIATES}/classes-jar/${variantData.variantConfiguration.dirName}")
- jar.archiveName = "classes.jar"
+ jar.destinationDir = scope.getJavaOutputDir();
+ jar.archiveName = "classes.jar"
+ }
}
}
public void createGenerateMicroApkDataTask(
- @NonNull BaseVariantData<? extends BaseVariantOutputData> variantData,
+ @NonNull TaskFactory tasks,
+ @NonNull VariantScope scope,
@NonNull Configuration config) {
- GenerateApkDataTask task = project.tasks.create(
- "handle${variantData.variantConfiguration.fullName.capitalize()}MicroApk",
- GenerateApkDataTask)
-
- variantData.generateApkDataTask = task
-
- task.androidBuilder = androidBuilder
- conventionMapping(task).map("resOutputDir") {
- project.file(
- "$project.buildDir/${FD_GENERATED}/res/microapk/${variantData.variantConfiguration.dirName}")
- }
- conventionMapping(task).map("apkFile") {
- // only care about the first one. There shouldn't be more anyway.
- config.getFiles().iterator().next()
- }
- conventionMapping(task).map("manifestFile") {
- project.file(
- "$project.buildDir/${FD_INTERMEDIATES}/${FD_GENERATED}/manifests/microapk/${variantData.variantConfiguration.dirName}/${FN_ANDROID_MANIFEST_XML}")
- }
- conventionMapping(task).map("mainPkgName") {
- variantData.variantConfiguration.getApplicationId()
- }
-
- conventionMapping(task).map("minSdkVersion") {
- variantData.variantConfiguration.getMinSdkVersion().apiLevel
- }
-
- conventionMapping(task).map("targetSdkVersion") {
- variantData.variantConfiguration.getTargetSdkVersion().apiLevel
- }
-
- task.dependsOn config
+ AndroidTask<GenerateApkDataTask> generateMicroApkTask = androidTasks.create(tasks,
+ new GenerateApkDataTask.ConfigAction(scope, config));
+ generateMicroApkTask.dependsOn tasks, config
// the merge res task will need to run after this one.
- variantData.resourceGenTask.dependsOn task
+ scope.resourceGenTask.dependsOn(tasks, generateMicroApkTask);
}
public void createNdkTasks(
@@ -1417,11 +906,12 @@
@NonNull TestVariantData variantData) {
BaseVariantData testedVariantData = variantData.getTestedVariantData() as BaseVariantData
variantData.assembleVariantTask.dependsOn createMockableJar
+ VariantScope variantScope = variantData.getScope()
- createPreBuildTasks(variantData)
- createProcessJavaResTask(variantData)
- createCompileAnchorTask(variantData)
- createJavaCompileTask(variantData, testedVariantData)
+ createPreBuildTasks(tasks, variantScope)
+ createProcessJavaResTask(tasks, variantScope)
+ createCompileAnchorTask(tasks, variantScope)
+ createJavaCompileTask(tasks, variantScope);
createJackAndUnitTestVerificationTask(variantData, testedVariantData)
createUnitTestTask(tasks, variantData)
@@ -1437,6 +927,8 @@
public void createAndroidTestVariantTasks(
@NonNull TaskFactory tasks,
@NonNull TestVariantData variantData) {
+ VariantScope variantScope = variantData.getScope()
+
BaseVariantData<? extends BaseVariantOutputData> testedVariantData =
variantData.
getTestedVariantData() as BaseVariantData<? extends BaseVariantOutputData>
@@ -1445,62 +937,61 @@
BaseVariantOutputData variantOutputData = variantData.outputs.get(0)
BaseVariantOutputData testedVariantOutputData = testedVariantData.outputs.get(0)
- createAnchorTasks(variantData)
+ createAnchorTasks(tasks, variantScope)
// Add a task to process the manifest
- createProcessTestManifestTask(variantData, "manifests")
+ createProcessTestManifestTask(tasks, variantScope)
// Add a task to create the res values
- createGenerateResValuesTask(variantData)
+ createGenerateResValuesTask(tasks, variantScope)
// Add a task to compile renderscript files.
- createRenderscriptTask(variantData)
+ createRenderscriptTask(tasks, variantScope)
// Add a task to merge the resource folders
- createMergeResourcesTask(variantData, true /*process9Patch*/)
+ createMergeResourcesTask(tasks, variantScope)
// Add a task to merge the assets folders
- createMergeAssetsTask(variantData, null /*default location*/, true /*includeDependencies*/)
+ createMergeAssetsTask(tasks, variantScope)
if (testedVariantData.variantConfiguration.type == VariantType.LIBRARY) {
// in this case the tested library must be fully built before test can be built!
if (testedVariantOutputData.assembleTask != null) {
- variantOutputData.manifestProcessorTask.dependsOn testedVariantOutputData.assembleTask
- variantData.mergeResourcesTask.dependsOn testedVariantOutputData.assembleTask
+ variantOutputData.scope.manifestProcessorTask.dependsOn(
+ tasks, testedVariantOutputData.assembleTask)
+ variantScope.mergeResourcesTask.dependsOn(tasks, testedVariantOutputData.assembleTask)
}
}
// Add a task to create the BuildConfig class
- createBuildConfigTask(variantData)
+ createBuildConfigTask(tasks, variantScope)
- createPreprocessResourcesTask(variantData)
+ createPreprocessResourcesTask(tasks, variantScope)
// Add a task to generate resource source files
- createProcessResTask(variantData, true /*generateResourcePackage*/)
+ createProcessResTask(tasks, variantScope, true /*generateResourcePackage*/)
// process java resources
- createProcessJavaResTask(variantData)
+ createProcessJavaResTask(tasks, variantScope)
- createAidlTask(variantData, null /*parcelableDir*/)
+ createAidlTask(tasks, variantScope)
// Add NDK tasks
if (isNdkTaskNeeded) {
createNdkTasks(variantData)
}
+ variantScope.setNdkBuildable(getNdkBuildable(variantData))
+ variantScope.setNdkOutputDirectories(getNdkOutputDirectories(variantData))
// Add a task to compile the test application
if (variantData.getVariantConfiguration().useJack) {
createJackTask(variantData, testedVariantData);
} else {
- createJavaCompileTask(variantData, testedVariantData)
- createPostCompilationTasks(variantData);
+ //createJavaCompileTask(variantData, testedVariantData)
+ createJavaCompileTask(tasks, variantScope)
+ createPostCompilationTasks(tasks, variantScope)
}
- // Variant scope should be create at the function, but there is currently a dependencies
- // on the NdkCompile tasks, and the scope mechanism does not support lazy evaluation yet.
- VariantScope variantScope = createVariantScope(variantData);
-
-
createPackagingTask(tasks, variantScope, false /*publishApk*/)
tasks.named(ASSEMBLE_ANDROID_TEST) {
@@ -1511,16 +1002,17 @@
}
// TODO - should compile src/lint/java from src/lint/java and jar it into build/lint/lint.jar
- public void createLintCompileTask() {
- lintCompile = project.tasks.create("compileLint", Task)
- File outputDir = new File("$project.buildDir/${FD_INTERMEDIATES}/lint")
+ private void createLintCompileTask(TaskFactory tasks) {
+ tasks.create(LINT_COMPILE, Task) { Task lintCompile ->
+ File outputDir = new File("$project.buildDir/${FD_INTERMEDIATES}/lint")
- lintCompile.doFirst {
- // create the directory for lint output if it does not exist.
- if (!outputDir.exists()) {
- boolean mkdirs = outputDir.mkdirs();
- if (!mkdirs) {
- throw new GradleException("Unable to create lint output directory.")
+ lintCompile.doFirst {
+ // create the directory for lint output if it does not exist.
+ if (!outputDir.exists()) {
+ boolean mkdirs = outputDir.mkdirs();
+ if (!mkdirs) {
+ throw new GradleException("Unable to create lint output directory.")
+ }
}
}
}
@@ -1537,49 +1029,29 @@
// Add tasks for running lint on individual variants. We've already added a
// lint task earlier which runs on all variants.
- public void createLintTasks(
- TaskFactory tasks,
- List<BaseVariantData<? extends BaseVariantOutputData>> variantDataList) {
- final Lint lint = project.tasks.create("lint", Lint)
- lint.description = "Runs lint on all variants."
- lint.group = JavaBasePlugin.VERIFICATION_GROUP
- lint.setLintOptions(getExtension().lintOptions)
- lint.setSdkHome(sdkHandler.getSdkFolder())
- lint.setToolingRegistry(toolingRegistry)
- tasks.named(JavaBasePlugin.CHECK_TASK_NAME) {
- it.dependsOn lint
+ public void createLintTasks(TaskFactory tasks, VariantScope scope) {
+ final BaseVariantData<? extends BaseVariantOutputData> baseVariantData = scope.variantData
+ if (!isLintVariant(baseVariantData)) {
+ return;
}
- lintAll = lint
- int count = variantDataList.size()
- for (int i = 0; i < count; i++) {
- final BaseVariantData<? extends BaseVariantOutputData> baseVariantData =
- variantDataList.get(i)
- if (!isLintVariant(baseVariantData)) {
- continue;
+ // wire the main lint task dependency.
+ tasks.named(LINT) {
+ it.dependsOn(LINT_COMPILE)
+ if (baseVariantData.javaCompileTask != null) {
+ it.dependsOn(baseVariantData.javaCompileTask)
}
-
- // wire the main lint task dependency.
- lint.dependsOn lintCompile
- optionalDependsOn(lint, baseVariantData.javaCompileTask)
-
- String variantName = baseVariantData.variantConfiguration.fullName
- def capitalizedVariantName = variantName.capitalize()
- Lint variantLintCheck = project.tasks.create("lint" + capitalizedVariantName, Lint)
- variantLintCheck.dependsOn lintCompile
- optionalDependsOn(variantLintCheck, baseVariantData.javaCompileTask)
-
- // Note that we don't do "lint.dependsOn lintCheck"; the "lint" target will
- // on its own run through all variants (and compare results), it doesn't delegate
- // to the individual tasks (since it needs to coordinate data collection and
- // reporting)
- variantLintCheck.setLintOptions(getExtension().lintOptions)
- variantLintCheck.setSdkHome(sdkHandler.getSdkFolder())
- variantLintCheck.setVariantName(variantName)
- variantLintCheck.setToolingRegistry(toolingRegistry)
- variantLintCheck.description = "Runs lint on the " + capitalizedVariantName + " build."
- variantLintCheck.group = JavaBasePlugin.VERIFICATION_GROUP
+ if (scope.javaCompileTask != null) {
+ it.dependsOn(scope.javaCompileTask.name)
+ }
}
+
+ AndroidTask<Lint> variantLintCheck = androidTasks.create(
+ tasks, new Lint.ConfigAction(scope))
+ variantLintCheck.dependsOn(tasks, LINT_COMPILE)
+ variantLintCheck.optionalDependsOn(tasks,
+ baseVariantData.javaCompileTask,
+ scope.javaCompileTask)
}
private void createLintVitalTask(@NonNull ApkVariantData variantData) {
@@ -1600,11 +1072,11 @@
lintReleaseCheck.setFatalOnly(true)
lintReleaseCheck.description = "Runs lint on just the fatal issues in the " +
capitalizedVariantName + " build."
- variantData.assembleVariantTask.dependsOn lintReleaseCheck
+ //variantData.assembleVariantTask.dependsOn lintReleaseCheck
// If lint is being run, we do not need to run lint vital.
project.gradle.taskGraph.whenReady { TaskExecutionGraph taskGraph ->
- if (taskGraph.hasTask(lintAll)) {
+ if (taskGraph.hasTask(LINT)) {
lintReleaseCheck.setEnabled(false)
}
}
@@ -1786,7 +1258,7 @@
}
protected void createConnectedTestForVariantData(
- TaskFactory tasks,
+ @NonNull TaskFactory tasks,
final TestVariantData testVariantData,
TestType testType) {
BaseVariantData<? extends BaseVariantOutputData> baseVariantData =
@@ -2024,19 +1496,22 @@
Closure<List<File>> inputLibraries
}
- public void createJarTask(@NonNull BaseVariantData variantData) {
+ public void createJarTask(@NonNull TaskFactory tasks, @NonNull final VariantScope scope) {
+ BaseVariantData variantData = scope.variantData;
GradleVariantConfiguration config = variantData.variantConfiguration
- AndroidJarTask jarTask = project.tasks.create(
- "jar${config.fullName.capitalize()}Classes",
- AndroidJarTask)
+ tasks.create("jar${config.fullName.capitalize()}Classes", AndroidJarTask) { AndroidJarTask jarTask ->
+ // AndroidJarTask jarTask = project.tasks.create(
+ // "jar${config.fullName.capitalize()}Classes",
+ // AndroidJarTask)
- jarTask.setArchiveName("classes.jar");
- jarTask.setDestinationDir(project.file(
- "$project.buildDir/${FD_INTERMEDIATES}/packaged/${config.dirName}/"))
- jarTask.from(variantData.javaCompileTask.destinationDir)
- jarTask.dependsOn variantData.javaCompileTask
- variantData.binayFileProviderTask = jarTask
+ jarTask.setArchiveName("classes.jar");
+ jarTask.setDestinationDir(new File(
+ "$scope.globalScope.buildDir/${FD_INTERMEDIATES}/packaged/${config.dirName}/"))
+ jarTask.from(scope.javaOutputDir);
+ jarTask.dependsOn scope.javaCompileTask.name
+ variantData.binayFileProviderTask = jarTask
+ }
}
/**
@@ -2047,88 +1522,54 @@
*
* @param variantData the variant data.
*/
- public void createPostCompilationTasks(@NonNull ApkVariantData variantData) {
+ public void createPostCompilationTasks(TaskFactory tasks, @NonNull final VariantScope scope) {
+ ApkVariantData variantData = (ApkVariantData) scope.variantData;
GradleVariantConfiguration config = variantData.variantConfiguration
- boolean isTestForApp = config.type.isForTesting() &&
- (variantData as TestVariantData).testedVariantData.variantConfiguration.type ==
- DEFAULT
-
- boolean isMinifyEnabled = config.isMinifyEnabled()
- boolean isMultiDexEnabled = config.isMultiDexEnabled() && !isTestForApp
- boolean isLegacyMultiDexMode = config.isLegacyMultiDexMode()
- File multiDexKeepProguard = config.getMultiDexKeepProguard()
- File multiDexKeepFile = config.getMultiDexKeepFile()
-
- boolean isTestCoverageEnabled = config.buildType.isTestCoverageEnabled() &&
- !config.type.isForTesting()
-
- // common dex task configuration
- String dexTaskName = "dex${config.fullName.capitalize()}"
- Dex dexTask = project.tasks.create(dexTaskName, Dex)
- variantData.dexTask = dexTask
- dexTask.androidBuilder = androidBuilder
- conventionMapping(dexTask).map("outputFolder") {
- project.file("${project.buildDir}/${FD_INTERMEDIATES}/dex/${config.dirName}")
- }
- dexTask.tmpFolder =
- project.file("$project.buildDir/${FD_INTERMEDIATES}/tmp/dex/${config.dirName}")
- dexTask.dexOptions = getExtension().dexOptions
- dexTask.multiDexEnabled = isMultiDexEnabled
- dexTask.legacyMultiDexMode = isLegacyMultiDexMode
- // dx doesn't work with receving --no-optimize in debug so we disable it for now.
- dexTask.optimize = true //!variantData.variantConfiguration.buildType.debuggable
-
-
// data holding dependencies and input for the dex. This gets updated as new
// post-compilation steps are inserted between the compilation and dx.
PostCompilationData pcData = new PostCompilationData()
- pcData.classGeneratingTask = [variantData.javaCompileTask]
+ pcData.classGeneratingTask = [scope.javaCompileTask.name]
pcData.libraryGeneratingTask =
[variantData.variantDependency.packageConfiguration.buildDependencies]
pcData.inputFiles = {
variantData.javaCompileTask.outputs.files.files as List
}
pcData.inputDir = {
- variantData.javaCompileTask.destinationDir
+ scope.javaOutputDir
}
pcData.inputLibraries = {
- androidBuilder.getPackagedJars(config) as List
+ scope.globalScope.androidBuilder.getPackagedJars(config) as List
}
// ---- Code Coverage first -----
+ boolean isTestCoverageEnabled = config.buildType.isTestCoverageEnabled() &&
+ !config.type.isForTesting()
if (isTestCoverageEnabled) {
- pcData = createJacocoTask(config, variantData, pcData)
+ pcData = createJacocoTask(tasks, scope, pcData);
}
- // ----- Minify next ----
- BaseVariantData<? extends BaseVariantOutputData> testedVariantData =
- (variantData instanceof TestVariantData ? variantData.testedVariantData :
- null) as BaseVariantData
+ boolean isTestForApp = config.type.isForTesting() &&
+ (variantData as TestVariantData).testedVariantData.variantConfiguration.type ==
+ DEFAULT
+ boolean isMinifyEnabled = config.isMinifyEnabled()
+ boolean isMultiDexEnabled = config.isMultiDexEnabled() && !isTestForApp
+ boolean isLegacyMultiDexMode = config.isLegacyMultiDexMode()
- File outFile = maybeCreateProguardTasks(variantData, testedVariantData, pcData);
+ // ----- Minify next ----
+ File outFile = maybeCreateProguardTasks(tasks, scope, pcData);
if (outFile != null) {
pcData.inputFiles = { [outFile] }
pcData.inputLibraries = { [] }
} else if ((getExtension().dexOptions.preDexLibraries && !isMultiDexEnabled) ||
(isMultiDexEnabled && !isLegacyMultiDexMode)) {
- def preDexTaskName = "preDex${config.fullName.capitalize()}"
- PreDex preDexTask = project.tasks.create(preDexTaskName, PreDex)
- variantData.preDexTask = preDexTask
- preDexTask.androidBuilder = androidBuilder
- preDexTask.dexOptions = getExtension().dexOptions
- preDexTask.multiDex = isMultiDexEnabled
-
- conventionMapping(preDexTask).map("inputFiles", pcData.inputLibraries)
- conventionMapping(preDexTask).map("outputFolder") {
- project.file(
- "${project.buildDir}/${FD_INTERMEDIATES}/pre-dexed/${config.dirName}")
- }
+ AndroidTask<PreDex> preDexTask =
+ androidTasks.create(tasks, new PreDex.ConfigAction(scope, pcData))
// update dependency.
- optionalDependsOn(preDexTask, pcData.libraryGeneratingTask)
- pcData.libraryGeneratingTask = [preDexTask] as List<Object>
+ preDexTask.dependsOn(tasks, pcData.libraryGeneratingTask)
+ pcData.libraryGeneratingTask = [preDexTask.name] as List<Object>
// update inputs
if (isMultiDexEnabled) {
@@ -2136,33 +1577,32 @@
} else {
pcData.inputLibraries = {
- project.fileTree(preDexTask.outputFolder).files as List
+ project.fileTree(scope.getPreDexOutputDir()).files as List
}
}
}
+ AndroidTask<CreateMainDexList> createMainDexListTask = null;
+ AndroidTask<RetraceMainDexList> retraceTask = null;
+
// ----- Multi-Dex support
if (isMultiDexEnabled && isLegacyMultiDexMode) {
if (!isMinifyEnabled) {
// create a task that will convert the output of the compilation
// into a jar. This is needed by the multi-dex input.
- JarMergingTask jarMergingTask = project.tasks.create(
- "packageAll${config.fullName.capitalize()}ClassesForMultiDex",
- JarMergingTask)
- conventionMapping(jarMergingTask).map("inputJars", pcData.inputLibraries)
- conventionMapping(jarMergingTask).map("inputDir", pcData.inputDir)
-
- jarMergingTask.jarFile = project.file(
- "$project.buildDir/${FD_INTERMEDIATES}/multi-dex/${config.dirName}/allclasses.jar")
+ AndroidTask<JarMergingTask> jarMergingTask = androidTasks.create(tasks,
+ new JarMergingTask.ConfigAction(scope, pcData));
// update dependencies
- optionalDependsOn(jarMergingTask, pcData.classGeneratingTask)
- optionalDependsOn(jarMergingTask, pcData.libraryGeneratingTask)
- pcData.libraryGeneratingTask = [jarMergingTask]
- pcData.classGeneratingTask = [jarMergingTask]
+ jarMergingTask.optionalDependsOn(
+ tasks,
+ pcData.classGeneratingTask,
+ pcData.libraryGeneratingTask)
+ pcData.libraryGeneratingTask = [jarMergingTask.name]
+ pcData.classGeneratingTask = [jarMergingTask.name]
// Update the inputs
- pcData.inputFiles = { [jarMergingTask.jarFile] }
+ pcData.inputFiles = { [scope.getJarMergingOutputFile()] }
pcData.inputDir = null
pcData.inputLibraries = { [] }
}
@@ -2170,148 +1610,70 @@
// ----------
// Create a task to collect the list of manifest entry points which are
// needed in the primary dex
- CreateManifestKeepList manifestKeepListTask = project.tasks.create(
- "collect${config.fullName.capitalize()}MultiDexComponents",
- CreateManifestKeepList)
-
- // since all the output have the same manifest, besides the versionCode,
- // we can take any of the output and use that.
- final BaseVariantOutputData output = variantData.outputs.get(0)
- manifestKeepListTask.dependsOn output.manifestProcessorTask
- conventionMapping(manifestKeepListTask).map("manifest") {
- output.manifestProcessorTask.getOutputFile()
- }
-
- manifestKeepListTask.proguardFile = multiDexKeepProguard
- manifestKeepListTask.outputFile = project.file(
- "${project.buildDir}/${FD_INTERMEDIATES}/multi-dex/${config.dirName}/manifest_keep.txt")
-
- //variant.ext.collectMultiDexComponents = manifestKeepListTask
+ AndroidTask<CreateManifestKeepList> manifestKeepListTask = androidTasks.create(tasks,
+ new CreateManifestKeepList.ConfigAction(scope, pcData))
+ manifestKeepListTask.dependsOn(tasks, variantData.outputs.get(0).scope.manifestProcessorTask)
// ----------
// Create a proguard task to shrink the classes to manifest components
- ProGuardTask proguardComponentsTask = createShrinkingProGuardTask(project,
- "shrink${config.fullName.capitalize()}MultiDexComponents")
-
- proguardComponentsTask.configuration(manifestKeepListTask.outputFile)
-
- proguardComponentsTask.libraryjars({
- checkNotNull(androidBuilder.getTargetInfo())
- File shrinkedAndroid = new File(androidBuilder.getTargetInfo().buildTools.location,
- "lib${File.separatorChar}shrinkedAndroid.jar")
-
- // TODO remove in 1.0
- // STOPSHIP
- if (!shrinkedAndroid.isFile()) {
- shrinkedAndroid = new File(androidBuilder.getTargetInfo().buildTools.location,
- "multidex${File.separatorChar}shrinkedAndroid.jar")
- }
- return shrinkedAndroid
- })
-
- proguardComponentsTask.injars(pcData.inputFiles.call().iterator().next())
-
- File componentsJarFile = project.file(
- "${project.buildDir}/${FD_INTERMEDIATES}/multi-dex/${config.dirName}/componentClasses.jar")
- proguardComponentsTask.outjars(componentsJarFile)
-
- proguardComponentsTask.printconfiguration(
- "${project.buildDir}/${FD_INTERMEDIATES}/multi-dex/${config.dirName}/components.flags")
+ AndroidTask<ProGuardTask> proguardComponentsTask =
+ androidTasks.create(tasks, new ProGuardTaskConfigAction(scope, pcData))
// update dependencies
- proguardComponentsTask.dependsOn manifestKeepListTask
- optionalDependsOn(proguardComponentsTask, pcData.classGeneratingTask)
- optionalDependsOn(proguardComponentsTask, pcData.libraryGeneratingTask)
+ proguardComponentsTask.dependsOn tasks, manifestKeepListTask
+ proguardComponentsTask.optionalDependsOn(tasks,
+ pcData.classGeneratingTask,
+ pcData.libraryGeneratingTask)
// ----------
// Compute the full list of classes for the main dex file
- CreateMainDexList createMainDexListTask = project.tasks.create(
- "create${config.fullName.capitalize()}MainDexClassList",
- CreateMainDexList)
- createMainDexListTask.androidBuilder = androidBuilder
- createMainDexListTask.dependsOn proguardComponentsTask
+ createMainDexListTask = androidTasks.create(tasks, new CreateMainDexList.ConfigAction(scope, pcData))
+ createMainDexListTask.dependsOn(tasks, proguardComponentsTask)
//createMainDexListTask.dependsOn { proguardMainDexTask }
- def files = pcData.inputFiles
- createMainDexListTask.allClassesJarFile = files().first()
- conventionMapping(createMainDexListTask).map("componentsJarFile") { componentsJarFile }
- // conventionMapping(createMainDexListTask).map("includeInMainDexJarFile") { mainDexJarFile }
- createMainDexListTask.mainDexListFile = multiDexKeepFile
- createMainDexListTask.outputFile = project.file(
- "${project.buildDir}/${FD_INTERMEDIATES}/multi-dex/${config.dirName}/maindexlist.txt")
-
- // update dependencies
- dexTask.dependsOn createMainDexListTask
-
// ----------
- // If proguard is on create a de-obfuscated list to aid debugging.
+ // If proguard is enabled, create a de-obfuscated list to aid debugging.
if (isMinifyEnabled) {
- RetraceMainDexList retraceTask = project.tasks.create(
- "retrace${config.fullName.capitalize()}MainDexClassList",
- RetraceMainDexList)
- retraceTask.dependsOn variantData.obfuscationTask, createMainDexListTask
-
- conventionMapping(retraceTask).
- map("mainDexListFile") { createMainDexListTask.outputFile }
- conventionMapping(retraceTask).map("mappingFile") {
- variantData.getMappingFile()
- }
- retraceTask.outputFile = project.file(
- "${project.buildDir}/${FD_INTERMEDIATES}/multi-dex/${config.dirName}/maindexlist_deobfuscated.txt")
- dexTask.dependsOn retraceTask
+ retraceTask = androidTasks.create(tasks,
+ new RetraceMainDexList.ConfigAction(scope, pcData))
+ retraceTask.dependsOn(tasks, scope.obfuscationTask, createMainDexListTask)
}
-
- // configure the dex task to receive the generated class list.
- conventionMapping(dexTask).map("mainDexListFile") { createMainDexListTask.outputFile }
}
- // ----- Dex Task ----
+ AndroidTask<Dex> dexTask = androidTasks.create(tasks, new Dex.ConfigAction(scope, pcData));
+ scope.setDexTask(dexTask);
// dependencies, some of these could be null
- optionalDependsOn(dexTask, variantData.obfuscationTask)
- optionalDependsOn(dexTask, pcData.classGeneratingTask)
- optionalDependsOn(dexTask, pcData.libraryGeneratingTask,)
-
- // inputs
- if (pcData.inputDir != null) {
- conventionMapping(dexTask).map("inputDir", pcData.inputDir)
- }
- conventionMapping(dexTask).map("inputFiles", pcData.inputFiles)
- conventionMapping(dexTask).map("libraries", pcData.inputLibraries)
+ dexTask.optionalDependsOn(tasks,
+ pcData.classGeneratingTask,
+ pcData.libraryGeneratingTask,
+ createMainDexListTask,
+ retraceTask)
}
public PostCompilationData createJacocoTask(
- @NonNull GradleVariantConfiguration config,
- @NonNull BaseVariantData variantData,
+ @NonNull TaskFactory tasks,
+ @NonNull VariantScope scope,
@NonNull final PostCompilationData pcData) {
- final JacocoInstrumentTask jacocoTask = project.tasks.create(
- "instrument${config.fullName.capitalize()}", JacocoInstrumentTask)
- conventionMapping(jacocoTask).map("jacocoClasspath") {
- project.configurations[JacocoPlugin.ANT_CONFIGURATION_NAME]
- }
- // can't directly use the existing inputFiles closure as we need the dir instead :\
- conventionMapping(jacocoTask).map("inputDir", pcData.inputDir)
- conventionMapping(jacocoTask).map("outputDir") {
- project.file(
- "${project.buildDir}/${FD_INTERMEDIATES}/coverage-instrumented-classes/${config.dirName}")
- }
- variantData.jacocoInstrumentTask = jacocoTask
+ AndroidTask<JacocoInstrumentTask> jacocoTask = androidTasks.create(tasks,
+ new JacocoInstrumentTask.ConfigAction(scope, pcData));
+
+ jacocoTask.optionalDependsOn(tasks, pcData.classGeneratingTask)
Copy agentTask = getJacocoAgentTask()
- jacocoTask.dependsOn agentTask
+ jacocoTask.dependsOn(tasks, agentTask)
// update dependency.
PostCompilationData pcData2 = new PostCompilationData()
- optionalDependsOn(jacocoTask, pcData.classGeneratingTask)
- pcData2.classGeneratingTask = [jacocoTask]
+ pcData2.classGeneratingTask = [jacocoTask.name]
pcData2.libraryGeneratingTask = [pcData.libraryGeneratingTask, agentTask]
// update inputs
pcData2.inputFiles = {
- project.files(jacocoTask.getOutputDir()).files as List
+ project.files(scope.variantData.jacocoInstrumentTask.getOutputDir()).files as List
}
pcData2.inputDir = {
- jacocoTask.getOutputDir()
+ scope.variantData.jacocoInstrumentTask.getOutputDir()
}
pcData2.inputLibraries = {
[pcData.inputLibraries.call(), [new File(agentTask.destinationDir, FILE_JACOCO_AGENT)]].
@@ -2321,20 +1683,6 @@
return pcData2
}
- private static ProGuardTask createShrinkingProGuardTask(
- @NonNull Project project,
- @NonNull String name) {
- ProGuardTask task = project.tasks.create(name, ProGuardTask)
-
- task.dontobfuscate()
- task.dontoptimize()
- task.dontpreverify()
- task.dontwarn()
- task.forceprocessing()
-
- return task;
- }
-
public void createJackTask(
@NonNull BaseVariantData<? extends BaseVariantOutputData> variantData,
@Nullable BaseVariantData<? extends BaseVariantOutputData> testedVariantData) {
@@ -2537,27 +1885,44 @@
// loop on all outputs. The only difference will be the name of the task, and location
// of the generated data.
for (ApkVariantOutputData vod : variantData.outputs) {
- VariantOutputScope variantOutputScope = new VariantOutputScope(variantScope, vod);
+ VariantOutputScope variantOutputScope = vod.scope;
// create final var inside the loop to ensure the closures will work.
final ApkVariantOutputData variantOutputData = vod
String outputName = variantOutputData.fullName
- AndroidTask<PackageApplication> packageApp = androidTasks.create(
- tasks,
+ // When shrinking resources, rather than having the packaging task
+ // directly map to the packageOutputFile of ProcessAndroidResources,
+ // we insert the ShrinkResources task into the chain, such that its
+ // input is the ProcessAndroidResources packageOutputFile, and its
+ // output is what the PackageApplication task reads.
+ AndroidTask<ShrinkResources> shrinkTask = null;
+
+ if (config.isMinifyEnabled() && config.getBuildType().isShrinkResources() && !config
+ .getUseJack()) {
+ shrinkTask = androidTasks.create(tasks,
+ new ShrinkResources.ConfigAction(variantOutputScope));
+ shrinkTask.dependsOn(tasks,
+ variantScope.obfuscationTask,
+ variantOutputScope.manifestProcessorTask,
+ variantOutputScope.processResourcesTask);
+ }
+
+ AndroidTask<PackageApplication> packageApp = androidTasks.create(tasks,
new PackageApplication.ConfigAction(variantOutputScope));
packageApp.dependsOn(tasks,
- variantOutputData.processResourcesTask,
- variantData.processJavaResourcesTask,
- variantOutputScope.getVariantScope().getNdkBuildable());
+ variantOutputScope.processResourcesTask,
+ variantOutputScope.variantScope.processJavaResourcesTask,
+ variantOutputScope.variantScope.getNdkBuildable());
- TaskManager.optionalDependsOn(
- packageApp,
+ packageApp.optionalDependsOn(
tasks,
- variantData.dexTask,
- variantData.javaCompileTask,
+ shrinkTask,
+ variantOutputScope.variantScope.dexTask,
+ variantOutputScope.variantScope.javaCompileTask,
+ variantData.javaCompileTask, // TODO: Remove when Jack is converted to AndroidTask.
variantOutputData.packageSplitResourcesTask,
variantOutputData.packageSplitAbiTask);
@@ -2688,49 +2053,23 @@
// right output if there are more than one.
// Add a task to install the application package
if (signedApk) {
- InstallVariantTask installTask = project.tasks.
- create("install${config.fullName.capitalize()}",
- InstallVariantTask)
- installTask.description = "Installs the ${variantData.description}."
- installTask.group = INSTALL_GROUP
- installTask.projectName = project.name
- installTask.variantData = variantData
- installTask.timeOutInMs = getExtension().getAdbOptions().getTimeOutInMs()
- installTask.installOptions = getExtension().getAdbOptions().getInstallOptions()
- installTask.processExecutor = androidBuilder.getProcessExecutor()
- conventionMapping(installTask).map("adbExe") { sdkHandler.sdkInfo?.adb }
- conventionMapping(installTask).map("splitSelectExe") {
- String path = androidBuilder.targetInfo?.buildTools?.getPath(
- BuildToolInfo.PathId.SPLIT_SELECT)
- if (path != null) {
- File splitSelectExe = new File(path)
- return splitSelectExe.exists() ? splitSelectExe : null;
- } else {
- return null;
- }
- }
- installTask.dependsOn variantData.assembleVariantTask
- variantData.installTask = installTask
+ AndroidTask<InstallVariantTask> installTask = androidTasks.create(
+ tasks,
+ new InstallVariantTask.ConfigAction(variantScope));
+ installTask.dependsOn(tasks, variantData.assembleVariantTask)
}
-
if (getExtension().lintOptions.checkReleaseBuilds) {
createLintVitalTask(variantData)
}
// add an uninstall task
- def uninstallTask = project.tasks.create(
- "uninstall${variantData.variantConfiguration.fullName.capitalize()}",
- UninstallTask)
- uninstallTask.description = "Uninstalls the ${variantData.description}."
- uninstallTask.group = INSTALL_GROUP
- uninstallTask.variant = variantData
- uninstallTask.androidBuilder = androidBuilder
- uninstallTask.timeOutInMs = getExtension().getAdbOptions().getTimeOutInMs()
+ AndroidTask<UninstallTask> uninstallTask = androidTasks.create(
+ tasks,
+ new UninstallTask.ConfigAction(variantScope));
- variantData.uninstallTask = uninstallTask
tasks.named(UNINSTALL_ALL) {
- it.dependsOn uninstallTask
+ it.dependsOn uninstallTask.name
}
}
@@ -2742,12 +2081,11 @@
}
public Task createAssembleTask(
+ TaskFactory tasks,
@NonNull BaseVariantData<? extends BaseVariantOutputData> variantData) {
Task assembleTask = project.tasks.
create("assemble${variantData.variantConfiguration.fullName.capitalize()}")
- assembleTask.description = "Assembles the ${variantData.description}."
- assembleTask.group = BUILD_GROUP
- return assembleTask
+ return assembleTask;
}
public Copy getJacocoAgentTask() {
@@ -2805,181 +2143,24 @@
*/
@Nullable
public File maybeCreateProguardTasks(
- final @NonNull BaseVariantData<? extends BaseVariantOutputData> variantData,
- final @Nullable BaseVariantData<? extends BaseVariantOutputData> testedVariantData,
- final @NonNull PostCompilationData pcData) {
-
- if (!variantData.getVariantConfiguration().isMinifyEnabled()) {
+ @NonNull TaskFactory tasks,
+ @NonNull VariantScope scope,
+ @NonNull final PostCompilationData pcData) {
+ if (!scope.variantData.getVariantConfiguration().isMinifyEnabled()) {
return null;
}
- final VariantConfiguration variantConfig = variantData.variantConfiguration
-
- // use single output for now.
- final BaseVariantOutputData variantOutputData = variantData.outputs.get(0)
-
- def proguardTask = project.tasks.create(
- "proguard${variantData.variantConfiguration.fullName.capitalize()}",
- AndroidProGuardTask)
-
- if (testedVariantData != null) {
- proguardTask.dependsOn testedVariantData.obfuscationTask
- }
-
- variantData.obfuscationTask = proguardTask
- variantData.mappingFileProviderTask = proguardTask
-
- // --- Output File ---
-
- final File outFile = variantData instanceof LibraryVariantData ?
- project.file(
- "${project.buildDir}/${FD_INTERMEDIATES}/$DIR_BUNDLES/${variantData.variantConfiguration.dirName}/classes.jar") :
- project.file(
- "${project.buildDir}/${FD_INTERMEDIATES}/classes-proguard/${variantData.variantConfiguration.dirName}/classes.jar")
- variantData.obfuscatedClassesJar = outFile
-
- // --- Proguard Config ---
-
- if (testedVariantData != null) {
- // Don't remove any code in tested app.
- proguardTask.dontshrink()
- proguardTask.dontoptimize()
-
- // We can't call dontobfuscate, since that would make ProGuard ignore the mapping file.
- proguardTask.keep("class * {*;}")
- proguardTask.keep("interface * {*;}")
- proguardTask.keep("enum * {*;}")
-
- // Input the mapping from the tested app so that we can deal with obfuscated code.
- proguardTask.applymapping(testedVariantData.mappingFile)
-
- // All -dontwarn rules for test dependencies should go in here:
- proguardTask.configuration(
- testedVariantData.variantConfiguration.testProguardFiles)
- } else {
- if (variantConfig.isTestCoverageEnabled()) {
- // when collecting coverage, don't remove the JaCoCo runtime
- proguardTask.keep("class com.vladium.** {*;}")
- proguardTask.keep("class org.jacoco.** {*;}")
- proguardTask.keep("interface org.jacoco.** {*;}")
- proguardTask.dontwarn("org.jacoco.**")
- }
-
- proguardTask.configuration {
- List<File> proguardFiles = variantConfig.getProguardFiles(true /*includeLibs*/,
- [extension.getDefaultProguardFile(DEFAULT_PROGUARD_CONFIG_FILE)])
-
- proguardFiles + [variantOutputData.processResourcesTask.proguardOutputFile]
- }
- }
-
- // --- InJars / LibraryJars ---
-
- if (variantData instanceof LibraryVariantData) {
- String packageName = variantConfig.getPackageFromManifest()
- if (packageName == null) {
- throw new BuildException("Failed to read manifest", null)
- }
- packageName = packageName.replace('.', '/');
-
- // injar: the compilation output
- // exclude R files and such from output
- String exclude = '!' + packageName + "/R.class"
- exclude += (', !' + packageName + "/R\$*.class")
- if (!((LibraryExtension) getExtension()).packageBuildConfig) {
- exclude += (', !' + packageName + "/Manifest.class")
- exclude += (', !' + packageName + "/Manifest\$*.class")
- exclude += (', !' + packageName + "/BuildConfig.class")
- }
- proguardTask.injars(pcData.inputDir, filter: exclude)
-
- // include R files and such for compilation
- String include = exclude.replace('!', '')
- proguardTask.libraryjars(pcData.inputDir, filter: include)
-
- // injar: the local dependencies
- Closure inJars = {
- DependencyManager.getPackagedLocalJarFileList(variantData.variantDependency)
- }
-
- proguardTask.injars(inJars, filter: '!META-INF/MANIFEST.MF')
-
- // libjar: the library dependencies. In this case we take all the compile-scope
- // dependencies
- Closure libJars = {
- // get all the compiled jar.
- Set<File> compiledJars = androidBuilder.getCompileClasspath(variantConfig)
- // and remove local jar that are also packaged
- List<File> localJars =
- DependencyManager.getPackagedLocalJarFileList(variantData.variantDependency)
-
- compiledJars.findAll({ !localJars.contains(it) })
- }
-
- proguardTask.libraryjars(libJars, filter: '!META-INF/MANIFEST.MF')
-
- // ensure local jars keep their package names
- proguardTask.keeppackagenames()
- } else {
- // injar: the compilation output
- proguardTask.injars(pcData.inputDir)
-
- // injar: the packaged dependencies
- proguardTask.injars(pcData.inputLibraries, filter: '!META-INF/MANIFEST.MF')
-
- // the provided-only jars as libraries.
- Closure libJars = {
- variantData.variantConfiguration.providedOnlyJars
- }
-
- proguardTask.libraryjars(libJars)
- }
-
- // libraryJars: the runtime jars. Do this in doFirst since the boot classpath isn't
- // available until the SDK is loaded in the prebuild task
- proguardTask.doFirst {
- for (String runtimeJar : androidBuilder.getBootClasspathAsStrings()) {
- proguardTask.libraryjars(runtimeJar)
- }
- }
-
- if (testedVariantData != null) {
- // input the tested app as library
- proguardTask.libraryjars(testedVariantData.javaCompileTask.destinationDir)
- // including its dependencies
- Closure testedPackagedJars = {
- androidBuilder.getPackagedJars(testedVariantData.variantConfiguration)
- }
-
- proguardTask.libraryjars(testedPackagedJars, filter: '!META-INF/MANIFEST.MF')
- }
-
- // --- Out files ---
-
- proguardTask.outjars(outFile)
-
- final File proguardOut = project.file(
- "${project.buildDir}/${FD_OUTPUTS}/mapping/${variantData.variantConfiguration.dirName}")
-
- proguardTask.dump(new File(proguardOut, "dump.txt"))
- proguardTask.printseeds(new File(proguardOut, "seeds.txt"))
- proguardTask.printusage(new File(proguardOut, "usage.txt"))
- proguardTask.printmapping(new File(proguardOut, "mapping.txt"))
-
- // proguard doesn't verify that the seed/mapping/usage folders exist and will fail
- // if they don't so create them.
- proguardTask.doFirst {
- proguardOut.mkdirs()
- }
+ AndroidTask<AndroidProGuardTask> proguardTask =
+ androidTasks.create(tasks, new AndroidProGuardTask.ConfigAction(scope, pcData));
+ scope.obfuscationTask = proguardTask
// update dependency.
- optionalDependsOn(proguardTask, pcData.classGeneratingTask)
- optionalDependsOn(proguardTask, pcData.libraryGeneratingTask)
- pcData.libraryGeneratingTask = [proguardTask]
- pcData.classGeneratingTask = [proguardTask]
+ proguardTask.optionalDependsOn(tasks, pcData.classGeneratingTask, pcData.libraryGeneratingTask)
+ pcData.libraryGeneratingTask = [proguardTask.name]
+ pcData.classGeneratingTask = [proguardTask.name]
- // Update the inputs
- return outFile;
+ // Return output file.
+ return scope.getProguardOutputFile();
}
public void createReportTasks(
@@ -2996,25 +2177,35 @@
}
public void createAnchorTasks(
- @NonNull BaseVariantData<? extends BaseVariantOutputData> variantData) {
- createPreBuildTasks(variantData)
+ @NonNull TaskFactory tasks,
+ @NonNull VariantScope scope) {
+ createPreBuildTasks(tasks, scope)
// also create sourceGenTask
- variantData.sourceGenTask = project.tasks.create(
- "generate${variantData.variantConfiguration.fullName.capitalize()}Sources")
+ final BaseVariantData<? extends BaseVariantOutputData> variantData = scope.variantData
+ scope.sourceGenTask = androidTasks.create(tasks,
+ "generate${variantData.variantConfiguration.fullName.capitalize()}Sources") { Task task ->
+ variantData.sourceGenTask = task
+ }
// and resGenTask
- variantData.resourceGenTask = project.tasks.create(
- "generate${variantData.variantConfiguration.fullName.capitalize()}Resources")
- variantData.assetGenTask = project.tasks.create(
- "generate${variantData.variantConfiguration.fullName.capitalize()}Assets")
+ scope.resourceGenTask = androidTasks.create(tasks,
+ "generate${variantData.variantConfiguration.fullName.capitalize()}Resources") { Task task ->
+ variantData.resourceGenTask = task
+ }
+
+ scope.assetGenTask = androidTasks.create(tasks,
+ "generate${variantData.variantConfiguration.fullName.capitalize()}Assets") { Task task ->
+ variantData.assetGenTask = task
+ }
+
// and compile task
- createCompileAnchorTask(variantData)
+ createCompileAnchorTask(tasks, scope)
}
- private void createPreBuildTasks(BaseVariantData<? extends BaseVariantOutputData> variantData) {
+ private void createPreBuildTasks(@NonNull TaskFactory tasks, @NonNull VariantScope scope) {
+ BaseVariantData<? extends BaseVariantOutputData> variantData = scope.variantData
variantData.preBuildTask = project.tasks.create(
"pre${variantData.variantConfiguration.fullName.capitalize()}Build")
- variantData.preBuildTask.dependsOn MAIN_PREBUILD
def prepareDependenciesTask = project.tasks.create(
"prepare${variantData.variantConfiguration.fullName.capitalize()}Dependencies",
@@ -3032,41 +2223,37 @@
prepareDependenciesTask.addChecker(configurationDependencies.checker)
for (LibraryDependencyImpl lib : configurationDependencies.libraries) {
- dependencyManager.addDependencyToPrepareTask(variantData, prepareDependenciesTask, lib)
+ dependencyManager.
+ addDependencyToPrepareTask(variantData, prepareDependenciesTask, lib)
}
}
- private void createCompileAnchorTask(
- BaseVariantData<? extends BaseVariantOutputData> variantData) {
- variantData.compileTask = project.tasks.create(
- "compile${variantData.variantConfiguration.fullName.capitalize()}Sources")
- variantData.compileTask.group = BUILD_GROUP
-
- variantData.assembleVariantTask.dependsOn variantData.compileTask
+ private void createCompileAnchorTask(@NonNull TaskFactory tasks, @NonNull VariantScope scope) {
+ BaseVariantData<? extends BaseVariantOutputData> variantData = scope.variantData
+ scope.compileTask = androidTasks.create(tasks,
+ "compile${variantData.variantConfiguration.fullName.capitalize()}Sources") { DefaultTask task ->
+ variantData.compileTask = task
+ variantData.compileTask.group = BUILD_GROUP
+ }
+ variantData.assembleVariantTask.dependsOn scope.compileTask.name
}
public void createCheckManifestTask(
- @NonNull BaseVariantData<? extends BaseVariantOutputData> variantData) {
+ @NonNull TaskFactory tasks,
+ @NonNull VariantScope scope) {
+ BaseVariantData<? extends BaseVariantOutputData> variantData = scope.variantData
String name = variantData.variantConfiguration.fullName
- variantData.checkManifestTask = project.tasks.create(
+ scope.checkManifestTask = androidTasks.create(tasks,
"check${name.capitalize()}Manifest",
- CheckManifest)
- variantData.checkManifestTask.dependsOn variantData.preBuildTask
-
- variantData.prepareDependenciesTask.dependsOn variantData.checkManifestTask
-
- variantData.checkManifestTask.variantName = name
- conventionMapping(variantData.checkManifestTask).map("manifest") {
- variantData.variantConfiguration.getDefaultSourceSet().manifestFile
- }
- }
-
- public static void optionalDependsOn(@NonNull AndroidTask main, TaskFactory taskFactory, Task... dependencies) {
- for (Task dependency : dependencies) {
- if (dependency != null) {
- main.dependsOn(taskFactory, dependency)
+ CheckManifest) { CheckManifest checkManifestTask ->
+ variantData.checkManifestTask = checkManifestTask
+ checkManifestTask.variantName = name
+ ConventionMappingHelper.map(variantData.checkManifestTask, "manifest") {
+ variantData.variantConfiguration.getDefaultSourceSet().manifestFile
}
}
+ scope.checkManifestTask.dependsOn(tasks, variantData.preBuildTask)
+ variantData.prepareDependenciesTask.dependsOn(scope.checkManifestTask.name)
}
public static void optionalDependsOn(@NonNull Task main, Task... dependencies) {
@@ -3104,25 +2291,4 @@
protected Logger getLogger() {
return logger
}
-
- @NonNull
- protected static List<SymbolFileProviderImpl> getTextSymbolDependencies(
- List<LibraryDependency> libraries) {
-
- List<SymbolFileProviderImpl> list = Lists.newArrayListWithCapacity(libraries.size())
-
- for (LibraryDependency lib : libraries) {
- list.add(new SymbolFileProviderImpl(lib.manifest, lib.symbolFile))
- }
-
- return list
- }
-
- protected VariantScope createVariantScope(BaseVariantData variantData) {
- return new VariantScope(
- globalScope,
- variantData,
- getNdkBuildable(variantData),
- getNdkOutputDirectories(variantData));
- }
}
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/TestApplicationTaskManager.java b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/TestApplicationTaskManager.java
index 876c00c..1111641 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/TestApplicationTaskManager.java
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/TestApplicationTaskManager.java
@@ -22,6 +22,7 @@
import com.android.annotations.Nullable;
import com.android.build.gradle.BaseExtension;
import com.android.build.gradle.TestExtension;
+import com.android.build.gradle.internal.scope.VariantScope;
import com.android.build.gradle.internal.tasks.DeviceProviderInstrumentTestTask;
import com.android.build.gradle.internal.test.TestApplicationTestData;
import com.android.build.gradle.internal.variant.BaseVariantData;
@@ -125,9 +126,10 @@
@Override
@Nullable
public File maybeCreateProguardTasks(
- @NonNull BaseVariantData<? extends BaseVariantOutputData> variantData,
- @Nullable BaseVariantData<? extends BaseVariantOutputData> testedVariantData,
- @NonNull PostCompilationData pcData) {
+ TaskFactory tasks,
+ VariantScope scope,
+ @NonNull final PostCompilationData pcData) {
+ BaseVariantData<? extends BaseVariantOutputData> variantData = scope.getVariantData();
final TestModuleProGuardTask proguardTask = project.getTasks().create(
"proguard"+ variantData.getVariantConfiguration().getFullName().toUpperCase(
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/VariantManager.java b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/VariantManager.java
index a408510..873dfcd 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/VariantManager.java
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/VariantManager.java
@@ -291,16 +291,6 @@
new Recorder.Property(SpanRecorders.VARIANT, variantData.getName()));
}
- // create the lint tasks.
- ThreadRecorder.get().record(ExecutionType.VARIANT_MANAGER_CREATE_LINT_TASKS,
- new Recorder.Block<Void>() {
- @Override
- public Void call() throws Exception {
- taskManager.createLintTasks(tasks, variantDataList);
- return null;
- }
- });
-
// Create the variant API objects after the tasks have been created!
createApiObjects();
@@ -314,7 +304,7 @@
TaskFactory tasks,
final BaseVariantData<?> variantData) {
if (variantData.getType().isForTesting()) {
- variantData.assembleVariantTask = taskManager.createAssembleTask(variantData);
+ variantData.assembleVariantTask = taskManager.createAssembleTask(tasks, variantData);
} else {
BuildTypeData buildTypeData =
buildTypes.get(variantData.getVariantConfiguration().getBuildType().getName());
@@ -323,7 +313,7 @@
// Reuse assemble task for build type if there is no product flavor.
variantData.assembleVariantTask = buildTypeData.getAssembleTask();
} else {
- variantData.assembleVariantTask = taskManager.createAssembleTask(variantData);
+ variantData.assembleVariantTask = taskManager.createAssembleTask(tasks, variantData);
// setup the task dependencies
// build type
@@ -333,7 +323,7 @@
GradleVariantConfiguration variantConfig = variantData.getVariantConfiguration();
for (GroupableProductFlavor flavor : variantConfig.getProductFlavors()) {
productFlavors.get(flavor.getName()).getAssembleTask()
- .dependsOn(variantData.assembleVariantTask);
+ .dependsOn(variantData.assembleVariantTask);
}
// assembleTask for this flavor(dimension), created on demand if needed.
@@ -447,9 +437,6 @@
* Create all variants.
*/
public void populateVariantDataList() {
- // Add a compile lint task
- taskManager.createLintCompileTask();
-
if (productFlavors.isEmpty()) {
createVariantDataForProductFlavors(
Collections.<com.android.build.gradle.api.GroupableProductFlavor>emptyList());
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/coverage/JacocoInstrumentTask.groovy b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/coverage/JacocoInstrumentTask.groovy
index 82e55b3..cc37469 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/coverage/JacocoInstrumentTask.groovy
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/coverage/JacocoInstrumentTask.groovy
@@ -16,6 +16,10 @@
package com.android.build.gradle.internal.coverage
+import com.android.build.gradle.internal.TaskManager
+import com.android.build.gradle.internal.scope.ConventionMappingHelper
+import com.android.build.gradle.internal.scope.TaskConfigAction
+import com.android.build.gradle.internal.scope.VariantScope
import org.gradle.api.DefaultTask
import org.gradle.api.file.FileCollection
import org.gradle.api.tasks.InputDirectory
@@ -23,6 +27,8 @@
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
+import static com.android.builder.model.AndroidProject.FD_INTERMEDIATES
+
/**
* Simple Jacoco instrument task that calls the Ant version.
*/
@@ -53,4 +59,40 @@
fileset(dir: getInputDir())
}
}
+
+ public static class ConfigAction implements TaskConfigAction<JacocoInstrumentTask> {
+
+ VariantScope scope;
+
+ TaskManager.PostCompilationData pcData;
+
+ ConfigAction(VariantScope scope, TaskManager.PostCompilationData pcData) {
+ this.scope = scope
+ this.pcData = pcData
+ }
+
+ @Override
+ String getName() {
+ return scope.getTaskName("instrument");
+ }
+
+ @Override
+ Class<JacocoInstrumentTask> getType() {
+ return JacocoInstrumentTask.class
+ }
+
+ @Override
+ void execute(JacocoInstrumentTask jacocoTask) {
+
+ ConventionMappingHelper.map(jacocoTask, "jacocoClasspath") {
+ scope.globalScope.project.configurations[JacocoPlugin.ANT_CONFIGURATION_NAME]
+ }
+ // can't directly use the existing inputFiles closure as we need the dir instead :\
+ ConventionMappingHelper.map(jacocoTask, "inputDir", pcData.inputDir)
+ ConventionMappingHelper.map(jacocoTask, "outputDir") {
+ new File("${scope.globalScope.buildDir}/${FD_INTERMEDIATES}/coverage-instrumented-classes/${scope.variantConfiguration.dirName}")
+ }
+ scope.variantData.jacocoInstrumentTask = jacocoTask
+ }
+ }
}
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/model/ModelBuilder.java b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/model/ModelBuilder.java
index 12b84d7..838ad3e 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/model/ModelBuilder.java
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/model/ModelBuilder.java
@@ -29,6 +29,7 @@
import com.android.build.gradle.internal.VariantManager;
import com.android.build.gradle.internal.core.GradleVariantConfiguration;
import com.android.build.gradle.internal.dsl.GroupableProductFlavor;
+import com.android.build.gradle.internal.scope.VariantScope;
import com.android.build.gradle.internal.variant.ApkVariantOutputData;
import com.android.build.gradle.internal.variant.BaseVariantData;
import com.android.build.gradle.internal.variant.BaseVariantOutputData;
@@ -279,7 +280,9 @@
Sets.newHashSet(variantData.prepareDependenciesTask.getName(),
taskManager.createMockableJar.getName()),
extraGeneratedSourceFolders != null ? extraGeneratedSourceFolders : Collections.<File>emptyList(),
- variantData.javaCompileTask.getDestinationDir(),
+ (variantData.javaCompileTask != null) ?
+ variantData.javaCompileTask.getDestinationDir() :
+ variantData.getScope().getJavaOutputDir(),
variantData.processJavaResourcesTask.getDestinationDir(),
dependencies,
sourceProviders.variantSourceProvider,
@@ -331,10 +334,11 @@
outputs.add(new AndroidArtifactOutputImpl(
outputFiles.build(),
variantOutputData.assembleTask.getName(),
- variantOutputData.manifestProcessorTask.getManifestOutputFile(),
+ variantOutputData.getScope().getManifestOutputFile(),
intVersionCode));
}
+ VariantScope scope = variantData.getScope();
return new AndroidArtifactImpl(
name,
outputs,
@@ -342,12 +346,14 @@
variantConfiguration.isSigningReady() || variantData.outputsAreSigned,
signingConfigName,
variantConfiguration.getApplicationId(),
- variantData.sourceGenTask.getName(),
- variantData.compileTask.getName(),
+ scope.getSourceGenTask().getName(),
+ scope.getCompileTask().getName(),
getGeneratedSourceFolders(variantData),
getGeneratedResourceFolders(variantData),
- variantData.javaCompileTask.getDestinationDir(),
- variantData.processJavaResourcesTask.getDestinationDir(),
+ (variantData.javaCompileTask != null) ?
+ variantData.javaCompileTask.getDestinationDir() :
+ scope.getJavaOutputDir(),
+ scope.getJavaResourcesDestinationDir(),
DependenciesImpl.cloneDependencies(variantData, androidBuilder),
sourceProviders.variantSourceProvider,
sourceProviders.multiFlavorSourceProvider,
@@ -404,15 +410,16 @@
folders = Lists.newArrayListWithExpectedSize(5);
}
- // The R class is only generated by the first output.
- BaseVariantOutputData variantOutputData = variantData.getOutputs().get(0);
- folders.add(variantOutputData.processResourcesTask.getSourceOutputDir());
+ VariantScope scope = variantData.getScope();
- folders.add(variantData.aidlCompileTask.getSourceOutputDir());
- folders.add(variantData.generateBuildConfigTask.getSourceOutputDir());
+ // The R class is only generated by the first output.
+ folders.add(scope.getRClassSourceOutputDir());
+
+ folders.add(scope.getAidlSourceOutputDir());
+ folders.add(scope.getBuildConfigSourceOutputDir());
Boolean ndkMode = variantData.getVariantConfiguration().getMergedFlavor().getRenderscriptNdkModeEnabled();
if (ndkMode == null || !ndkMode) {
- folders.add(variantData.renderscriptCompileTask.getSourceOutputDir());
+ folders.add(scope.getRenderscriptSourceOutputDir());
}
return folders;
@@ -436,8 +443,10 @@
result = Lists.newArrayListWithCapacity(2);
}
- result.add(variantData.renderscriptCompileTask.getResOutputDir());
- result.add(variantData.generateResValuesTask.getResOutputDir());
+ VariantScope scope = variantData.getScope();
+
+ result.add(scope.getRenderscriptResOutputDir());
+ result.add(scope.getGeneratedResOutputDir());
return result;
}
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/scope/AndroidTask.java b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/scope/AndroidTask.java
index eed096a..008de57 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/scope/AndroidTask.java
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/scope/AndroidTask.java
@@ -88,7 +88,7 @@
* @param taskFactory TaskFactory used to configure the task for dependencies.
* @param other The task that this depends on.
*/
- public void dependsOn(final TaskFactory taskFactory, final AndroidTask<? extends Task> other) {
+ public void dependsOn(final TaskFactory taskFactory, final AndroidTask<?> other) {
taskFactory.named(name, new Action<Task>() {
@Override
public void execute(Task task) {
@@ -100,21 +100,55 @@
}
/**
- * Add dependency on another object.
+ * Add dependency on objects.
* This method adds dependencies on any objects accepted by {@link Task#dependsOn} and is
* needed for compatibility until all tasks are trasitioned to AndroidTask.
* @param taskFactory TaskFactory used to configure the task for dependencies.
- * @param other Objects accepted by {@link Task#dependsOn}.
+ * @param dependencies Objects accepted by {@link Task#dependsOn}.
*/
- public void dependsOn(final TaskFactory taskFactory, final Object... other) {
+ public void dependsOn(final TaskFactory taskFactory, final Object... dependencies) {
taskFactory.named(name, new Action<Task>() {
@Override
public void execute(Task task) {
- task.dependsOn(other);
+ for (Object dependency : dependencies) {
+ if (dependency instanceof AndroidTask) {
+ task.dependsOn(((AndroidTask) dependency).getName());
+ } else {
+ task.dependsOn(dependency);
+ }
+ }
}
});
}
+ /**
+ * Add dependency on other objects if the object is not null.
+ * This method adds dependencies on any objects accepted by {@link Task#dependsOn} and is
+ * needed for compatibility until all tasks are trasitioned to AndroidTask.
+ * @param taskFactory TaskFactory used to configure the task for dependencies.
+ * @param dependencies Objects accepted by {@link Task#dependsOn}.
+ */
+ public void optionalDependsOn(final TaskFactory taskFactory, final Object... dependencies) {
+ for (Object dependency : dependencies) {
+ if (dependency != null) {
+ if (dependency instanceof AndroidTask) {
+ dependsOn(taskFactory, ((AndroidTask) dependency).getName());
+ } else {
+ dependsOn(taskFactory, dependency);
+ }
+ }
+ }
+ }
+
+
+ public void optionalDependsOn(final TaskFactory taskFactory, @NonNull List<?> dependencies) {
+ for (Object dependency : dependencies) {
+ if (dependency != null) {
+ dependsOn(taskFactory, dependency);
+ }
+ }
+ }
+
private void addDependent(AndroidTask<? extends Task> tAndroidTask) {
downstreamTasks.add(tAndroidTask);
}
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/scope/AndroidTaskRegistry.java b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/scope/AndroidTaskRegistry.java
index 44c6fec..c20330d 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/scope/AndroidTaskRegistry.java
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/scope/AndroidTaskRegistry.java
@@ -19,11 +19,15 @@
import com.android.build.gradle.internal.TaskFactory;
import org.gradle.api.Action;
+import org.gradle.api.DefaultTask;
import org.gradle.api.Task;
+import org.gradle.api.internal.ClosureBackedAction;
import java.util.HashMap;
import java.util.Map;
+import groovy.lang.Closure;
+
/**
* Registry for creating and storing AndroidTask.
*/
@@ -44,6 +48,31 @@
return newTask;
}
+ public synchronized AndroidTask<Task> create(
+ TaskFactory taskFactory,
+ String taskName,
+ Closure configAction) {
+
+ taskFactory.create(taskName, DefaultTask.class, new ClosureBackedAction<Task>(configAction));
+ final AndroidTask<Task> newTask = new AndroidTask<Task>(taskName, Task.class);
+ tasks.put(taskName, newTask);
+
+ return newTask;
+ }
+
+ public synchronized <T extends Task> AndroidTask<T> create(
+ TaskFactory taskFactory,
+ String taskName,
+ Class<T> taskClass,
+ Closure configAction) {
+
+ taskFactory.create(taskName, taskClass, new ClosureBackedAction<T>(configAction));
+ final AndroidTask<T> newTask = new AndroidTask<T>(taskName, taskClass);
+ tasks.put(taskName, newTask);
+
+ return newTask;
+ }
+
public <T extends Task> AndroidTask<T> create(
TaskFactory taskFactory,
TaskConfigAction<T> configAction) {
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/scope/GlobalScope.java b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/scope/GlobalScope.java
index b1d7137..d0b001a 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/scope/GlobalScope.java
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/scope/GlobalScope.java
@@ -16,14 +16,19 @@
package com.android.build.gradle.internal.scope;
+import static com.android.builder.model.AndroidProject.FD_GENERATED;
+import static com.android.builder.model.AndroidProject.FD_INTERMEDIATES;
import static com.android.builder.model.AndroidProject.FD_OUTPUTS;
import static com.android.builder.model.AndroidProject.PROPERTY_APK_LOCATION;
import com.android.annotations.NonNull;
import com.android.build.gradle.BaseExtension;
+import com.android.build.gradle.internal.SdkHandler;
import com.android.builder.core.AndroidBuilder;
+import com.android.builder.model.AndroidProject;
import org.gradle.api.Project;
+import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry;
import java.io.File;
@@ -39,16 +44,31 @@
private String projectBaseName;
@NonNull
private BaseExtension extension;
+ @NonNull
+ private SdkHandler sdkHandler;
+ @NonNull
+ private ToolingModelBuilderRegistry toolingRegistry;
+
+ @NonNull
+ private final File intermediatesDir;
+ @NonNull
+ private final File generatedDir;
public GlobalScope(
@NonNull Project project,
@NonNull AndroidBuilder androidBuilder,
@NonNull String projectBaseName,
- @NonNull BaseExtension extension) {
+ @NonNull BaseExtension extension,
+ @NonNull SdkHandler sdkHandler,
+ @NonNull ToolingModelBuilderRegistry toolingRegistry) {
this.project = project;
this.androidBuilder = androidBuilder;
this.projectBaseName = projectBaseName;
this.extension = extension;
+ this.sdkHandler = sdkHandler;
+ this.toolingRegistry = toolingRegistry;
+ intermediatesDir = new File(getBuildDir(), FD_INTERMEDIATES);
+ generatedDir = new File(getBuildDir(), FD_GENERATED);
}
@NonNull
@@ -72,11 +92,31 @@
}
@NonNull
+ public SdkHandler getSdkHandler() {
+ return sdkHandler;
+ }
+
+ @NonNull
+ public ToolingModelBuilderRegistry getToolingRegistry() {
+ return toolingRegistry;
+ }
+
+ @NonNull
public File getBuildDir() {
return project.getBuildDir();
}
@NonNull
+ public File getIntermediatesDir() {
+ return intermediatesDir;
+ }
+
+ @NonNull
+ public File getGeneratedDir() {
+ return generatedDir;
+ }
+
+ @NonNull
public String getDefaultApkLocation() {
return getBuildDir() + "/" + FD_OUTPUTS + "/apk";
}
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/scope/VariantOutputScope.java b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/scope/VariantOutputScope.java
index f9a7390..8534920 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/scope/VariantOutputScope.java
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/scope/VariantOutputScope.java
@@ -16,15 +16,28 @@
package com.android.build.gradle.internal.scope;
+import static com.android.builder.model.AndroidProject.FD_INTERMEDIATES;
+
import com.android.annotations.NonNull;
+import com.android.annotations.Nullable;
import com.android.build.gradle.internal.TaskFactory;
+import com.android.build.gradle.internal.TaskManager;
import com.android.build.gradle.internal.variant.ApkVariantData;
import com.android.build.gradle.internal.variant.BaseVariantOutputData;
+import com.android.build.gradle.tasks.CompatibleScreensManifest;
+import com.android.build.gradle.tasks.ManifestProcessorTask;
import com.android.build.gradle.tasks.PackageApplication;
+import com.android.build.gradle.tasks.PackageSplitAbi;
+import com.android.build.gradle.tasks.PackageSplitRes;
+import com.android.build.gradle.tasks.ProcessAndroidResources;
import com.android.build.gradle.tasks.ZipAlign;
+import com.android.builder.model.AndroidProject;
import com.android.utils.StringHelper;
+import com.android.xml.AndroidManifest;
import com.google.common.collect.ImmutableMap;
+import org.gradle.api.Task;
+
import java.io.File;
import java.util.Map;
@@ -38,6 +51,13 @@
@NonNull
private BaseVariantOutputData variantOutputData;
+ // Tasks
+ private AndroidTask<CompatibleScreensManifest> compatibleScreensManifestTask;
+
+ private AndroidTask<? extends ManifestProcessorTask> manifestProcessorTask;
+
+ private AndroidTask<ProcessAndroidResources> processResourcesTask;
+
public VariantOutputScope(
@NonNull VariantScope variantScope,
@NonNull BaseVariantOutputData variantOutputData) {
@@ -61,6 +81,16 @@
}
@NonNull
+ public String getTaskName(@NonNull String prefix) {
+ return getTaskName(prefix, "");
+ }
+
+ @NonNull
+ public String getTaskName(@NonNull String prefix, @NonNull String suffix) {
+ return prefix + StringHelper.capitalize(getVariantOutputData().getFullName()) + suffix;
+ }
+
+ @NonNull
public File getPackageApk() {
ApkVariantData apkVariantData = (ApkVariantData) variantScope.getVariantData();
@@ -79,4 +109,74 @@
return getGlobalScope().getProject().file(getGlobalScope().getDefaultApkLocation() + "/" + apkName);
}
}
+
+ @NonNull
+ public File getCompressedResourceFile() {
+ return new File(getGlobalScope().getIntermediatesDir(), "/res/" +
+ "resources-" + variantOutputData.getBaseName() + "-stripped.ap_");
+ }
+
+ @NonNull
+ public File getCompatibleScreensManifestFile() {
+ return new File(getGlobalScope().getIntermediatesDir(),
+ "/manifests/density/" + variantOutputData.getDirName() + "/AndroidManifest.xml");
+
+ }
+
+ @NonNull
+ public File getManifestOutputFile() {
+ switch(variantScope.getVariantConfiguration().getType()) {
+ case DEFAULT:
+ return new File(getGlobalScope().getIntermediatesDir(),
+ "/manifests/full/" + variantOutputData.getDirName()
+ + "/AndroidManifest.xml");
+ case LIBRARY:
+ return new File(getGlobalScope().getIntermediatesDir(),
+ TaskManager.DIR_BUNDLES + "/"
+ + getVariantScope().getVariantConfiguration().getDirName()
+ + "/AndroidManifest.xml");
+ case ANDROID_TEST:
+ return new File(getGlobalScope().getIntermediatesDir(),
+ "manifest/" + variantScope.getVariantConfiguration().getDirName()
+ + "/AndroidManifest.xml");
+ default:
+ throw new RuntimeException(
+ "getManifestOutputFile called for an unexpected variant.");
+ }
+ }
+
+ @NonNull
+ public File getProcessResourcePackageOutputFile() {
+ return new File(getGlobalScope().getIntermediatesDir(),
+ "res/resources-" + variantOutputData.getBaseName() + ".ap_");
+ }
+
+ // Tasks
+ @Nullable
+ public AndroidTask<CompatibleScreensManifest> getCompatibleScreensManifestTask() {
+ return compatibleScreensManifestTask;
+ }
+
+ public void setCompatibleScreensManifestTask(
+ @Nullable AndroidTask<CompatibleScreensManifest> compatibleScreensManifestTask) {
+ this.compatibleScreensManifestTask = compatibleScreensManifestTask;
+ }
+
+ public AndroidTask<? extends ManifestProcessorTask> getManifestProcessorTask() {
+ return manifestProcessorTask;
+ }
+
+ public void setManifestProcessorTask(
+ AndroidTask<? extends ManifestProcessorTask> manifestProcessorTask) {
+ this.manifestProcessorTask = manifestProcessorTask;
+ }
+
+ public AndroidTask<ProcessAndroidResources> getProcessResourcesTask() {
+ return processResourcesTask;
+ }
+
+ public void setProcessResourcesTask(
+ AndroidTask<ProcessAndroidResources> processResourcesTask) {
+ this.processResourcesTask = processResourcesTask;
+ }
}
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/scope/VariantScope.java b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/scope/VariantScope.java
index afabc3e..05d00df 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/scope/VariantScope.java
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/scope/VariantScope.java
@@ -16,19 +16,42 @@
package com.android.build.gradle.internal.scope;
+import static com.android.builder.model.AndroidProject.FD_GENERATED;
+
import com.android.annotations.NonNull;
-import com.android.build.gradle.BaseExtension;
+import com.android.annotations.Nullable;
+import com.android.build.gradle.internal.TaskManager;
import com.android.build.gradle.internal.core.GradleVariantConfiguration;
+import com.android.build.gradle.internal.coverage.JacocoInstrumentTask;
+import com.android.build.gradle.internal.tasks.CheckManifest;
+import com.android.build.gradle.internal.tasks.FileSupplier;
+import com.android.build.gradle.internal.tasks.PrepareDependenciesTask;
import com.android.build.gradle.internal.variant.ApkVariantData;
import com.android.build.gradle.internal.variant.BaseVariantData;
import com.android.build.gradle.internal.variant.BaseVariantOutputData;
-import com.android.build.gradle.tasks.ZipAlign;
-import com.android.builder.core.AndroidBuilder;
+import com.android.build.gradle.internal.variant.LibraryVariantData;
+import com.android.build.gradle.internal.variant.TestVariantData;
+import com.android.build.gradle.tasks.AidlCompile;
+import com.android.build.gradle.tasks.BinaryFileProviderTask;
+import com.android.build.gradle.tasks.Dex;
+import com.android.build.gradle.tasks.GenerateBuildConfig;
+import com.android.build.gradle.tasks.GenerateResValues;
+import com.android.build.gradle.tasks.MergeAssets;
+import com.android.build.gradle.tasks.MergeResources;
+import com.android.build.gradle.tasks.NdkCompile;
+import com.android.build.gradle.tasks.PreprocessResourcesTask;
+import com.android.build.gradle.tasks.ProcessAndroidResources;
+import com.android.build.gradle.tasks.RenderscriptCompile;
import com.android.builder.core.VariantConfiguration;
-import com.google.common.collect.ImmutableMap;
+import com.android.builder.core.VariantType;
+import com.android.utils.StringHelper;
+import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
-import org.gradle.api.Project;
+import org.gradle.api.Task;
+import org.gradle.api.file.FileCollection;
+import org.gradle.api.tasks.Copy;
+import org.gradle.api.tasks.compile.AbstractCompile;
import java.io.File;
import java.util.Collection;
@@ -44,20 +67,67 @@
private GlobalScope globalScope;
@NonNull
private BaseVariantData<? extends BaseVariantOutputData> variantData;
- @NonNull
+
+ @Nullable
private Collection<Object> ndkBuildable;
- @NonNull
+ @Nullable
private Collection<File> ndkOutputDirectories;
+ @Nullable
+ private File mergeResourceOutputDir;
+
+ // Tasks
+ private AndroidTask<Task> preBuildTask;
+ private AndroidTask<PrepareDependenciesTask> prepareDependenciesTask;
+ private AndroidTask<ProcessAndroidResources> generateRClassTask;
+
+ private AndroidTask<Task> sourceGenTask;
+ private AndroidTask<Task> resourceGenTask;
+ private AndroidTask<Task> assetGenTask;
+ private AndroidTask<CheckManifest> checkManifestTask;
+
+ private AndroidTask<RenderscriptCompile> renderscriptCompileTask;
+ private AndroidTask<AidlCompile> aidlCompileTask;
+ @Nullable
+ private AndroidTask<MergeResources> mergeResourcesTask;
+ @Nullable
+ private AndroidTask<MergeAssets> mergeAssetsTask;
+ private AndroidTask<GenerateBuildConfig> generateBuildConfigTask;
+ private AndroidTask<GenerateResValues> generateResValuesTask;
+
+ /**
+ * Anchor task for post-processing the merged resources to backport some features to earlier
+ * API versions, e.g. generate PNGs from vector drawables (vector drawables were added in 21).
+ */
+ @Nullable
+ private AndroidTask<Dex> dexTask;
+ @Nullable
+ private AndroidTask jacocoIntrumentTask;
+ @Nullable
+ private AndroidTask<PreprocessResourcesTask> preprocessResourcesTask;
+
+ private AndroidTask<Copy> processJavaResourcesTask;
+ private AndroidTask<NdkCompile> ndkCompileTask;
+
+ // can be JavaCompile or JackTask depending on user's settings.
+ @Nullable
+ private AndroidTask<? extends AbstractCompile> javaCompileTask;
+ // empty anchor compile task to set all compilations tasks as dependents.
+ private AndroidTask<Task> compileTask;
+ private AndroidTask<JacocoInstrumentTask> jacocoInstrumentTask;
+
+ private FileSupplier mappingFileProviderTask;
+ private AndroidTask<BinaryFileProviderTask> binayFileProviderTask;
+
+ // TODO : why is Jack not registered as the obfuscationTask ???
+ private AndroidTask<? extends Task> obfuscationTask;
+
+
public VariantScope(
@NonNull GlobalScope globalScope,
- @NonNull BaseVariantData<? extends BaseVariantOutputData> variantData,
- @NonNull Collection<Object> ndkBuildable,
- @NonNull Collection<File> ndkOutputDirectories) {
+ @NonNull BaseVariantData<? extends BaseVariantOutputData> variantData) {
this.globalScope = globalScope;
this.variantData = variantData;
- this.ndkBuildable = ndkBuildable;
- this.ndkOutputDirectories = ndkOutputDirectories;
}
@NonNull
@@ -76,23 +146,43 @@
}
@NonNull
+ public String getTaskName(@NonNull String prefix) {
+ return getTaskName(prefix, "");
+ }
+
+ @NonNull
+ public String getTaskName(@NonNull String prefix, @NonNull String suffix) {
+ return prefix + StringHelper.capitalize(getVariantConfiguration().getFullName()) + suffix;
+ }
+
+ @Nullable
public Collection<Object> getNdkBuildable() {
return ndkBuildable;
}
- @NonNull
+ public void setNdkBuildable(@NonNull Collection<Object> ndkBuildable) {
+ this.ndkBuildable = ndkBuildable;
+ }
+
+ @Nullable
public Collection<File> getNdkOutputDirectories() {
return ndkOutputDirectories;
}
+ public void setNdkOutputDirectories(@NonNull Collection<File> ndkOutputDirectories) {
+ this.ndkOutputDirectories = ndkOutputDirectories;
+ }
+
@NonNull
public Set<File> getJniFolders() {
+ assert getNdkOutputDirectories() != null;
+
VariantConfiguration config = getVariantConfiguration();
ApkVariantData apkVariantData = (ApkVariantData) variantData;
// for now only the project's compilation output.
Set<File> set = Sets.newHashSet();
set.addAll(getNdkOutputDirectories());
- set.add(apkVariantData.renderscriptCompileTask.getLibOutputDir());
+ set.add(getRenderscriptLibOutputDir());
set.addAll(config.getLibraryJniFolders());
set.addAll(config.getJniLibsList());
@@ -105,4 +195,338 @@
}
return set;
}
+
+ @Nullable
+ public BaseVariantData getTestedVariantData() {
+ return variantData instanceof TestVariantData ?
+ (BaseVariantData) ((TestVariantData) variantData).getTestedVariantData() :
+ null;
+ }
+
+
+ // Precomputed file paths.
+
+ @NonNull
+ public File getDexOutputFolder() {
+ return new File(globalScope.getIntermediatesDir(), "/dex/" + getVariantConfiguration().getDirName());
+ }
+
+ @NonNull
+ public FileCollection getJavaClasspath() {
+ return getGlobalScope().getProject().files(
+ getGlobalScope().getAndroidBuilder().getCompileClasspath(
+ getVariantData().getVariantConfiguration()));
+ }
+
+ @NonNull
+ public File getJavaOutputDir() {
+ return new File(globalScope.getIntermediatesDir(), "/classes/" +
+ variantData.getVariantConfiguration().getDirName());
+ }
+
+ @NonNull
+ public File getJavaDependencyCache() {
+ return new File(globalScope.getIntermediatesDir(), "/dependency-cache/" +
+ variantData.getVariantConfiguration().getDirName());
+ }
+
+ @NonNull
+ public File getPreDexOutputDir() {
+ return new File(globalScope.getIntermediatesDir(), "/pre-dexed/" +
+ getVariantConfiguration().getDirName());
+ }
+
+ @NonNull
+ public File getProguardOutputFile() {
+ return (variantData instanceof LibraryVariantData) ?
+ new File(globalScope.getIntermediatesDir(),
+ TaskManager.DIR_BUNDLES + "/" + getVariantConfiguration().getDirName()
+ + "/classes.jar") :
+ new File(globalScope.getIntermediatesDir(),
+ "/classes-proguard/" + getVariantConfiguration().getDirName()
+ + "/classes.jar");
+ }
+
+ @NonNull
+ public File getProguardComponentsJarFile() {
+ return new File(globalScope.getIntermediatesDir(), "multi-dex/" + getVariantConfiguration().getDirName()
+ + "/componentClasses.jar");
+ }
+
+ @NonNull
+ public File getJarMergingOutputFile() {
+ return new File(globalScope.getIntermediatesDir(), "multi-dex/" + getVariantConfiguration().getDirName()
+ + "/allclasses.jar");
+ }
+
+ @NonNull
+ public File getManifestKeepListFile() {
+ return new File(globalScope.getIntermediatesDir(), "multi-dex/" + getVariantConfiguration().getDirName()
+ + "/manifest_keep.txt");
+ }
+
+ @NonNull
+ public File getMainDexListFile() {
+ return new File(globalScope.getIntermediatesDir(), "multi-dex/" + getVariantConfiguration().getDirName()
+ + "/maindexlist.txt");
+ }
+
+ @NonNull
+ public File getRenderscriptSourceOutputDir() {
+ return new File(globalScope.getGeneratedDir(),
+ "source/rs/" + variantData.getVariantConfiguration().getDirName());
+ }
+
+ @NonNull
+ public File getRenderscriptLibOutputDir() {
+ return new File(globalScope.getGeneratedDir(),
+ "rs/" + variantData.getVariantConfiguration().getDirName() + "/lib");
+ }
+
+ @NonNull
+ public File getSymbolLocation() {
+ return new File(globalScope.getIntermediatesDir() + "/symbols/" +
+ variantData.getVariantConfiguration().getDirName());
+ }
+
+ @NonNull
+ public File getDefaultMergeResourcesOutputDir() {
+ return new File(globalScope.getIntermediatesDir(),
+ "/res/merged/" + getVariantConfiguration().getDirName());
+ }
+
+ @NonNull
+ public File getMergeResourcesOutputDir() {
+ if (mergeResourceOutputDir == null) {
+ return getDefaultMergeResourcesOutputDir();
+ }
+ return mergeResourceOutputDir;
+ }
+
+ public void setMergeResourceOutputDir(@Nullable File mergeResourceOutputDir) {
+ this.mergeResourceOutputDir = mergeResourceOutputDir;
+ }
+
+ @NonNull
+ public File getMergeAssetsOutputDir() {
+ return getVariantConfiguration().getType() == VariantType.LIBRARY ?
+ new File(globalScope.getIntermediatesDir(),
+ TaskManager.DIR_BUNDLES + "/" + getVariantConfiguration().getDirName() +
+ "/assets") :
+ new File(globalScope.getIntermediatesDir(),
+ "/assets/" + getVariantConfiguration().getDirName());
+ }
+
+ @NonNull
+ public File getBuildConfigSourceOutputDir() {
+ return new File(globalScope.getBuildDir() + "/" + FD_GENERATED + "/source/buildConfig/"
+ + variantData.getVariantConfiguration().getDirName());
+ }
+
+ @NonNull
+ public File getGeneratedResOutputDir() {
+ return new File(globalScope.getGeneratedDir(),
+ "res/resValues/" + getVariantConfiguration().getDirName());
+ }
+
+ @NonNull
+ public File getRenderscriptResOutputDir() {
+ return new File(globalScope.getGeneratedDir(),
+ "res/rs/" + getVariantConfiguration().getDirName());
+ }
+
+ @NonNull
+ public File getJavaResourcesDestinationDir() {
+ return new File(globalScope.getIntermediatesDir(),
+ "javaResources/" + getVariantConfiguration().getDirName());
+ }
+
+ @NonNull
+ public File getRClassSourceOutputDir() {
+ return new File(globalScope.getGeneratedDir(),
+ "source/r/" + getVariantConfiguration().getDirName());
+ }
+
+ @NonNull
+ public File getAidlSourceOutputDir() {
+ return new File(globalScope.getGeneratedDir(),
+ "source/aidl/" + getVariantConfiguration().getDirName());
+ }
+
+ // Tasks getters/setters.
+
+ public AndroidTask<Task> getPreBuildTask() {
+ return preBuildTask;
+ }
+
+ public void setPreBuildTask(
+ AndroidTask<Task> preBuildTask) {
+ this.preBuildTask = preBuildTask;
+ }
+
+ public AndroidTask<PrepareDependenciesTask> getPrepareDependenciesTask() {
+ return prepareDependenciesTask;
+ }
+
+ public void setPrepareDependenciesTask(
+ AndroidTask<PrepareDependenciesTask> prepareDependenciesTask) {
+ this.prepareDependenciesTask = prepareDependenciesTask;
+ }
+
+ public AndroidTask<ProcessAndroidResources> getGenerateRClassTask() {
+ return generateRClassTask;
+ }
+
+ public void setGenerateRClassTask(
+ AndroidTask<ProcessAndroidResources> generateRClassTask) {
+ this.generateRClassTask = generateRClassTask;
+ }
+
+ public AndroidTask<Task> getSourceGenTask() {
+ return sourceGenTask;
+ }
+
+ public void setSourceGenTask(
+ AndroidTask<Task> sourceGenTask) {
+ this.sourceGenTask = sourceGenTask;
+ }
+
+ public AndroidTask<Task> getResourceGenTask() {
+ return resourceGenTask;
+ }
+
+ public void setResourceGenTask(
+ AndroidTask<Task> resourceGenTask) {
+ this.resourceGenTask = resourceGenTask;
+ }
+
+ public AndroidTask<Task> getAssetGenTask() {
+ return assetGenTask;
+ }
+
+ public void setAssetGenTask(
+ AndroidTask<Task> assetGenTask) {
+ this.assetGenTask = assetGenTask;
+ }
+
+ public AndroidTask<CheckManifest> getCheckManifestTask() {
+ return checkManifestTask;
+ }
+
+ public void setCheckManifestTask(
+ AndroidTask<CheckManifest> checkManifestTask) {
+ this.checkManifestTask = checkManifestTask;
+ }
+
+ public AndroidTask<RenderscriptCompile> getRenderscriptCompileTask() {
+ return renderscriptCompileTask;
+ }
+
+ public void setRenderscriptCompileTask(
+ AndroidTask<RenderscriptCompile> renderscriptCompileTask) {
+ this.renderscriptCompileTask = renderscriptCompileTask;
+ }
+
+ public AndroidTask<AidlCompile> getAidlCompileTask() {
+ return aidlCompileTask;
+ }
+
+ public void setAidlCompileTask(
+ AndroidTask<AidlCompile> aidlCompileTask) {
+ this.aidlCompileTask = aidlCompileTask;
+ }
+
+ @Nullable
+ public AndroidTask<MergeResources> getMergeResourcesTask() {
+ return mergeResourcesTask;
+ }
+
+ public void setMergeResourcesTask(
+ @Nullable AndroidTask<MergeResources> mergeResourcesTask) {
+ this.mergeResourcesTask = mergeResourcesTask;
+ }
+
+ @Nullable
+ public AndroidTask<MergeAssets> getMergeAssetsTask() {
+ return mergeAssetsTask;
+ }
+
+ public void setMergeAssetsTask(
+ @Nullable AndroidTask<MergeAssets> mergeAssetsTask) {
+ this.mergeAssetsTask = mergeAssetsTask;
+ }
+
+ public AndroidTask<GenerateBuildConfig> getGenerateBuildConfigTask() {
+ return generateBuildConfigTask;
+ }
+
+ public void setGenerateBuildConfigTask(
+ AndroidTask<GenerateBuildConfig> generateBuildConfigTask) {
+ this.generateBuildConfigTask = generateBuildConfigTask;
+ }
+
+ public AndroidTask<GenerateResValues> getGenerateResValuesTask() {
+ return generateResValuesTask;
+ }
+
+ public void setGenerateResValuesTask(
+ AndroidTask<GenerateResValues> generateResValuesTask) {
+ this.generateResValuesTask = generateResValuesTask;
+ }
+
+ @Nullable
+ public AndroidTask<Dex> getDexTask() {
+ return dexTask;
+ }
+
+ public void setDexTask(@Nullable AndroidTask<Dex> dexTask) {
+ this.dexTask = dexTask;
+ }
+
+ @Nullable
+ public AndroidTask<PreprocessResourcesTask> getPreprocessResourcesTask() {
+ return preprocessResourcesTask;
+ }
+
+ public void setPreprocessResourcesTask(
+ @Nullable AndroidTask<PreprocessResourcesTask> preprocessResourcesTask) {
+ this.preprocessResourcesTask = preprocessResourcesTask;
+ }
+
+ public AndroidTask<Copy> getProcessJavaResourcesTask() {
+ return processJavaResourcesTask;
+ }
+
+ public void setProcessJavaResourcesTask(
+ AndroidTask<Copy> processJavaResourcesTask) {
+ this.processJavaResourcesTask = processJavaResourcesTask;
+ }
+
+ @Nullable
+ public AndroidTask<? extends AbstractCompile> getJavaCompileTask() {
+ return javaCompileTask;
+ }
+
+ public void setJavaCompileTask(
+ @Nullable AndroidTask<? extends AbstractCompile> javaCompileTask) {
+ this.javaCompileTask = javaCompileTask;
+ }
+
+ public AndroidTask<Task> getCompileTask() {
+ return compileTask;
+ }
+
+ public void setCompileTask(
+ AndroidTask<Task> compileTask) {
+ this.compileTask = compileTask;
+ }
+
+ public AndroidTask<? extends Task> getObfuscationTask() {
+ return obfuscationTask;
+ }
+
+ public void setObfuscationTask(
+ AndroidTask<? extends Task> obfuscationTask) {
+ this.obfuscationTask = obfuscationTask;
+ }
}
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/tasks/GenerateApkDataTask.java b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/tasks/GenerateApkDataTask.java
index f97f04b..573b8f1 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/tasks/GenerateApkDataTask.java
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/tasks/GenerateApkDataTask.java
@@ -18,13 +18,24 @@
import static com.android.SdkConstants.DOT_ANDROID_PACKAGE;
import static com.android.SdkConstants.FD_RES_RAW;
+import static com.android.SdkConstants.FN_ANDROID_MANIFEST_XML;
import static com.android.builder.core.BuilderConstants.ANDROID_WEAR_MICRO_APK;
+import com.android.SdkConstants;
+import com.android.annotations.NonNull;
+import com.android.build.gradle.internal.scope.ConventionMappingHelper;
+import com.android.build.gradle.internal.scope.TaskConfigAction;
+import com.android.build.gradle.internal.scope.VariantScope;
+import com.android.build.gradle.internal.variant.ApkVariantData;
+import com.android.build.gradle.tasks.AidlCompile;
import com.android.builder.core.AndroidBuilder;
+import com.android.builder.core.VariantConfiguration;
import com.android.ide.common.internal.LoggedErrorException;
import com.android.ide.common.process.ProcessException;
+import com.android.utils.StringHelper;
import com.google.common.io.Files;
+import org.gradle.api.artifacts.Configuration;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.OutputDirectory;
@@ -33,6 +44,7 @@
import java.io.File;
import java.io.IOException;
+import java.util.concurrent.Callable;
/**
* Task to generate micro app data res file.
@@ -133,4 +145,84 @@
public void setManifestFile(File manifestFile) {
this.manifestFile = manifestFile;
}
+
+ public static class ConfigAction implements TaskConfigAction<GenerateApkDataTask> {
+
+ @NonNull
+ VariantScope scope;
+
+ @NonNull
+ Configuration config;
+
+ public ConfigAction(@NonNull VariantScope scope, @NonNull Configuration config) {
+ this.scope = scope;
+ this.config = config;
+ }
+
+ @Override
+ @NonNull
+ public String getName() {
+ return scope.getTaskName("handle", "MicroApk");
+ }
+
+ @Override
+ @NonNull
+ public Class<GenerateApkDataTask> getType() {
+ return GenerateApkDataTask.class;
+ }
+
+ @Override
+ public void execute(GenerateApkDataTask task) {
+ final ApkVariantData variantData = (ApkVariantData) scope.getVariantData();
+ variantData.generateApkDataTask = task;
+
+ task.setAndroidBuilder(scope.getGlobalScope().getAndroidBuilder());
+ ConventionMappingHelper.map(task, "resOutputDir", new Callable<File>() {
+ @Override
+ public File call() throws Exception {
+ return new File(
+ scope.getGlobalScope().getGeneratedDir(),
+ "/res/microapk/"
+ + variantData.getVariantConfiguration().getDirName());
+ }
+ });
+ ConventionMappingHelper.map(task, "apkFile", new Callable<File>() {
+ @Override
+ public File call() throws Exception {
+ // only care about the first one. There shouldn't be more anyway.
+ return config.getFiles().iterator().next();
+ }
+ });
+ ConventionMappingHelper.map(task, "manifestFile", new Callable<File>() {
+ @Override
+ public File call() throws Exception {
+ return new File(
+ scope.getGlobalScope().getGeneratedDir(),
+ "/manifests/microapk/"
+ + scope.getVariantData().getVariantConfiguration().getDirName()
+ + "/" + FN_ANDROID_MANIFEST_XML);
+ }
+ });
+ ConventionMappingHelper.map(task, "mainPkgName", new Callable<String>() {
+ @Override
+ public String call() throws Exception {
+ return variantData.getVariantConfiguration().getApplicationId();
+ }
+ });
+
+ ConventionMappingHelper.map(task, "minSdkVersion", new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ return variantData.getVariantConfiguration().getMinSdkVersion().getApiLevel();
+ }
+ });
+
+ ConventionMappingHelper.map(task, "targetSdkVersion", new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ return variantData.getVariantConfiguration().getTargetSdkVersion().getApiLevel();
+ }
+ });
+ }
+ }
}
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/tasks/InstallVariantTask.groovy b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/tasks/InstallVariantTask.groovy
index 1133ac6..8a2086e 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/tasks/InstallVariantTask.groovy
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/tasks/InstallVariantTask.groovy
@@ -16,20 +16,27 @@
package com.android.build.gradle.internal.tasks
import com.android.build.gradle.internal.LoggerWrapper
+import com.android.build.gradle.internal.TaskManager
+import com.android.build.gradle.internal.scope.ConventionMappingHelper
+import com.android.build.gradle.internal.scope.TaskConfigAction
+import com.android.build.gradle.internal.scope.VariantScope
+import com.android.build.gradle.internal.variant.ApkVariantData
import com.android.build.gradle.internal.variant.BaseVariantData
import com.android.build.gradle.internal.variant.BaseVariantOutputData
-import com.android.builder.testing.api.DeviceConfigProviderImpl
import com.android.builder.core.VariantConfiguration
import com.android.builder.internal.InstallUtils
+import com.android.builder.sdk.SdkInfo
+import com.android.builder.sdk.TargetInfo
import com.android.builder.testing.ConnectedDeviceProvider
+import com.android.builder.testing.api.DeviceConfigProviderImpl
import com.android.builder.testing.api.DeviceConnector
import com.android.builder.testing.api.DeviceProvider
-import com.android.ddmlib.IDevice
import com.android.ide.common.build.SplitOutputMatcher
import com.android.ide.common.process.ProcessExecutor
import com.android.utils.ILogger
import com.google.common.base.Joiner
import com.google.common.collect.ImmutableList
+import org.gradle.api.Action
import org.gradle.api.GradleException
import org.gradle.api.logging.LogLevel
import org.gradle.api.tasks.Input
@@ -37,6 +44,10 @@
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.TaskAction
+import java.util.concurrent.Callable
+
+import static com.android.sdklib.BuildToolInfo.PathId.SPLIT_SELECT
+
/**
* Task installing an app variant. It looks at connected device and install the best matching
* variant output on each device.
@@ -123,4 +134,59 @@
"${successfulInstallCount==1?'device':'devicess'}.");
}
}
+
+ public static class ConfigAction implements TaskConfigAction<InstallVariantTask> {
+
+ private final VariantScope scope;
+
+ public ConfigAction(VariantScope scope) {
+ this.scope = scope;
+ }
+
+ @Override
+ String getName() {
+ return "install${scope.getVariantConfiguration().fullName.capitalize()}";
+ }
+
+ @Override
+ Class<InstallVariantTask> getType() {
+ return InstallVariantTask.class
+ }
+
+ @Override
+ public void execute(InstallVariantTask installTask) {
+ installTask.setDescription("Installs the " + scope.getVariantData().getDescription() + ".");
+ installTask.setGroup(TaskManager.INSTALL_GROUP);
+ installTask.setProjectName(scope.getGlobalScope().getProject().getName());
+ installTask.setVariantData(scope.getVariantData());
+ installTask.setTimeOutInMs(scope.getGlobalScope().getExtension().getAdbOptions().getTimeOutInMs());
+ installTask.setInstallOptions(scope.getGlobalScope().getExtension().getAdbOptions().getInstallOptions());
+ installTask.setProcessExecutor(scope.getGlobalScope().getAndroidBuilder().getProcessExecutor());
+ ConventionMappingHelper.map(installTask, "adbExe", new Closure<File>(this, this) {
+ public File doCall(Object it) {
+ final SdkInfo info = scope.getGlobalScope().getSdkHandler().getSdkInfo();
+ return (info == null ? null : info.getAdb());
+ }
+
+ public File doCall() {
+ return doCall(null);
+ }
+
+ });
+ ConventionMappingHelper.map(installTask, "splitSelectExe", new Callable<File>() {
+ @Override
+ public File call() throws Exception {
+ final TargetInfo info = scope.getGlobalScope().getAndroidBuilder().getTargetInfo();
+ String path = info == null ? null : info.getBuildTools().getPath(SPLIT_SELECT);
+ if (path != null) {
+ File splitSelectExe = new File(path);
+ return splitSelectExe.exists() ? splitSelectExe : null;
+ } else {
+ return null;
+ }
+ }
+ });
+ ((ApkVariantData) scope.getVariantData()).installTask = installTask;
+ }
+ }
}
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/tasks/UninstallTask.java b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/tasks/UninstallTask.java
index f190d30..e83b8db 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/tasks/UninstallTask.java
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/tasks/UninstallTask.java
@@ -16,15 +16,19 @@
package com.android.build.gradle.internal.tasks;
import com.android.build.gradle.internal.LoggerWrapper;
+import com.android.build.gradle.internal.TaskManager;
+import com.android.build.gradle.internal.scope.ConventionMappingHelper;
+import com.android.build.gradle.internal.scope.TaskConfigAction;
+import com.android.build.gradle.internal.scope.VariantScope;
+import com.android.build.gradle.internal.variant.ApkVariantData;
import com.android.build.gradle.internal.variant.BaseVariantData;
-import com.android.builder.internal.InstallUtils;
import com.android.builder.sdk.SdkInfo;
import com.android.builder.testing.ConnectedDeviceProvider;
import com.android.builder.testing.api.DeviceConnector;
import com.android.builder.testing.api.DeviceException;
import com.android.builder.testing.api.DeviceProvider;
-import com.android.ddmlib.IDevice;
import com.android.utils.ILogger;
+import com.android.utils.StringHelper;
import org.gradle.api.Task;
import org.gradle.api.logging.LogLevel;
@@ -32,11 +36,11 @@
import org.gradle.api.specs.Spec;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputFile;
-import org.gradle.api.tasks.Optional;
import org.gradle.api.tasks.TaskAction;
import java.io.File;
import java.util.List;
+import java.util.concurrent.Callable;
public class UninstallTask extends BaseTask {
@@ -109,4 +113,46 @@
public void setTimeOutInMs(int timeoutInMs) {
mTimeOutInMs = timeoutInMs;
}
+
+ public static class ConfigAction implements TaskConfigAction<UninstallTask> {
+
+ private final VariantScope scope;
+
+ public ConfigAction(VariantScope scope) {
+ this.scope = scope;
+ }
+
+ @Override
+ public String getName() {
+ return "uninstall"
+ + StringHelper.capitalize(scope.getVariantConfiguration().getFullName());
+ }
+
+ @Override
+ public Class<UninstallTask> getType() {
+ return UninstallTask.class;
+ }
+
+ @Override
+ public void execute(UninstallTask uninstallTask) {
+
+ uninstallTask.setDescription(
+ "Uninstalls the " + scope.getVariantData().getDescription() + ".");
+ uninstallTask.setGroup(TaskManager.INSTALL_GROUP);
+ uninstallTask.setVariant(scope.getVariantData());
+ uninstallTask.setAndroidBuilder(scope.getGlobalScope().getAndroidBuilder());
+ uninstallTask.setTimeOutInMs(
+ scope.getGlobalScope().getExtension().getAdbOptions().getTimeOutInMs());
+
+ ConventionMappingHelper.map(uninstallTask, "adbExe", new Callable<File>() {
+ @Override
+ public File call() throws Exception {
+ final SdkInfo info = scope.getGlobalScope().getSdkHandler().getSdkInfo();
+ return (info == null ? null : info.getAdb());
+ }
+ });
+
+ ((ApkVariantData) scope.getVariantData()).uninstallTask = uninstallTask;
+ }
+ }
}
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/tasks/multidex/CreateMainDexList.groovy b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/tasks/multidex/CreateMainDexList.groovy
index 96e645d..122960c 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/tasks/multidex/CreateMainDexList.groovy
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/tasks/multidex/CreateMainDexList.groovy
@@ -18,14 +18,23 @@
package com.android.build.gradle.internal.tasks.multidex
+import com.android.build.gradle.internal.TaskManager
+import com.android.build.gradle.internal.scope.ConventionMappingHelper
+import com.android.build.gradle.internal.scope.TaskConfigAction
+import com.android.build.gradle.internal.scope.VariantScope
import com.android.build.gradle.internal.tasks.BaseTask
+import com.android.builder.model.AndroidProject
import com.google.common.base.Charsets
import com.google.common.base.Joiner
import com.google.common.io.Files
+import org.gradle.api.Task
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction
+
+import static com.android.builder.model.AndroidProject.FD_INTERMEDIATES
+
/**
* Task to create the main (non-obfuscated) list of classes to keep.
* It uses a jar containing all the classes, as well as a shrinked jar file created by proguard.
@@ -92,4 +101,40 @@
private Set<String> callDx(File allClassesJarFile, File jarOfRoots) {
return getBuilder().createMainDexList(allClassesJarFile, jarOfRoots)
}
+
+ public static class ConfigAction implements TaskConfigAction<CreateMainDexList> {
+
+ VariantScope scope;
+
+ private Closure<List<File>> inputFiles
+
+ ConfigAction(VariantScope scope, TaskManager.PostCompilationData pcData) {
+ this.scope = scope
+ inputFiles = pcData.inputFiles;
+ }
+
+ @Override
+ String getName() {
+ return scope.getTaskName("create", "MainDexClassList");
+ }
+
+ @Override
+ Class<CreateMainDexList> getType() {
+ return CreateMainDexList
+ }
+
+ @Override
+ void execute(CreateMainDexList createMainDexList) {
+ createMainDexList.androidBuilder = scope.globalScope.androidBuilder
+
+ def files = inputFiles
+ createMainDexList.allClassesJarFile = files().first()
+ ConventionMappingHelper.map(createMainDexList, "componentsJarFile") {
+ scope.getProguardComponentsJarFile()
+ }
+ // ConventionMappingHelper.map(createMainDexListTask, "includeInMainDexJarFile") { mainDexJarFile }
+ createMainDexList.mainDexListFile = scope.manifestKeepListFile
+ createMainDexList.outputFile = scope.getMainDexListFile()
+ }
+ }
}
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/tasks/multidex/CreateManifestKeepList.groovy b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/tasks/multidex/CreateManifestKeepList.groovy
index 7d6ab56..b4dbd8c 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/tasks/multidex/CreateManifestKeepList.groovy
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/tasks/multidex/CreateManifestKeepList.groovy
@@ -18,7 +18,12 @@
package com.android.build.gradle.internal.tasks.multidex
+import com.android.build.gradle.internal.TaskManager
+import com.android.build.gradle.internal.scope.ConventionMappingHelper
+import com.android.build.gradle.internal.scope.TaskConfigAction
+import com.android.build.gradle.internal.scope.VariantScope
import com.android.build.gradle.internal.tasks.DefaultAndroidTask
+import com.android.build.gradle.internal.variant.BaseVariantOutputData
import com.google.common.base.Charsets
import com.google.common.io.Files
import org.gradle.api.tasks.InputFile
@@ -111,4 +116,41 @@
}
}
}
+
+ public static class ConfigAction implements TaskConfigAction<CreateManifestKeepList> {
+
+ VariantScope scope;
+ TaskManager.PostCompilationData pcData;
+
+ ConfigAction(VariantScope scope, TaskManager.PostCompilationData pcData) {
+ this.scope = scope
+ this.pcData = pcData
+ }
+
+ @Override
+ String getName() {
+ return scope.getTaskName("collect", "MultiDexComponents");
+ }
+
+ @Override
+ Class<CreateManifestKeepList> getType() {
+ return CreateManifestKeepList
+ }
+
+ @Override
+ void execute(CreateManifestKeepList manifestKeepListTask) {
+ // since all the output have the same manifest, besides the versionCode,
+ // we can take any of the output and use that.
+ final BaseVariantOutputData output = scope.variantData.outputs.get(0)
+ ConventionMappingHelper.map(manifestKeepListTask, "manifest") {
+ output.getScope().getManifestOutputFile()
+ }
+
+ manifestKeepListTask.proguardFile = scope.variantConfiguration.getMultiDexKeepProguard()
+ manifestKeepListTask.outputFile = scope.getManifestKeepListFile();
+
+ //variant.ext.collectMultiDexComponents = manifestKeepListTask
+ }
+ }
+
}
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/tasks/multidex/JarMergingTask.groovy b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/tasks/multidex/JarMergingTask.groovy
index 6700f57..78b968f 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/tasks/multidex/JarMergingTask.groovy
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/tasks/multidex/JarMergingTask.groovy
@@ -19,6 +19,10 @@
package com.android.build.gradle.internal.tasks.multidex
import com.android.build.gradle.internal.tasks.DefaultAndroidTask
+import com.android.build.gradle.internal.TaskManager
+import com.android.build.gradle.internal.scope.ConventionMappingHelper
+import com.android.build.gradle.internal.scope.TaskConfigAction
+import com.android.build.gradle.internal.scope.VariantScope
import com.google.common.collect.Sets
import com.google.common.hash.Hashing
import com.google.common.io.Files
@@ -152,4 +156,37 @@
fis.close()
}
+
+ public static class ConfigAction implements TaskConfigAction<JarMergingTask> {
+
+ private VariantScope scope
+
+ private Closure<File> inputDir;
+
+ private Closure<List<File>> inputLibraries;
+
+ ConfigAction(VariantScope scope, TaskManager.PostCompilationData pcData) {
+ this.scope = scope
+ inputDir = pcData.inputDir
+ inputLibraries = pcData.inputLibraries
+ }
+
+ @Override
+ String getName() {
+ return scope.getTaskName("packageAll", "ClassesForMultiDex")
+ }
+
+ @Override
+ Class<JarMergingTask> getType() {
+ return JarMergingTask
+ }
+
+ @Override
+ void execute(JarMergingTask jarMergingTask) {
+ ConventionMappingHelper.map(jarMergingTask, "inputJars", inputLibraries)
+ ConventionMappingHelper.map(jarMergingTask, "inputDir", inputDir)
+
+ jarMergingTask.jarFile = scope.getJarMergingOutputFile()
+ }
+ }
}
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/tasks/multidex/RetraceMainDexList.groovy b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/tasks/multidex/RetraceMainDexList.groovy
index 0811936..1e46d97 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/tasks/multidex/RetraceMainDexList.groovy
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/tasks/multidex/RetraceMainDexList.groovy
@@ -18,6 +18,10 @@
package com.android.build.gradle.internal.tasks.multidex
+import com.android.build.gradle.internal.TaskManager
+import com.android.build.gradle.internal.scope.ConventionMappingHelper
+import com.android.build.gradle.internal.scope.TaskConfigAction
+import com.android.build.gradle.internal.scope.VariantScope
import com.android.build.gradle.internal.tasks.DefaultAndroidTask
import com.google.common.base.Charsets
import com.google.common.base.Joiner
@@ -28,6 +32,9 @@
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction
+
+import static com.android.builder.model.AndroidProject.FD_INTERMEDIATES
+
/**
* Take a list of classes for the main dex (that was computed before obfuscation),
* a proguard-generated mapping file and create a new list of classes with the new
@@ -115,4 +122,39 @@
return map
}
+
+
+ public static class ConfigAction implements TaskConfigAction<RetraceMainDexList> {
+
+ VariantScope scope;
+
+ TaskManager.PostCompilationData pcData;
+
+ ConfigAction(VariantScope scope, TaskManager.PostCompilationData pcData) {
+ this.scope = scope
+ this.pcData = pcData
+ }
+
+ @Override
+ String getName() {
+ return scope.getTaskName("retrace", "MainDexClassList");
+ }
+
+ @Override
+ Class<RetraceMainDexList> getType() {
+ return RetraceMainDexList.class
+ }
+
+ @Override
+ void execute(RetraceMainDexList retraceTask) {
+ ConventionMappingHelper.map(retraceTask, "mainDexListFile") { scope.getMainDexListFile() }
+ ConventionMappingHelper.map(retraceTask, "mappingFile") {
+ scope.variantData.getMappingFile()
+ }
+ retraceTask.outputFile = new File(
+ "${scope.globalScope.buildDir}/${FD_INTERMEDIATES}/multi-dex/" +
+ "${scope.variantConfiguration.dirName}/maindexlist_deobfuscated.txt")
+
+ }
+ }
}
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/variant/BaseVariantData.java b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/variant/BaseVariantData.java
index 351353e..222ac06 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/variant/BaseVariantData.java
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/variant/BaseVariantData.java
@@ -27,6 +27,7 @@
import com.android.build.gradle.internal.coverage.JacocoInstrumentTask;
import com.android.build.gradle.internal.dependency.VariantDependencies;
import com.android.build.gradle.internal.dsl.Splits;
+import com.android.build.gradle.internal.scope.VariantScope;
import com.android.build.gradle.internal.tasks.CheckManifest;
import com.android.build.gradle.internal.tasks.FileSupplier;
import com.android.build.gradle.internal.tasks.GenerateApkDataTask;
@@ -91,6 +92,10 @@
private VariantDependencies variantDependency;
+ // Needed for ModelBuilder. Should be removed once VariantScope can replace BaseVariantData.
+ @NonNull
+ private final VariantScope scope;
+
public Task preBuildTask;
public PrepareDependenciesTask prepareDependenciesTask;
public ProcessAndroidResources generateRClassTask;
@@ -176,6 +181,8 @@
variantConfiguration.getMinSdkVersion().getApiLevel()));
}
variantConfiguration.checkSourceProviders();
+
+ scope = new VariantScope(taskManager.getGlobalScope(), this);
}
@@ -298,7 +305,7 @@
addJavaSourceFoldersToModel(generatedSourceFolders);
}
- public void registerResGeneratingTask(@NonNull Task task, @NonNull File... generatedResFolders) {
+ public void registerResGeneratingTask(@NonNull Task task, @NonNull File... generatedResFolders) {
// no need add the folders anywhere, the convention mapping closure for the MergeResources
// action will pick them up from here
resourceGenTask.dependsOn(task);
@@ -370,8 +377,8 @@
*/
private List<File> getGeneratedResFolders() {
List<File> generatedResFolders = Lists.newArrayList(
- renderscriptCompileTask.getResOutputDir(),
- generateResValuesTask.getResOutputDir());
+ scope.getRenderscriptResOutputDir(),
+ scope.getGeneratedResOutputDir());
if (extraGeneratedResFolders != null) {
generatedResFolders.addAll(extraGeneratedResFolders);
}
@@ -531,22 +538,22 @@
}
// then all the generated src folders.
- if (generateRClassTask != null) {
- sourceList.add(generateRClassTask.getSourceOutputDir());
+ if (getScope().getGenerateRClassTask() != null) {
+ sourceList.add(getScope().getRClassSourceOutputDir());
}
// for the other, there's no duplicate so no issue.
- if (generateBuildConfigTask != null) {
- sourceList.add(generateBuildConfigTask.getSourceOutputDir());
+ if (getScope().getGenerateBuildConfigTask() != null) {
+ sourceList.add(scope.getBuildConfigSourceOutputDir());
}
- if (aidlCompileTask != null) {
- sourceList.add(aidlCompileTask.getSourceOutputDir());
+ if (getScope().getAidlCompileTask() != null) {
+ sourceList.add(scope.getAidlSourceOutputDir());
}
if (!variantConfiguration.getRenderscriptNdkModeEnabled()
- && renderscriptCompileTask != null) {
- sourceList.add(renderscriptCompileTask.getSourceOutputDir());
+ && getScope().getRenderscriptCompileTask() != null) {
+ sourceList.add(scope.getRenderscriptSourceOutputDir());
}
javaSources = sourceList.toArray();
@@ -646,4 +653,9 @@
}
return output;
}
+
+ @NonNull
+ public VariantScope getScope() {
+ return scope;
+ }
}
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/variant/BaseVariantOutputData.java b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/variant/BaseVariantOutputData.java
index c938018..e0c47c8 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/variant/BaseVariantOutputData.java
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/variant/BaseVariantOutputData.java
@@ -22,6 +22,7 @@
import com.android.build.OutputFile;
import com.android.build.VariantOutput;
import com.android.build.gradle.api.ApkOutputFile;
+import com.android.build.gradle.internal.scope.VariantOutputScope;
import com.android.build.gradle.tasks.ManifestProcessorTask;
import com.android.build.gradle.tasks.PackageSplitAbi;
import com.android.build.gradle.tasks.PackageSplitRes;
@@ -60,6 +61,9 @@
public Task assembleTask;
+ @NonNull
+ private final VariantOutputScope scope;
+
public BaseVariantOutputData(
@NonNull OutputFile.OutputType outputType,
@NonNull Collection<FilterData> filters,
@@ -67,6 +71,7 @@
this.variantData = variantData;
this.mainApkOutputFile = new ApkOutputFile(
outputType, filters, getOutputFilePromise());
+ scope = new VariantOutputScope(variantData.getScope(), this);
}
@Nullable
@@ -152,4 +157,9 @@
void setMultiOutput(boolean multiOutput) {
this.multiOutput = multiOutput;
}
+
+ @NonNull
+ public VariantOutputScope getScope() {
+ return scope;
+ }
}
\ No newline at end of file
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/AidlCompile.groovy b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/AidlCompile.groovy
index 0805fe5..38dda4b 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/AidlCompile.groovy
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/AidlCompile.groovy
@@ -16,13 +16,25 @@
package com.android.build.gradle.tasks
+import com.android.SdkConstants
import com.android.annotations.NonNull
import com.android.annotations.Nullable
import com.android.annotations.concurrency.GuardedBy
+import com.android.build.gradle.api.ApkVariant
+import com.android.build.gradle.internal.TaskManager
+import com.android.build.gradle.internal.scope.ConventionMappingHelper
+import com.android.build.gradle.internal.scope.TaskConfigAction
+import com.android.build.gradle.internal.scope.VariantScope
import com.android.build.gradle.internal.tasks.IncrementalTask
+import com.android.build.gradle.internal.variant.ApkVariantData
+import com.android.build.gradle.internal.variant.BaseVariantData
+import com.android.build.gradle.internal.variant.BaseVariantOutputData
import com.android.builder.compiling.DependencyFileProcessor
+import com.android.builder.core.VariantConfiguration
+import com.android.builder.core.VariantType
import com.android.builder.internal.incremental.DependencyData
import com.android.builder.internal.incremental.DependencyDataStore
+import com.android.builder.model.AndroidProject
import com.android.ide.common.internal.WaitableExecutor
import com.android.ide.common.res2.FileStatus
import com.google.common.collect.Lists
@@ -36,6 +48,9 @@
import java.util.concurrent.Callable
+import static com.android.builder.model.AndroidProject.FD_GENERATED
+import static com.android.builder.model.AndroidProject.FD_INTERMEDIATES
+
/**
* Task to compile aidl files. Supports incremental update.
*/
@@ -278,4 +293,54 @@
new File(output).delete()
}
}
+
+
+ public static class ConfigAction implements TaskConfigAction<AidlCompile> {
+
+ @NonNull
+ VariantScope scope
+
+ ConfigAction(@NonNull VariantScope scope) {
+ this.scope = scope
+ }
+
+ @Override
+ @NonNull
+ String getName() {
+ return scope.getTaskName("compile", "Aidl")
+ }
+
+ @Override
+ @NonNull
+ Class<AidlCompile> getType() {
+ return AidlCompile
+ }
+
+ @Override
+ void execute(AidlCompile compileTask) {
+ VariantConfiguration variantConfiguration = scope.variantConfiguration
+
+ scope.variantData.aidlCompileTask = compileTask
+
+ compileTask.androidBuilder = scope.globalScope.androidBuilder
+ compileTask.incrementalFolder =
+ new File(
+ "$scope.globalScope.buildDir/${FD_INTERMEDIATES}/incremental/aidl/${variantConfiguration.dirName}")
+
+ ConventionMappingHelper.map(compileTask, "sourceDirs") { variantConfiguration.aidlSourceList }
+ ConventionMappingHelper.map(compileTask, "importDirs") { variantConfiguration.aidlImports }
+
+ ConventionMappingHelper.map(compileTask, "sourceOutputDir") {
+ //new File(scope.globalScope.generatedDir, "source/aidl/${variantConfiguration.dirName}")
+ scope.getAidlSourceOutputDir()
+ }
+
+ if (variantConfiguration.type == VariantType.LIBRARY) {
+ compileTask.aidlParcelableDir = new File(
+ "$scope.globalScope.buildDir/${FD_INTERMEDIATES}/$TaskManager.DIR_BUNDLES/${variantConfiguration.dirName}/$SdkConstants.FD_AIDL")
+ }
+
+ }
+ }
+
}
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/AndroidProGuardTask.java b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/AndroidProGuardTask.java
index f25be99..cd8fa12 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/AndroidProGuardTask.java
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/AndroidProGuardTask.java
@@ -16,18 +16,44 @@
package com.android.build.gradle.tasks;
+import static com.android.builder.model.AndroidProject.FD_INTERMEDIATES;
+import static com.android.builder.model.AndroidProject.FD_OUTPUTS;
+
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
+import com.android.build.gradle.LibraryExtension;
+import com.android.build.gradle.internal.DependencyManager;
+import com.android.build.gradle.internal.TaskManager;
+import com.android.build.gradle.internal.scope.TaskConfigAction;
+import com.android.build.gradle.internal.scope.VariantScope;
import com.android.build.gradle.internal.tasks.FileSupplier;
+import com.android.build.gradle.internal.variant.BaseVariantData;
+import com.android.build.gradle.internal.variant.BaseVariantOutputData;
+import com.android.build.gradle.internal.variant.LibraryVariantData;
+import com.android.builder.core.VariantConfiguration;
+import com.android.utils.StringHelper;
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+import org.codehaus.groovy.runtime.DefaultGroovyMethods;
+import org.gradle.api.Action;
import org.gradle.api.Task;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.Optional;
import org.gradle.api.tasks.TaskAction;
+import org.gradle.tooling.BuildException;
import java.io.File;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Set;
+import groovy.lang.Closure;
import proguard.ParseException;
import proguard.gradle.ProGuardTask;
@@ -86,4 +112,269 @@
}
super.proguard();
}
+
+ public static class ConfigAction implements TaskConfigAction<AndroidProGuardTask> {
+
+ private VariantScope scope;
+
+ private Closure<File> inputDir;
+
+ private Closure<List<File>> inputLibraries;
+
+ public ConfigAction(VariantScope scope,
+ TaskManager.PostCompilationData pcData) {
+ this.scope = scope;
+ inputDir = pcData.getInputDir();
+ inputLibraries = pcData.getInputLibraries();
+ }
+
+ @Override
+ public String getName() {
+ return scope.getTaskName("proguard");
+ }
+
+ @Override
+ public Class<AndroidProGuardTask> getType() {
+ return AndroidProGuardTask.class;
+ }
+
+ @Override
+ public void execute(final AndroidProGuardTask proguardTask) {
+ final BaseVariantData<? extends BaseVariantOutputData> variantData = scope.getVariantData();
+ final VariantConfiguration variantConfig = scope.getVariantData().getVariantConfiguration();
+ final BaseVariantData testedVariantData = scope.getTestedVariantData();
+
+ // use single output for now.
+ final BaseVariantOutputData variantOutputData = scope.getVariantData().getOutputs().get(0);
+
+ if (testedVariantData != null) {
+ proguardTask.dependsOn(testedVariantData.getScope().getObfuscationTask().getName());
+ }
+
+ variantData.obfuscationTask = proguardTask;
+ variantData.mappingFileProviderTask = proguardTask;
+
+ // --- Output File ---
+
+ final File outFile = variantData instanceof LibraryVariantData ? new File(
+ String.valueOf(scope.getGlobalScope().getBuildDir()) + "/" + FD_INTERMEDIATES + "/"
+ + TaskManager.DIR_BUNDLES + "/" + variantData.getVariantConfiguration()
+ .getDirName() + "/classes.jar") : new File(
+ String.valueOf(scope.getGlobalScope().getBuildDir()) + "/" + FD_INTERMEDIATES
+ + "/classes-proguard/" + variantData.getVariantConfiguration().getDirName()
+ + "/classes.jar");
+ variantData.obfuscatedClassesJar = outFile;
+
+ // --- Proguard Config ---
+
+ try {
+
+ if (testedVariantData != null) {
+ // Don't remove any code in tested app.
+ proguardTask.dontshrink();
+ proguardTask.dontoptimize();
+
+ // We can't call dontobfuscate, since that would make ProGuard ignore the mapping file.
+ proguardTask.keep("class * {*;}");
+ proguardTask.keep("interface * {*;}");
+ proguardTask.keep("enum * {*;}");
+
+ // Input the mapping from the tested app so that we can deal with obfuscated code.
+ proguardTask.applymapping(testedVariantData.getMappingFile());
+
+ // All -dontwarn rules for test dependencies should go in here:
+ proguardTask.configuration(
+ testedVariantData.getVariantConfiguration().getTestProguardFiles());
+ } else {
+ if (variantConfig.isTestCoverageEnabled()) {
+ // when collecting coverage, don't remove the JaCoCo runtime
+ proguardTask.keep("class com.vladium.** {*;}");
+ proguardTask.keep("class org.jacoco.** {*;}");
+ proguardTask.keep("interface org.jacoco.** {*;}");
+ proguardTask.dontwarn("org.jacoco.**");
+ }
+
+ proguardTask.configuration(new Closure<Collection<File>>(this, this) {
+ public Collection<File> doCall(Object it) {
+ List<File> proguardFiles = variantConfig.getProguardFiles(true,
+ Collections.singletonList(scope.getGlobalScope().getExtension()
+ .getDefaultProguardFile(
+ TaskManager.DEFAULT_PROGUARD_CONFIG_FILE)));
+ proguardFiles.add(
+ variantOutputData.processResourcesTask.getProguardOutputFile());
+ return proguardFiles;
+ }
+
+ public Collection<File> doCall() {
+ return doCall(null);
+ }
+
+ });
+ }
+
+ // --- InJars / LibraryJars ---
+
+ if (variantData instanceof LibraryVariantData) {
+ String packageName = variantConfig.getPackageFromManifest();
+ if (packageName == null) {
+ throw new BuildException("Failed to read manifest", null);
+ }
+
+ packageName = packageName.replace(".", "/");
+
+ // injar: the compilation output
+ // exclude R files and such from output
+ String exclude = "!" + packageName + "/R.class";
+ exclude += (", !" + packageName + "/R$*.class");
+ if (!((LibraryExtension) scope.getGlobalScope().getExtension())
+ .getPackageBuildConfig()) {
+ exclude += (", !" + packageName + "/Manifest.class");
+ exclude += (", !" + packageName + "/Manifest$*.class");
+ exclude += (", !" + packageName + "/BuildConfig.class");
+ }
+
+ proguardTask.injars(ImmutableMap.of("filter", exclude), inputDir);
+
+ // include R files and such for compilation
+ String include = exclude.replace("!", "");
+ LinkedHashMap<String, Object> map1 = new LinkedHashMap<String, Object>(1);
+ map1.put("filter", include);
+ proguardTask.libraryjars(map1, inputDir);
+
+ // injar: the local dependencies
+ Closure inJars = new Closure<List<File>>(this, this) {
+ public List<File> doCall(Object it) {
+ return DependencyManager
+ .getPackagedLocalJarFileList(variantData.getVariantDependency());
+ }
+
+ public List<File> doCall() {
+ return doCall(null);
+ }
+
+ };
+
+ proguardTask.injars(ImmutableMap.of("filter", "!META-INF/MANIFEST.MF"), inJars);
+
+ // libjar: the library dependencies. In this case we take all the compile-scope
+ // dependencies
+ Closure libJars = new Closure<Iterable<File>>(this, this) {
+ public Iterable<File> doCall(Object it) {
+ // get all the compiled jar.
+ Set<File> compiledJars = scope.getGlobalScope().getAndroidBuilder()
+ .getCompileClasspath(variantConfig);
+ // and remove local jar that are also packaged
+ final List<File> localJars = DependencyManager
+ .getPackagedLocalJarFileList(variantData.getVariantDependency());
+
+ return Iterables.filter(compiledJars, new Predicate<File>() {
+ @Override
+ public boolean apply(File file) {
+ return !localJars.contains(file);
+ }
+ });
+ }
+
+ public Iterable<File> doCall() {
+ return doCall(null);
+ }
+ };
+
+ proguardTask.libraryjars(ImmutableMap.of("filter", "!META-INF/MANIFEST.MF"), libJars);
+
+ // ensure local jars keep their package names
+ proguardTask.keeppackagenames();
+ } else {
+ // injar: the compilation output
+ proguardTask.injars(inputDir);
+
+ // injar: the packaged dependencies
+ LinkedHashMap<String, String> map = new LinkedHashMap<String, String>(1);
+ map.put("filter", "!META-INF/MANIFEST.MF");
+ proguardTask.injars(map, inputLibraries);
+
+ // the provided-only jars as libraries.
+ Closure libJars = new Closure<List<File>>(this, this) {
+ public List<File> doCall(Object it) {
+ return variantData.getVariantConfiguration().getProvidedOnlyJars();
+ }
+
+ public List<File> doCall() {
+ return doCall(null);
+ }
+
+ };
+
+ proguardTask.libraryjars(libJars);
+ }
+
+ // libraryJars: the runtime jars. Do this in doFirst since the boot classpath isn't
+ // available until the SDK is loaded in the prebuild task
+ proguardTask.doFirst(new Action<Task>() {
+ @Override
+ public void execute(Task proguardTask) {
+ for (String runtimeJar : scope.getGlobalScope().getAndroidBuilder()
+ .getBootClasspathAsStrings()) {
+ try {
+ ((AndroidProGuardTask)proguardTask).libraryjars(runtimeJar);
+ } catch (ParseException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ });
+
+ if (testedVariantData != null) {
+ // input the tested app as library
+ proguardTask.libraryjars(testedVariantData.javaCompileTask.getDestinationDir());
+ // including its dependencies
+ Closure testedPackagedJars = new Closure<Set<File>>(this, this) {
+ public Set<File> doCall(Object it) {
+ return scope.getGlobalScope().getAndroidBuilder()
+ .getPackagedJars(testedVariantData.getVariantConfiguration());
+ }
+
+ public Set<File> doCall() {
+ return doCall(null);
+ }
+
+ };
+
+ LinkedHashMap<String, String> map = new LinkedHashMap<String, String>(1);
+ map.put("filter", "!META-INF/MANIFEST.MF");
+ proguardTask.libraryjars(map, testedPackagedJars);
+ }
+
+ // --- Out files ---
+
+ proguardTask.outjars(outFile);
+
+ final File proguardOut = new File(
+ String.valueOf(scope.getGlobalScope().getBuildDir()) + "/" + FD_OUTPUTS
+ + "/mapping/" + variantData.getVariantConfiguration().getDirName());
+
+ proguardTask.dump(new File(proguardOut, "dump.txt"));
+ proguardTask.printseeds(new File(proguardOut, "seeds.txt"));
+ proguardTask.printusage(new File(proguardOut, "usage.txt"));
+ proguardTask.printmapping(new File(proguardOut, "mapping.txt"));
+
+ // proguard doesn't verify that the seed/mapping/usage folders exist and will fail
+ // if they don't so create them.
+ proguardTask.doFirst(new Closure<Boolean>(this, this) {
+ public Boolean doCall(Task it) {
+ return proguardOut.mkdirs();
+ }
+
+ public Boolean doCall() {
+ return doCall(null);
+ }
+
+ });
+ } catch (ParseException e) {
+ throw new RuntimeException(e);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
}
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/CompatibleScreensManifest.groovy b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/CompatibleScreensManifest.groovy
index 0b680c2..7320ecc 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/CompatibleScreensManifest.groovy
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/CompatibleScreensManifest.groovy
@@ -17,6 +17,9 @@
package com.android.build.gradle.tasks
import com.android.annotations.NonNull
+import com.android.build.gradle.internal.scope.ConventionMappingHelper
+import com.android.build.gradle.internal.scope.TaskConfigAction
+import com.android.build.gradle.internal.scope.VariantOutputScope
import com.android.build.gradle.internal.tasks.DefaultAndroidTask
import com.android.resources.Density
import com.google.common.base.Charsets
@@ -76,4 +79,41 @@
return density;
}
+
+ public static class ConfigAction implements TaskConfigAction<CompatibleScreensManifest> {
+
+ @NonNull
+ VariantOutputScope scope
+ @NonNull
+ Set<String> screenSizes
+
+ ConfigAction(
+ @NonNull VariantOutputScope scope,
+ @NonNull Set<String> screenSizes) {
+ this.scope = scope
+ this.screenSizes = screenSizes
+ }
+
+ @Override
+ String getName() {
+ return scope.getTaskName("create", "CompatibleScreenManifest")
+ }
+
+ @Override
+ Class<CompatibleScreensManifest> getType() {
+ return CompatibleScreensManifest.class
+ }
+
+ @Override
+ void execute(CompatibleScreensManifest csmTask) {
+
+ csmTask.screenDensity = scope.variantOutputData.getMainOutputFile().getFilter(
+ com.android.build.OutputFile.DENSITY)
+ csmTask.screenSizes = screenSizes
+
+ ConventionMappingHelper.map(csmTask, "manifestFile") {
+ scope.getCompatibleScreensManifestFile()
+ }
+ }
+ }
}
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/Dex.groovy b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/Dex.groovy
index 7214271..36af87b 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/Dex.groovy
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/Dex.groovy
@@ -17,8 +17,17 @@
import com.android.SdkConstants
import com.android.annotations.Nullable
+import com.android.build.gradle.internal.TaskManager
+import com.android.build.gradle.internal.core.GradleVariantConfiguration
import com.android.build.gradle.internal.dsl.DexOptions
+import com.android.build.gradle.internal.scope.ConventionMappingHelper
+import com.android.build.gradle.internal.scope.TaskConfigAction
+import com.android.build.gradle.internal.scope.VariantScope
import com.android.build.gradle.internal.tasks.BaseTask
+import com.android.build.gradle.internal.variant.ApkVariantData
+import com.android.build.gradle.internal.variant.TestVariantData
+import com.android.utils.StringHelper
+import org.codehaus.groovy.runtime.DefaultGroovyMethods
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputDirectory
import org.gradle.api.tasks.InputFile
@@ -29,8 +38,12 @@
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.incremental.IncrementalTaskInputs
+import java.util.concurrent.Callable
import java.util.concurrent.atomic.AtomicBoolean
+import static com.android.builder.core.VariantType.DEFAULT
+import static com.android.builder.model.AndroidProject.FD_INTERMEDIATES
+
public class Dex extends BaseTask {
// ----- PUBLIC TASK API -----
@@ -157,4 +170,74 @@
getOptimize(),
)
}
+
+
+ public static class ConfigAction implements TaskConfigAction<Dex> {
+
+ private final VariantScope scope;
+
+ private final TaskManager.PostCompilationData pcData;
+
+ public ConfigAction(VariantScope scope, TaskManager.PostCompilationData pcData) {
+ this.scope = scope;
+ this.pcData = pcData;
+ }
+
+ @Override
+ public String getName() {
+ return scope.getTaskName("dex")
+ }
+
+ @Override
+ public Class<Dex> getType() {
+ return Dex.class;
+ }
+
+ @Override
+ public void execute(Dex dexTask) {
+ ApkVariantData variantData = (ApkVariantData) scope.getVariantData();
+ final GradleVariantConfiguration config = variantData.getVariantConfiguration();
+
+ boolean isTestForApp = config.getType().isForTesting() && (DefaultGroovyMethods
+ .asType(variantData, TestVariantData.class)).getTestedVariantData()
+ .getVariantConfiguration().getType().equals(DEFAULT);
+
+ boolean isMultiDexEnabled = config.isMultiDexEnabled() && !isTestForApp;
+ boolean isLegacyMultiDexMode = config.isLegacyMultiDexMode();
+
+ variantData.dexTask = dexTask;
+ dexTask.setAndroidBuilder(scope.getGlobalScope().getAndroidBuilder());
+ ConventionMappingHelper.map(dexTask, "outputFolder", new Callable<File>() {
+ @Override
+ public File call() throws Exception {
+ return scope.getDexOutputFolder();
+ }
+ });
+ dexTask.setTmpFolder(new File(
+ String.valueOf(scope.getGlobalScope().getBuildDir()) + "/" + FD_INTERMEDIATES
+ + "/tmp/dex/" + config.getDirName()));
+ dexTask.setDexOptions(scope.getGlobalScope().getExtension().getDexOptions());
+ dexTask.setMultiDexEnabled(isMultiDexEnabled);
+ dexTask.setLegacyMultiDexMode(isLegacyMultiDexMode);
+ // dx doesn't work with receving --no-optimize in debug so we disable it for now.
+ dexTask.setOptimize(true);//!variantData.variantConfiguration.buildType.debuggable
+
+ // inputs
+ if (pcData.getInputDir() != null) {
+ ConventionMappingHelper.map(dexTask, "inputDir", pcData.getInputDir());
+ }
+ ConventionMappingHelper.map(dexTask, "inputFiles", pcData.getInputFiles());
+ ConventionMappingHelper.map(dexTask, "libraries", pcData.getInputLibraries());
+
+ if (isMultiDexEnabled && isLegacyMultiDexMode) {
+ // configure the dex task to receive the generated class list.
+ ConventionMappingHelper.map(dexTask, "mainDexListFile", new Callable<File>() {
+ @Override
+ public File call() throws Exception {
+ return scope.getMainDexListFile();
+ }
+ });
+ }
+ }
+ }
}
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/GenerateBuildConfig.groovy b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/GenerateBuildConfig.groovy
index d296c8d..0216881 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/GenerateBuildConfig.groovy
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/GenerateBuildConfig.groovy
@@ -15,8 +15,15 @@
*/
package com.android.build.gradle.tasks
+import com.android.annotations.NonNull
+import com.android.build.gradle.internal.scope.ConventionMappingHelper
+import com.android.build.gradle.internal.scope.TaskConfigAction
+import com.android.build.gradle.internal.scope.VariantScope
import com.android.build.gradle.internal.tasks.BaseTask
+import com.android.build.gradle.internal.variant.BaseVariantData
+import com.android.build.gradle.internal.variant.BaseVariantOutputData
import com.android.builder.compiling.BuildConfigGenerator
+import com.android.builder.core.VariantConfiguration
import com.android.builder.model.ClassField
import com.google.common.collect.Lists
import org.gradle.api.tasks.Input
@@ -53,7 +60,8 @@
@Input
String buildTypeName
- @Input @Optional
+ @Input
+ @Optional
String versionName
@Input
@@ -103,22 +111,100 @@
// where debug is true, which is the most likely scenario while the user is looking
// at source code.
//map.put(PH_DEBUG, Boolean.toString(mDebug));
- generator.addField("boolean", "DEBUG", getDebuggable() ? "Boolean.parseBoolean(\"true\")" : "false")
- .addField("String", "APPLICATION_ID", "\"${getAppPackageName()}\"")
- .addField("String", "BUILD_TYPE", "\"${getBuildTypeName()}\"")
- .addField("String", "FLAVOR", "\"${getFlavorName()}\"")
- .addField("int", "VERSION_CODE", Integer.toString(getVersionCode()))
- .addField("String", "VERSION_NAME", "\"${vn}\"")
- .addItems(getItems())
+ generator.addField("boolean", "DEBUG",
+ getDebuggable() ? "Boolean.parseBoolean(\"true\")" : "false")
+ .addField("String", "APPLICATION_ID", "\"${getAppPackageName()}\"")
+ .addField("String", "BUILD_TYPE", "\"${getBuildTypeName()}\"")
+ .addField("String", "FLAVOR", "\"${getFlavorName()}\"")
+ .addField("int", "VERSION_CODE", Integer.toString(getVersionCode()))
+ .addField("String", "VERSION_NAME", "\"${vn}\"")
+ .addItems(getItems())
List<String> flavors = getFlavorNamesWithDimensionNames()
int count = flavors.size()
if (count > 1) {
- for (int i = 0; i < count ; i+=2) {
- generator.addField("String", "FLAVOR_${flavors.get(i+1)}", "\"${flavors.get(i)}\"")
+ for (int i = 0; i < count; i += 2) {
+ generator.
+ addField("String", "FLAVOR_${flavors.get(i + 1)}", "\"${flavors.get(i)}\"")
}
}
generator.generate()
}
+
+ // ----- Config Action -----
+
+ public static class ConfigAction implements TaskConfigAction<GenerateBuildConfig> {
+
+ @NonNull
+ VariantScope scope
+
+ ConfigAction(@NonNull VariantScope scope) {
+ this.scope = scope
+ }
+
+ @Override
+ @NonNull
+ String getName() {
+ return scope.getTaskName("generate", "BuildConfig");
+ }
+
+ @Override
+ @NonNull
+ Class<GenerateBuildConfig> getType() {
+ return GenerateBuildConfig
+ }
+
+
+ @Override
+ void execute(GenerateBuildConfig generateBuildConfigTask) {
+ BaseVariantData<? extends BaseVariantOutputData> variantData = scope.variantData
+
+ variantData.generateBuildConfigTask = generateBuildConfigTask
+
+ VariantConfiguration variantConfiguration = variantData.variantConfiguration
+
+ generateBuildConfigTask.androidBuilder = scope.globalScope.androidBuilder
+
+ ConventionMappingHelper.map(generateBuildConfigTask, "buildConfigPackageName") {
+ variantConfiguration.originalApplicationId
+ }
+
+ ConventionMappingHelper.map(generateBuildConfigTask, "appPackageName") {
+ variantConfiguration.applicationId
+ }
+
+ ConventionMappingHelper.map(generateBuildConfigTask, "versionName") {
+ variantConfiguration.versionName
+ }
+
+ ConventionMappingHelper.map(generateBuildConfigTask, "versionCode") {
+ variantConfiguration.versionCode
+ }
+
+ ConventionMappingHelper.map(generateBuildConfigTask, "debuggable") {
+ variantConfiguration.buildType.isDebuggable()
+ }
+
+ ConventionMappingHelper.map(generateBuildConfigTask, "buildTypeName") {
+ variantConfiguration.buildType.name
+ }
+
+ ConventionMappingHelper.map(generateBuildConfigTask, "flavorName") {
+ variantConfiguration.flavorName
+ }
+
+ ConventionMappingHelper.map(generateBuildConfigTask, "flavorNamesWithDimensionNames") {
+ variantConfiguration.flavorNamesWithDimensionNames
+ }
+
+ ConventionMappingHelper.map(generateBuildConfigTask, "items") {
+ variantConfiguration.buildConfigItems
+ }
+
+ ConventionMappingHelper.map(generateBuildConfigTask, "sourceOutputDir") {
+ scope.getBuildConfigSourceOutputDir()
+ }
+ }
+ }
}
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/GenerateResValues.groovy b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/GenerateResValues.groovy
index be6593a..6fe016e 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/GenerateResValues.groovy
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/GenerateResValues.groovy
@@ -15,8 +15,14 @@
*/
package com.android.build.gradle.tasks
+import com.android.annotations.NonNull
+import com.android.build.gradle.internal.scope.ConventionMappingHelper
+import com.android.build.gradle.internal.scope.TaskConfigAction
+import com.android.build.gradle.internal.scope.VariantScope
import com.android.build.gradle.internal.tasks.BaseTask
import com.android.builder.compiling.ResValueGenerator
+import com.android.builder.core.VariantConfiguration
+import com.android.builder.model.AndroidProject
import com.android.builder.model.ClassField
import com.google.common.collect.Lists
import org.gradle.api.tasks.Input
@@ -24,6 +30,8 @@
import org.gradle.api.tasks.ParallelizableTask
import org.gradle.api.tasks.TaskAction
+import static com.android.builder.model.AndroidProject.FD_GENERATED
+
@ParallelizableTask
public class GenerateResValues extends BaseTask {
@@ -69,4 +77,43 @@
generator.generate()
}
}
+
+
+ public static class ConfigAction implements TaskConfigAction<GenerateResValues> {
+
+ @NonNull
+ VariantScope scope
+
+ ConfigAction(@NonNull VariantScope scope) {
+ this.scope = scope
+ }
+
+ @Override
+ String getName() {
+ return scope.getTaskName("generate", "ResValues");
+ }
+
+ @Override
+ Class getType() {
+ return GenerateResValues.class
+ }
+
+ @Override
+ void execute(GenerateResValues generateResValuesTask) {
+ scope.variantData.generateResValuesTask = generateResValuesTask
+
+ VariantConfiguration variantConfiguration = scope.variantData.variantConfiguration
+
+ generateResValuesTask.androidBuilder = scope.globalScope.androidBuilder
+
+ ConventionMappingHelper.map(generateResValuesTask, "items") {
+ variantConfiguration.resValues
+ }
+
+ ConventionMappingHelper.map(generateResValuesTask, "resOutputDir") {
+ new File(scope.globalScope.generatedDir,
+ "res/resValues/${scope.variantData.variantConfiguration.dirName}")
+ }
+ }
+ }
}
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/Lint.groovy b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/Lint.groovy
index 02bd1c2..94b4793 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/Lint.groovy
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/Lint.groovy
@@ -21,6 +21,9 @@
import com.android.build.gradle.internal.LintGradleClient
import com.android.build.gradle.internal.dsl.LintOptions
import com.android.build.gradle.internal.model.ModelBuilder
+import com.android.build.gradle.internal.scope.AndroidTask
+import com.android.build.gradle.internal.scope.TaskConfigAction
+import com.android.build.gradle.internal.scope.VariantScope
import com.android.build.gradle.internal.tasks.DefaultAndroidTask
import com.android.builder.model.AndroidProject
import com.android.builder.model.Variant
@@ -35,6 +38,7 @@
import com.google.common.collect.Maps
import org.gradle.api.GradleException
import org.gradle.api.Project
+import org.gradle.api.plugins.JavaBasePlugin
import org.gradle.api.tasks.ParallelizableTask
import org.gradle.api.tasks.TaskAction
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
@@ -263,4 +267,36 @@
return issues;
}
}
+
+ public static class ConfigAction implements TaskConfigAction<Lint> {
+
+ @NonNull
+ VariantScope scope
+
+ ConfigAction(@NonNull VariantScope scope) {
+ this.scope = scope
+ }
+
+ @Override
+ @NonNull
+ String getName() {
+ return scope.getTaskName("lint")
+ }
+
+ @Override
+ @NonNull
+ Class<Lint> getType() {
+ return Lint
+ }
+
+ @Override
+ void execute(Lint lint) {
+ lint.setLintOptions(scope.globalScope.getExtension().lintOptions)
+ lint.setSdkHome(scope.globalScope.sdkHandler.getSdkFolder())
+ lint.setVariantName(scope.variantConfiguration.fullName)
+ lint.setToolingRegistry(scope.globalScope.toolingRegistry)
+ lint.description = "Runs lint on the " + scope.variantConfiguration.fullName.capitalize() + " build."
+ lint.group = JavaBasePlugin.VERIFICATION_GROUP
+ }
+ }
}
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/MergeAssets.groovy b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/MergeAssets.groovy
index c0149d3..3195d82 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/MergeAssets.groovy
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/MergeAssets.groovy
@@ -15,7 +15,16 @@
*/
package com.android.build.gradle.tasks
+import com.android.annotations.NonNull
+import com.android.build.gradle.internal.scope.ConventionMappingHelper
+import com.android.build.gradle.internal.scope.TaskConfigAction
+import com.android.build.gradle.internal.scope.VariantScope
import com.android.build.gradle.internal.tasks.IncrementalTask
+import com.android.build.gradle.internal.variant.BaseVariantData
+import com.android.build.gradle.internal.variant.BaseVariantOutputData
+import com.android.builder.core.VariantConfiguration
+import com.android.builder.core.VariantType
+import com.android.builder.model.AndroidProject
import com.android.ide.common.res2.AssetMerger
import com.android.ide.common.res2.AssetSet
import com.android.ide.common.res2.FileStatus
@@ -139,4 +148,50 @@
throw new ResourceException(e.getMessage(), e)
}
}
+
+
+ public static class ConfigAction implements TaskConfigAction<MergeAssets> {
+
+ @NonNull
+ VariantScope scope
+
+ ConfigAction(VariantScope scope) {
+ this.scope = scope
+ }
+
+ @Override
+ String getName() {
+ return scope.getTaskName("merge", "Assets");
+ }
+
+ @Override
+ Class<MergeAssets> getType() {
+ return MergeAssets
+ }
+
+ @Override
+ void execute(MergeAssets mergeAssetsTask) {
+ BaseVariantData<? extends BaseVariantOutputData> variantData = scope.variantData
+ VariantConfiguration variantConfig = variantData.variantConfiguration
+ boolean includeDependencies = variantConfig.type != VariantType.LIBRARY
+
+ variantData.mergeAssetsTask = mergeAssetsTask
+
+ mergeAssetsTask.androidBuilder = scope.globalScope.androidBuilder
+ mergeAssetsTask.incrementalFolder =
+ new File(
+ "$scope.globalScope.buildDir/${AndroidProject.FD_INTERMEDIATES}/incremental/mergeAssets/${variantConfig.dirName}")
+
+ ConventionMappingHelper.map(mergeAssetsTask, "inputAssetSets") {
+ def generatedAssets = []
+ if (variantData.copyApkTask != null) {
+ generatedAssets.add(variantData.copyApkTask.destinationDir)
+ }
+ variantConfig.getAssetSets(generatedAssets, includeDependencies)
+ }
+ ConventionMappingHelper.map(mergeAssetsTask, "outputDir") {
+ scope.getMergeAssetsOutputDir()
+ }
+ }
+ }
}
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/MergeManifests.groovy b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/MergeManifests.groovy
index eb2d002..63a84ab 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/MergeManifests.groovy
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/MergeManifests.groovy
@@ -14,9 +14,20 @@
* limitations under the License.
*/
package com.android.build.gradle.tasks
+
+import com.android.annotations.NonNull
import com.android.build.gradle.internal.dependency.ManifestDependencyImpl
+import com.android.build.gradle.internal.scope.ConventionMappingHelper
+import com.android.build.gradle.internal.scope.TaskConfigAction
+import com.android.build.gradle.internal.scope.VariantOutputScope
+import com.android.build.gradle.internal.scope.VariantScope
+import com.android.build.gradle.internal.tasks.PrepareDependenciesTask
import com.android.build.gradle.internal.variant.ApkVariantOutputData
+import com.android.build.gradle.internal.variant.BaseVariantData
+import com.android.build.gradle.internal.variant.BaseVariantOutputData
import com.android.builder.core.VariantConfiguration
+import com.android.builder.dependency.LibraryDependency
+import com.android.builder.model.AndroidProject
import com.android.manifmerger.ManifestMerger2
import com.google.common.collect.Lists
import org.gradle.api.tasks.Input
@@ -25,6 +36,9 @@
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.ParallelizableTask
+import static com.android.builder.model.AndroidProject.FD_INTERMEDIATES
+import static com.android.builder.model.AndroidProject.FD_OUTPUTS
+
/**
* A task that processes the manifest
*/
@@ -129,4 +143,120 @@
variantConfiguration.getManifestPlaceholders(),
getReportFile())
}
+
+ // ----- ConfigAction -----
+
+ public static class ConfigAction implements TaskConfigAction<MergeManifests> {
+
+ VariantOutputScope scope
+
+ ConfigAction(VariantOutputScope scope) {
+ this.scope = scope
+ }
+
+ @Override
+ String getName() {
+ return scope.getTaskName("process", "Manifest")
+ }
+
+ @Override
+ Class<MergeManifests> getType() {
+ return MergeManifests
+ }
+
+ @Override
+ void execute(MergeManifests processManifestTask) {
+ BaseVariantOutputData variantOutputData = scope.variantOutputData
+
+ BaseVariantData<? extends BaseVariantOutputData> variantData =
+ scope.variantScope.variantData
+ VariantConfiguration config = variantData.getVariantConfiguration()
+
+ variantOutputData.manifestProcessorTask = processManifestTask
+
+ processManifestTask.androidBuilder = scope.globalScope.androidBuilder
+
+ processManifestTask.dependsOn variantData.prepareDependenciesTask
+ if (variantData.generateApkDataTask != null) {
+ processManifestTask.dependsOn variantData.generateApkDataTask
+ }
+ if (scope.compatibleScreensManifestTask != null) {
+ processManifestTask.dependsOn scope.compatibleScreensManifestTask.name
+ }
+
+ processManifestTask.variantConfiguration = config
+ if (variantOutputData instanceof ApkVariantOutputData) {
+ processManifestTask.variantOutputData =
+ variantOutputData as ApkVariantOutputData
+ }
+
+ ConventionMappingHelper.map(processManifestTask, "libraries") {
+ List<ManifestDependencyImpl> manifests =
+ getManifestDependencies(config.directLibraries)
+
+ if (variantData.generateApkDataTask != null &&
+ variantData.getVariantConfiguration().getBuildType().
+ isEmbedMicroApp()) {
+ manifests.add(new ManifestDependencyImpl(
+ variantData.generateApkDataTask.getManifestFile(), []))
+ }
+
+ if (scope.compatibleScreensManifestTask != null) {
+ manifests.add(new ManifestDependencyImpl(
+ scope.getCompatibleScreensManifestFile(), []))
+ }
+
+ return manifests
+ }
+
+ ConventionMappingHelper.map(processManifestTask, "minSdkVersion") {
+ if (scope.globalScope.androidBuilder.isPreviewTarget()) {
+ return scope.globalScope.androidBuilder.getTargetCodename()
+ }
+
+ config.mergedFlavor.minSdkVersion?.apiString
+ }
+
+ ConventionMappingHelper.map(processManifestTask, "targetSdkVersion") {
+ if (scope.globalScope.androidBuilder.isPreviewTarget()) {
+ return scope.globalScope.androidBuilder.getTargetCodename()
+ }
+
+ return config.mergedFlavor.targetSdkVersion?.apiString
+ }
+
+ ConventionMappingHelper.map(processManifestTask, "maxSdkVersion") {
+ if (scope.globalScope.androidBuilder.isPreviewTarget()) {
+ return null
+ }
+
+ return config.mergedFlavor.maxSdkVersion
+ }
+
+ ConventionMappingHelper.map(processManifestTask, "manifestOutputFile") {
+ scope.getManifestOutputFile()
+ }
+
+ ConventionMappingHelper.map(processManifestTask, "reportFile") {
+ new File(
+ "${scope.getGlobalScope().getBuildDir()}/${FD_OUTPUTS}/logs/manifest-merger-${config.baseName}-report.txt")
+ }
+
+ }
+
+ @NonNull
+ private static List<ManifestDependencyImpl> getManifestDependencies(
+ List<LibraryDependency> libraries) {
+
+ List<ManifestDependencyImpl> list = Lists.newArrayListWithCapacity(libraries.size())
+
+ for (LibraryDependency lib : libraries) {
+ // get the dependencies
+ List<ManifestDependencyImpl> children = getManifestDependencies(lib.dependencies)
+ list.add(new ManifestDependencyImpl(lib.getName(), lib.manifest, children))
+ }
+
+ return list
+ }
+ }
}
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/MergeResources.groovy b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/MergeResources.groovy
index 212c6f2..3a56b00 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/MergeResources.groovy
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/MergeResources.groovy
@@ -15,7 +15,14 @@
*/
package com.android.build.gradle.tasks
+import com.android.annotations.NonNull
+import com.android.build.gradle.internal.scope.ConventionMappingHelper
+import com.android.build.gradle.internal.scope.TaskConfigAction
+import com.android.build.gradle.internal.scope.VariantScope
import com.android.build.gradle.internal.tasks.IncrementalTask
+import com.android.build.gradle.internal.variant.BaseVariantData
+import com.android.build.gradle.internal.variant.BaseVariantOutputData
+import com.android.builder.core.VariantType
import com.android.builder.png.QueuedCruncher
import com.android.ide.common.internal.PngCruncher
import com.android.ide.common.res2.FileStatus
@@ -25,6 +32,8 @@
import com.android.ide.common.res2.ResourceMerger
import com.android.ide.common.res2.ResourceSet
import com.android.sdklib.BuildToolInfo
+import com.android.sdklib.repository.FullRevision
+import com.google.common.collect.Lists
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.Optional
@@ -32,6 +41,8 @@
import org.gradle.api.tasks.ParallelizableTask
import org.gradle.api.tasks.OutputFile
+import static com.android.builder.model.AndroidProject.FD_INTERMEDIATES
+
@ParallelizableTask
public class MergeResources extends IncrementalTask {
@@ -191,4 +202,73 @@
throw new ResourceException(e.getMessage(), e)
}
}
+
+ public static class ConfigAction implements TaskConfigAction<MergeResources> {
+
+ @NonNull
+ VariantScope scope
+ @NonNull
+ String taskNamePrefix
+ @NonNull
+ File outputLocation;
+ boolean includeDependencies;
+ boolean process9Patch;
+
+ ConfigAction(VariantScope scope, String taskNamePrefix, File outputLocation,
+ boolean includeDependencies, boolean process9Patch) {
+ this.scope = scope
+ this.taskNamePrefix = taskNamePrefix
+ this.outputLocation = outputLocation
+ this.includeDependencies = includeDependencies
+ this.process9Patch = process9Patch
+
+ scope.setMergeResourceOutputDir(outputLocation)
+ }
+
+ @Override
+ String getName() {
+ return scope.getTaskName(taskNamePrefix, "Resources")
+ }
+
+ @Override
+ Class<MergeResources> getType() {
+ return MergeResources
+ }
+
+ @Override
+ void execute(MergeResources mergeResourcesTask) {
+ BaseVariantData<? extends BaseVariantOutputData> variantData = scope.variantData
+
+ mergeResourcesTask.androidBuilder = scope.globalScope.androidBuilder
+ mergeResourcesTask.incrementalFolder = new File(
+ "$scope.globalScope.buildDir/${FD_INTERMEDIATES}/incremental/" +
+ "${taskNamePrefix}Resources/${variantData.variantConfiguration.dirName}")
+
+ mergeResourcesTask.process9Patch = process9Patch
+ mergeResourcesTask.crunchPng = scope.globalScope.extension.aaptOptions.getCruncherEnabled()
+ mergeResourcesTask.normalizeResources = scope.globalScope.extension.buildToolsRevision.compareTo(new FullRevision(21, 0, 0)) < 0
+
+ ConventionMappingHelper.map(mergeResourcesTask, "useNewCruncher") { scope.globalScope.getExtension().aaptOptions.useNewCruncher }
+
+ ConventionMappingHelper.map(mergeResourcesTask, "inputResourceSets") {
+ List<File> generatedResFolders = Lists.newArrayList(
+ scope.getRenderscriptResOutputDir(),
+ scope.getGeneratedResOutputDir())
+ if (variantData.extraGeneratedResFolders != null) {
+ generatedResFolders += variantData.extraGeneratedResFolders
+ }
+ if (variantData.generateApkDataTask != null &&
+ variantData.getVariantConfiguration().getBuildType().isEmbedMicroApp()) {
+ generatedResFolders.add(variantData.generateApkDataTask.getResOutputDir())
+ }
+ variantData.variantConfiguration.getResourceSets(generatedResFolders,
+ includeDependencies)
+ }
+
+ ConventionMappingHelper.map(mergeResourcesTask, "outputDir") {
+ outputLocation ?: scope.getDefaultMergeResourcesOutputDir()
+ }
+ variantData.mergeResourcesTask = mergeResourcesTask
+ }
+ }
}
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/PackageApplication.java b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/PackageApplication.java
index 7a408f8..ffff5ae 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/PackageApplication.java
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/PackageApplication.java
@@ -242,7 +242,7 @@
@Override
public String getName() {
- return "package" + StringHelper.capitalize(scope.getVariantOutputData().getFullName());
+ return scope.getTaskName("package");
}
@Override
@@ -257,26 +257,15 @@
.getVariantOutputData();
final GradleVariantConfiguration config = scope.getVariantScope().getVariantConfiguration();
- String outputName = variantOutputData.getFullName();
- String outputBaseName = variantOutputData.getBaseName();
-
variantOutputData.packageApplicationTask = packageApp;
packageApp.setAndroidBuilder(scope.getGlobalScope().getAndroidBuilder());
if (config.isMinifyEnabled() && config.getBuildType().isShrinkResources() && !config
.getUseJack()) {
- final ShrinkResources shrinkTask = createShrinkResourcesTask(variantOutputData);
-
- // When shrinking resources, rather than having the packaging task
- // directly map to the packageOutputFile of ProcessAndroidResources,
- // we insert the ShrinkResources task into the chain, such that its
- // input is the ProcessAndroidResources packageOutputFile, and its
- // output is what the PackageApplication task reads.
- packageApp.dependsOn(shrinkTask);
ConventionMappingHelper.map(packageApp, "resourceFile", new Callable<File>() {
@Override
public File call() {
- return shrinkTask.getCompressedResources();
+ return scope.getCompressedResourceFile();
}
});
} else {
@@ -291,14 +280,17 @@
ConventionMappingHelper.map(packageApp, "dexFolder", new Callable<File>() {
@Override
public File call() {
- if (variantData.dexTask != null) {
- return variantData.dexTask.getOutputFolder();
+ if (scope.getVariantScope().getDexTask() != null) {
+ return scope.getVariantScope().getDexOutputFolder();
+ }
+
+ if (scope.getVariantScope().getJavaCompileTask() != null) {
+ return scope.getVariantScope().getJavaOutputDir();
}
if (variantData.javaCompileTask != null) {
return variantData.javaCompileTask.getDestinationDir();
}
-
return null;
}
});
@@ -414,7 +406,9 @@
}
});
- task.dependsOn(variantData.obfuscationTask, variantOutputData.manifestProcessorTask,
+ task.dependsOn(
+ scope.getVariantScope().getObfuscationTask().getName(),
+ scope.getManifestProcessorTask().getName(),
variantOutputData.processResourcesTask);
return task;
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/PreDex.groovy b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/PreDex.groovy
index a0bd84a..0f3b5ba 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/PreDex.groovy
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/PreDex.groovy
@@ -16,9 +16,18 @@
package com.android.build.gradle.tasks
import com.android.SdkConstants
import com.android.annotations.NonNull
+import com.android.build.gradle.internal.TaskManager
+import com.android.build.gradle.internal.scope.ConventionMappingHelper
+import com.android.build.gradle.internal.scope.TaskConfigAction
+import com.android.build.gradle.internal.scope.VariantScope
import com.android.build.gradle.internal.tasks.BaseTask
+import com.android.build.gradle.internal.variant.ApkVariantData
+import com.android.build.gradle.internal.variant.TestVariantData
import com.android.builder.core.AndroidBuilder
import com.android.builder.core.DexOptions
+import com.android.builder.core.VariantConfiguration
+import com.android.builder.core.VariantType
+import com.android.builder.model.AndroidProject
import com.android.ide.common.internal.WaitableExecutor
import com.google.common.base.Charsets
import com.google.common.collect.Lists
@@ -37,6 +46,8 @@
import java.util.concurrent.Callable
+import static com.android.builder.model.AndroidProject.FD_INTERMEDIATES
+
@ParallelizableTask
public class PreDex extends BaseTask {
@@ -192,4 +203,47 @@
return new File(outFolder, name + "-" + hashCode.toString() + SdkConstants.DOT_JAR)
}
+
+ public static class ConfigAction implements TaskConfigAction<PreDex> {
+
+ VariantScope scope;
+
+ TaskManager.PostCompilationData pcData
+
+ ConfigAction(VariantScope scope, TaskManager.PostCompilationData pcData) {
+ this.scope = scope
+ this.pcData = pcData
+ }
+
+ @Override
+ String getName() {
+ return scope.getTaskName("preDex")
+ }
+
+ @Override
+ Class<PreDex> getType() {
+ return PreDex.class
+ }
+
+ @Override
+ void execute(PreDex preDexTask) {
+ ApkVariantData variantData = (ApkVariantData) scope.variantData;
+ VariantConfiguration config = variantData.variantConfiguration
+
+ boolean isTestForApp = config.type.isForTesting() &&
+ (variantData as TestVariantData).testedVariantData.variantConfiguration.type ==
+ VariantType.DEFAULT
+ boolean isMultiDexEnabled = config.isMultiDexEnabled() && !isTestForApp
+
+ variantData.preDexTask = preDexTask
+ preDexTask.androidBuilder = scope.globalScope.androidBuilder
+ preDexTask.dexOptions = scope.globalScope.getExtension().dexOptions
+ preDexTask.multiDex = isMultiDexEnabled
+
+ ConventionMappingHelper.map(preDexTask, "inputFiles", pcData.inputLibraries)
+ ConventionMappingHelper.map(preDexTask, "outputFolder") {
+ scope.getPreDexOutputDir();
+ }
+ }
+ }
}
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/ProcessAndroidResources.groovy b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/ProcessAndroidResources.groovy
index 18ed77a..dae7a52 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/ProcessAndroidResources.groovy
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/ProcessAndroidResources.groovy
@@ -15,11 +15,23 @@
*/
package com.android.build.gradle.tasks
+import com.android.annotations.NonNull
+import com.android.build.gradle.internal.LoggingUtil
import com.android.build.gradle.internal.dependency.SymbolFileProviderImpl
import com.android.build.gradle.internal.dsl.AaptOptions
+import com.android.build.gradle.internal.scope.ConventionMappingHelper
+import com.android.build.gradle.internal.scope.TaskConfigAction
+import com.android.build.gradle.internal.scope.VariantOutputScope
import com.android.build.gradle.internal.tasks.IncrementalTask
+import com.android.build.gradle.internal.variant.BaseVariantData
+import com.android.build.gradle.internal.variant.BaseVariantOutputData
import com.android.builder.core.AaptPackageProcessBuilder
+import com.android.builder.core.VariantConfiguration
import com.android.builder.core.VariantType
+import com.android.builder.dependency.LibraryDependency
+import com.google.common.collect.Iterators
+import com.google.common.collect.Lists
+import org.gradle.api.logging.Logging
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputDirectory
import org.gradle.api.tasks.InputFile
@@ -29,6 +41,9 @@
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.ParallelizableTask
+import static com.android.builder.model.AndroidProject.FD_GENERATED
+import static com.android.builder.model.AndroidProject.FD_INTERMEDIATES
+
@ParallelizableTask
public class ProcessAndroidResources extends IncrementalTask {
@@ -144,4 +159,145 @@
aaptPackageCommandBuilder,
getEnforceUniquePackageName())
}
+
+ public static class ConfigAction implements TaskConfigAction<ProcessAndroidResources> {
+
+ VariantOutputScope scope;
+ File symbolLocation;
+ boolean generateResourcePackage;
+
+ ConfigAction(VariantOutputScope scope, File symbolLocation, generateResourcePackage) {
+ this.scope = scope
+ this.symbolLocation = symbolLocation
+ this.generateResourcePackage = generateResourcePackage
+ }
+
+ @Override
+ String getName() {
+ return scope.getTaskName("process", "Resources")
+ }
+
+ @Override
+ Class<ProcessAndroidResources> getType() {
+ return ProcessAndroidResources.class;
+ }
+
+ @Override
+ void execute(ProcessAndroidResources processResources) {
+ BaseVariantOutputData variantOutputData = scope.variantOutputData
+ BaseVariantData variantData = scope.variantScope.variantData
+ variantOutputData.processResourcesTask = processResources
+ VariantConfiguration config = variantData.getVariantConfiguration()
+
+ processResources.androidBuilder = scope.globalScope.androidBuilder
+
+ if (variantData.getSplitHandlingPolicy() ==
+ BaseVariantData.SplitHandlingPolicy.RELEASE_21_AND_AFTER_POLICY) {
+ Set<String> allFilters = new HashSet<>();
+ allFilters.addAll(variantData.getFilters(com.android.build.OutputFile.FilterType.DENSITY))
+ allFilters.addAll(variantData.getFilters(com.android.build.OutputFile.FilterType.LANGUAGE))
+ processResources.splits = allFilters;
+ }
+
+ // only generate code if the density filter is null, and if we haven't generated
+ // it yet (if you have abi + density splits, then several abi output will have no
+ // densityFilter)
+ if (variantOutputData.getMainOutputFile().getFilter(com.android.build.OutputFile.DENSITY) == null
+ && variantData.generateRClassTask == null) {
+ variantData.generateRClassTask = processResources
+ processResources.enforceUniquePackageName = scope.globalScope.getExtension().getEnforceUniquePackageName()
+
+ ConventionMappingHelper.map(processResources, "libraries") {
+ getTextSymbolDependencies(config.allLibraries)
+ }
+ ConventionMappingHelper.map(processResources, "packageForR") {
+ config.originalApplicationId
+ }
+
+ // TODO: unify with generateBuilderConfig, compileAidl, and library packaging somehow?
+ ConventionMappingHelper.map(processResources, "sourceOutputDir") {
+ scope.getVariantScope().getRClassSourceOutputDir();
+ }
+
+ ConventionMappingHelper.map(processResources, "textSymbolOutputDir") {
+ symbolLocation
+ }
+
+ if (config.buildType.isMinifyEnabled()) {
+ if (config.buildType.shrinkResources && config.useJack) {
+ LoggingUtil.displayWarning(Logging.getLogger(this.class), scope.globalScope.project,
+ "shrinkResources does not yet work with useJack=true")
+ }
+ ConventionMappingHelper.map(processResources, "proguardOutputFile") {
+ new File(
+ "$scope.globalScope.buildDir/${FD_INTERMEDIATES}/proguard-rules/${config.dirName}/aapt_rules.txt")
+ }
+ } else if (config.buildType.shrinkResources) {
+ LoggingUtil.displayWarning(Logging.getLogger(this.class), scope.globalScope.project,
+ "To shrink resources you must also enable ProGuard")
+ }
+ }
+
+ ConventionMappingHelper.map(processResources, "manifestFile") {
+ variantOutputData.manifestProcessorTask.getOutputFile()
+ }
+
+ ConventionMappingHelper.map(processResources, "resDir") {
+ variantData.finalResourcesDir
+ }
+
+ ConventionMappingHelper.map(processResources, "assetsDir") {
+ variantData.mergeAssetsTask.outputDir
+ }
+
+ if (generateResourcePackage) {
+ ConventionMappingHelper.map(processResources, "packageOutputFile") {
+ scope.getProcessResourcePackageOutputFile()
+ }
+ }
+
+ ConventionMappingHelper.map(processResources, "type") { config.type }
+ ConventionMappingHelper.map(processResources, "debuggable") { config.buildType.debuggable }
+ ConventionMappingHelper.map(processResources, "aaptOptions") { scope.globalScope.getExtension().aaptOptions }
+ ConventionMappingHelper.map(processResources, "pseudoLocalesEnabled") { config.buildType.pseudoLocalesEnabled }
+
+ ConventionMappingHelper.map(processResources, "resourceConfigs") {
+ Collection<String> resConfigs = config.mergedFlavor.resourceConfigurations;
+ if (resConfigs != null && resConfigs.size() == 1
+ && Iterators.getOnlyElement(resConfigs.iterator()).equals("auto")) {
+
+ return variantData.discoverListOfResourceConfigs();
+ }
+ return config.mergedFlavor.resourceConfigurations
+ }
+
+ ConventionMappingHelper.map(processResources, "preferredDensity") {
+ variantOutputData.getMainOutputFile().getFilter(com.android.build.OutputFile.DENSITY)
+ }
+
+ }
+
+ private static <T> Set<T> removeAllNullEntries(Set<T> input) {
+ HashSet<T> output = new HashSet<T>();
+ for (T element : input) {
+ if (element != null) {
+ output.add(element);
+ }
+ }
+ return output;
+ }
+
+ @NonNull
+ private static List<SymbolFileProviderImpl> getTextSymbolDependencies(
+ List<LibraryDependency> libraries) {
+
+ List<SymbolFileProviderImpl> list = Lists.newArrayListWithCapacity(libraries.size())
+
+ for (LibraryDependency lib : libraries) {
+ list.add(new SymbolFileProviderImpl(lib.manifest, lib.symbolFile))
+ }
+
+ return list
+ }
+ }
}
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/ProcessManifest.groovy b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/ProcessManifest.groovy
index 9bf6e4f..e738598 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/ProcessManifest.groovy
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/ProcessManifest.groovy
@@ -16,7 +16,15 @@
package com.android.build.gradle.tasks
+import com.android.build.gradle.internal.TaskManager
+import com.android.build.gradle.internal.scope.ConventionMappingHelper
+import com.android.build.gradle.internal.scope.TaskConfigAction
+import com.android.build.gradle.internal.scope.VariantScope
+import com.android.build.gradle.internal.variant.BaseVariantOutputData
+import com.android.builder.core.AndroidBuilder
import com.android.builder.core.VariantConfiguration
+import com.android.builder.model.AndroidProject
+import com.android.builder.model.ProductFlavor
import com.android.manifmerger.ManifestMerger2
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFile
@@ -99,4 +107,71 @@
variantConfiguration.getManifestPlaceholders(),
getReportFile())
}
+
+ public static class ConfigAction implements TaskConfigAction<ProcessManifest> {
+
+ VariantScope scope
+
+ ConfigAction(VariantScope scope) {
+ this.scope = scope
+ }
+
+ @Override
+ String getName() {
+ return scope.getTaskName("process", "Manifest")
+ }
+
+ @Override
+ Class<ProcessManifest> getType() {
+ return ProcessManifest
+ }
+
+ @Override
+ void execute(ProcessManifest processManifest) {
+ VariantConfiguration config = scope.variantConfiguration
+ AndroidBuilder androidBuilder = scope.globalScope.androidBuilder
+
+ // get single output for now.
+ BaseVariantOutputData variantOutputData = scope.variantData.outputs.get(0)
+
+ variantOutputData.manifestProcessorTask = processManifest
+ processManifest.androidBuilder = androidBuilder
+
+ processManifest.variantConfiguration = config
+
+ ProductFlavor mergedFlavor = config.mergedFlavor
+
+ ConventionMappingHelper.map(processManifest, "minSdkVersion") {
+ if (androidBuilder.isPreviewTarget()) {
+ return androidBuilder.getTargetCodename()
+ }
+ return mergedFlavor.minSdkVersion?.apiString
+ }
+
+ ConventionMappingHelper.map(processManifest, "targetSdkVersion") {
+ if (androidBuilder.isPreviewTarget()) {
+ return androidBuilder.getTargetCodename()
+ }
+
+ return mergedFlavor.targetSdkVersion?.apiString
+ }
+
+ ConventionMappingHelper.map(processManifest, "maxSdkVersion") {
+ if (androidBuilder.isPreviewTarget()) {
+ return null
+ }
+
+ return mergedFlavor.maxSdkVersion
+ }
+
+ ConventionMappingHelper.map(processManifest, "manifestOutputFile") {
+ variantOutputData.getScope().getManifestOutputFile()
+ }
+
+ ConventionMappingHelper.map(processManifest, "aaptFriendlyManifestOutputFile") {
+ new File(scope.globalScope.getIntermediatesDir(),
+ "$TaskManager.DIR_BUNDLES/${config.dirName}/aapt/AndroidManifest.xml")
+ }
+ }
+ }
}
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/ProcessTestManifest.groovy b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/ProcessTestManifest.groovy
index d0ce6c5..0144816 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/ProcessTestManifest.groovy
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/ProcessTestManifest.groovy
@@ -15,7 +15,15 @@
*/
package com.android.build.gradle.tasks
+import com.android.build.gradle.internal.DependencyManager
import com.android.build.gradle.internal.dependency.ManifestDependencyImpl
+import com.android.build.gradle.internal.scope.ConventionMappingHelper
+import com.android.build.gradle.internal.scope.TaskConfigAction
+import com.android.build.gradle.internal.scope.VariantOutputScope
+import com.android.build.gradle.internal.scope.VariantScope
+import com.android.build.gradle.internal.variant.BaseVariantOutputData
+import com.android.builder.core.VariantConfiguration
+import com.android.builder.model.AndroidProject
import com.google.common.collect.Lists
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFile
@@ -98,4 +106,84 @@
getManifestOutputFile(),
getTmpDir())
}
+
+ // ----- ConfigAction -----
+
+
+ public static class ConfigAction implements TaskConfigAction<ProcessTestManifest> {
+
+ VariantScope scope
+
+ ConfigAction(VariantScope scope) {
+ this.scope = scope
+ }
+
+ @Override
+ String getName() {
+ return scope.getTaskName("process", "Manifest")
+ }
+
+ @Override
+ Class<ProcessTestManifest> getType() {
+ return ProcessTestManifest
+ }
+
+ @Override
+ void execute(ProcessTestManifest processTestManifestTask) {
+
+ VariantConfiguration config = scope.variantConfiguration
+ ConventionMappingHelper.map(processTestManifestTask, "testManifestFile") {
+ config.getMainManifest()
+ }
+ ConventionMappingHelper.map(processTestManifestTask, "tmpDir") {
+ new File(scope.globalScope.getIntermediatesDir(), "manifest/tmp")
+ }
+
+ // get single output for now.
+ BaseVariantOutputData variantOutputData = scope.variantData.outputs.get(0)
+
+ variantOutputData.manifestProcessorTask = processTestManifestTask
+
+ processTestManifestTask.androidBuilder = scope.globalScope.androidBuilder
+
+ ConventionMappingHelper.map(processTestManifestTask, "testApplicationId") {
+ config.applicationId
+ }
+ ConventionMappingHelper.map(processTestManifestTask, "minSdkVersion") {
+ if (scope.globalScope.androidBuilder.isPreviewTarget()) {
+ return scope.globalScope.androidBuilder.getTargetCodename()
+ }
+
+ config.minSdkVersion?.apiString
+ }
+ ConventionMappingHelper.map(processTestManifestTask, "targetSdkVersion") {
+ if (scope.globalScope.androidBuilder.isPreviewTarget()) {
+ return scope.globalScope.androidBuilder.getTargetCodename()
+ }
+
+ return config.targetSdkVersion?.apiString
+ }
+ ConventionMappingHelper.map(processTestManifestTask, "testedApplicationId") {
+ config.testedApplicationId
+ }
+ ConventionMappingHelper.map(processTestManifestTask, "instrumentationRunner") {
+ config.instrumentationRunner
+ }
+ ConventionMappingHelper.map(processTestManifestTask, "handleProfiling") {
+ config.handleProfiling
+ }
+ ConventionMappingHelper.map(processTestManifestTask, "functionalTest") {
+ config.functionalTest
+ }
+ ConventionMappingHelper.map(processTestManifestTask, "libraries") {
+ DependencyManager.getManifestDependencies(config.directLibraries)
+ }
+ ConventionMappingHelper.map(processTestManifestTask, "manifestOutputFile") {
+ variantOutputData.getScope().getManifestOutputFile()
+ }
+ ConventionMappingHelper.map(processTestManifestTask, "placeholdersValues") {
+ config.getManifestPlaceholders()
+ }
+ }
+ }
}
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/RenderscriptCompile.groovy b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/RenderscriptCompile.groovy
index 2dac216..6946fad 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/RenderscriptCompile.groovy
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/RenderscriptCompile.groovy
@@ -16,12 +16,28 @@
package com.android.build.gradle.tasks
+import com.android.annotations.NonNull
+import com.android.build.gradle.internal.core.GradleVariantConfiguration
+import com.android.build.gradle.internal.scope.ConventionMappingHelper
+import com.android.build.gradle.internal.scope.TaskConfigAction
+import com.android.build.gradle.internal.scope.VariantOutputScope
+import com.android.build.gradle.internal.scope.VariantScope
import com.android.build.gradle.internal.tasks.NdkTask
+import com.android.build.gradle.internal.variant.BaseVariantData
+import com.android.build.gradle.internal.variant.BaseVariantOutputData
+import com.android.builder.core.VariantConfiguration
+import com.android.builder.model.AndroidProject
+import com.android.builder.model.ApiVersion
+import com.android.builder.model.ProductFlavor
+import com.android.sdklib.SdkVersionInfo
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
+import static com.android.builder.model.AndroidProject.FD_GENERATED
+import static com.android.builder.model.AndroidProject.FD_INTERMEDIATES
+
/**
* Task to compile Renderscript files. Supports incremental update.
*/
@@ -103,4 +119,78 @@
getSupportMode(),
getNdkConfig()?.abiFilters)
}
+
+ // ----- ConfigAction -----
+
+ public static class ConfigAction implements TaskConfigAction<RenderscriptCompile> {
+
+ @NonNull
+ VariantScope scope
+
+ ConfigAction(VariantScope scope) {
+ this.scope = scope
+ }
+
+ @Override
+ String getName() {
+ return scope.getTaskName("compile", "Renderscript");
+ }
+
+ @Override
+ Class<RenderscriptCompile> getType() {
+ return RenderscriptCompile
+ }
+
+ @Override
+ void execute(RenderscriptCompile renderscriptTask) {
+ BaseVariantData<? extends BaseVariantOutputData> variantData = scope.variantData
+ GradleVariantConfiguration config = variantData.variantConfiguration
+
+ variantData.renderscriptCompileTask = renderscriptTask
+ ProductFlavor mergedFlavor = config.mergedFlavor
+ boolean ndkMode = config.renderscriptNdkModeEnabled
+ renderscriptTask.androidBuilder = scope.globalScope.androidBuilder
+
+ ConventionMappingHelper.map(renderscriptTask, "targetApi") {
+ int targetApi = mergedFlavor.renderscriptTargetApi != null ?
+ mergedFlavor.renderscriptTargetApi : -1
+ ApiVersion apiVersion = config.getMinSdkVersion()
+ if (apiVersion != null) {
+ int minSdk = apiVersion.apiLevel
+ if (apiVersion.codename != null) {
+ minSdk = SdkVersionInfo.getApiByBuildCode(apiVersion.codename, true)
+ }
+
+ return targetApi > minSdk ? targetApi : minSdk
+ }
+
+ return targetApi
+ }
+
+ renderscriptTask.supportMode = config.renderscriptSupportModeEnabled
+ renderscriptTask.ndkMode = ndkMode
+ renderscriptTask.debugBuild = config.buildType.renderscriptDebuggable
+ renderscriptTask.optimLevel = config.buildType.renderscriptOptimLevel
+
+ ConventionMappingHelper.map(renderscriptTask, "sourceDirs") { config.renderscriptSourceList }
+ ConventionMappingHelper.map(renderscriptTask, "importDirs") { config.renderscriptImports }
+
+ ConventionMappingHelper.map(renderscriptTask, "sourceOutputDir") {
+ new File(
+ "$scope.globalScope.buildDir/${FD_GENERATED}/source/rs/${variantData.variantConfiguration.dirName}")
+ }
+ ConventionMappingHelper.map(renderscriptTask, "resOutputDir") {
+ scope.getRenderscriptResOutputDir()
+ }
+ ConventionMappingHelper.map(renderscriptTask, "objOutputDir") {
+ new File(
+ "$scope.globalScope.buildDir/${FD_INTERMEDIATES}/rs/${variantData.variantConfiguration.dirName}/obj")
+ }
+ ConventionMappingHelper.map(renderscriptTask, "libOutputDir") {
+ new File(
+ "$scope.globalScope.buildDir/${FD_INTERMEDIATES}/rs/${variantData.variantConfiguration.dirName}/lib")
+ }
+ ConventionMappingHelper.map(renderscriptTask, "ndkConfig") { config.ndkConfig }
+ }
+ }
}
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/ShrinkResources.groovy b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/ShrinkResources.groovy
index 944e916..c45c5db 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/ShrinkResources.groovy
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/ShrinkResources.groovy
@@ -16,15 +16,27 @@
package com.android.build.gradle.tasks
+import com.android.build.gradle.internal.scope.ConventionMappingHelper
+import com.android.build.gradle.internal.scope.TaskConfigAction
+import com.android.build.gradle.internal.scope.VariantOutputScope
import com.android.build.gradle.internal.tasks.BaseTask
+import com.android.build.gradle.internal.variant.ApkVariantOutputData
+import com.android.build.gradle.internal.variant.BaseVariantData
import com.android.build.gradle.internal.variant.BaseVariantOutputData
import com.android.builder.core.AaptPackageProcessBuilder
+import com.android.builder.model.AndroidProject
+import com.android.utils.StringHelper
+import org.codehaus.groovy.runtime.StringGroovyMethods
import org.gradle.api.logging.LogLevel
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.ParallelizableTask
import org.gradle.api.tasks.TaskAction
+import java.util.concurrent.Callable
+
+import static com.android.builder.model.AndroidProject.FD_INTERMEDIATES
+
/**
* Task which strips out unused resources
* <p>
@@ -170,4 +182,42 @@
private static String toKbString(long size) {
return Integer.toString((int)size/1024);
}
+
+ public static class ConfigAction implements TaskConfigAction<ShrinkResources> {
+
+ private VariantOutputScope scope;
+
+ public ConfigAction(VariantOutputScope scope) {
+ this.scope = scope;
+ }
+
+ @Override
+ String getName() {
+ return scope.getTaskName("shrink", "Resources");
+ }
+
+ @Override
+ Class<ShrinkResources> getType() {
+ return ShrinkResources.class
+ }
+
+ @Override
+ void execute(ShrinkResources task) {
+ BaseVariantData<? extends BaseVariantOutputData> variantData =
+ scope.variantScope.variantData
+ task.setAndroidBuilder(scope.getGlobalScope().getAndroidBuilder());
+ task.variantOutputData = scope.variantOutputData;
+
+ final String outputBaseName = scope.variantOutputData.getBaseName();
+ task.setCompressedResources(scope.getCompressedResourceFile());
+
+ ConventionMappingHelper.map(task, "uncompressedResources", new Callable<File>() {
+ @Override
+ public File call() {
+ return scope.variantOutputData.processResourcesTask.getPackageOutputFile();
+ }
+ });
+
+ }
+ }
}
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/ZipAlign.java b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/ZipAlign.java
index ea43e8f..15e910e 100644
--- a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/ZipAlign.java
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/ZipAlign.java
@@ -97,7 +97,7 @@
@Override
public String getName() {
- return "zipalign" + StringHelper.capitalize(scope.getVariantOutputData().getFullName());
+ return scope.getTaskName("zipalign");
}
@Override
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/factory/JavaCompileConfigAction.java b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/factory/JavaCompileConfigAction.java
new file mode 100644
index 0000000..502937b
--- /dev/null
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/factory/JavaCompileConfigAction.java
@@ -0,0 +1,191 @@
+package com.android.build.gradle.tasks.factory;
+
+import static com.android.builder.core.VariantType.LIBRARY;
+import static com.android.builder.core.VariantType.UNIT_TEST;
+import static com.android.builder.model.AndroidProject.FD_INTERMEDIATES;
+
+import com.android.build.gradle.internal.CompileOptions;
+import com.android.build.gradle.internal.scope.ConventionMappingHelper;
+import com.android.build.gradle.internal.scope.TaskConfigAction;
+import com.android.build.gradle.internal.scope.VariantScope;
+import com.android.build.gradle.internal.variant.BaseVariantData;
+import com.android.sdklib.AndroidTargetHash;
+import com.android.sdklib.AndroidVersion;
+
+import org.codehaus.groovy.runtime.DefaultGroovyMethods;
+import org.gradle.api.Action;
+import org.gradle.api.JavaVersion;
+import org.gradle.api.Task;
+import org.gradle.api.file.FileCollection;
+import org.gradle.api.tasks.compile.AbstractCompile;
+import org.gradle.api.tasks.compile.JavaCompile;
+
+import java.io.File;
+
+import groovy.lang.Closure;
+
+/**
+ * Configuration Action for a JavaCompile task.
+ */
+public class JavaCompileConfigAction implements TaskConfigAction<JavaCompile> {
+
+ private VariantScope scope;
+
+ public JavaCompileConfigAction(VariantScope scope) {
+ this.scope = scope;
+ }
+
+ @Override
+ public String getName() {
+ return scope.getTaskName("compile", "Java");
+ }
+
+ @Override
+ public Class<JavaCompile> getType() {
+ return JavaCompile.class;
+ }
+
+ @Override
+ public void execute(final JavaCompile javaCompileTask) {
+ final BaseVariantData testedVariantData = scope.getTestedVariantData();
+ scope.getVariantData().javaCompileTask = javaCompileTask;
+
+ javaCompileTask.setSource(scope.getVariantData().getJavaSources());
+
+ ConventionMappingHelper
+ .map(javaCompileTask, "classpath", new Closure<FileCollection>(this, this) {
+ public FileCollection doCall(Object it) {
+ FileCollection classpath = scope.getJavaClasspath();
+
+ if (testedVariantData != null) {
+ // For libraries, the classpath from androidBuilder includes the library output
+ // (bundle/classes.jar) as a normal dependency. In unit tests we don't want to package
+ // the jar at every run, so we use the *.class files instead.
+ if (!testedVariantData.getType().equals(LIBRARY) || scope
+ .getVariantData().getType().equals(UNIT_TEST)) {
+ classpath = classpath
+ .plus(testedVariantData.getScope().getJavaClasspath())
+ .plus(scope.getGlobalScope().getProject().files(
+ testedVariantData.getScope().getJavaOutputDir(),
+ testedVariantData.getScope().getJavaDependencyCache()));
+ }
+
+ if (scope.getVariantData().getType().equals(UNIT_TEST)
+ && testedVariantData.getType().equals(LIBRARY)) {
+ // The bundled classes.jar may exist, but it's probably old. Don't use it, we
+ // already have the *.class files in the classpath.
+ classpath = classpath.minus(scope.getGlobalScope().getProject()
+ .files(testedVariantData.getVariantConfiguration()
+ .getOutput().getJarFile()));
+ }
+
+ }
+
+ return classpath;
+ }
+
+ public FileCollection doCall() {
+ return doCall(null);
+ }
+
+ });
+
+ ConventionMappingHelper
+ .map(javaCompileTask, "destinationDir", new Closure<File>(this, this) {
+ public File doCall(Object it) {
+ return scope.getJavaOutputDir();
+ }
+
+ public File doCall() {
+ return doCall(null);
+ }
+
+ });
+ ConventionMappingHelper
+ .map(javaCompileTask, "dependencyCacheDir", new Closure<File>(this, this) {
+ public File doCall(Object it) {
+ return scope.getJavaDependencyCache();
+ }
+
+ public File doCall() {
+ return doCall(null);
+ }
+
+ });
+
+ configureLanguageLevel(javaCompileTask);
+ javaCompileTask.getOptions().setEncoding(
+ scope.getGlobalScope().getExtension().getCompileOptions().getEncoding());
+
+ // setup the boot classpath just before the task actually runs since this will
+ // force the sdk to be parsed.
+ javaCompileTask.doFirst(new Closure<String>(this, this) {
+ public String doCall(Task it) {
+ return setBootClasspath(javaCompileTask.getOptions(), DefaultGroovyMethods
+ .join(scope.getGlobalScope().getAndroidBuilder()
+ .getBootClasspathAsStrings(), File.pathSeparator));
+ }
+
+ public String doCall() {
+ return doCall(null);
+ }
+
+ });
+ }
+
+ private void configureLanguageLevel(AbstractCompile compileTask) {
+ final CompileOptions compileOptions = scope.getGlobalScope().getExtension()
+ .getCompileOptions();
+ JavaVersion javaVersionToUse;
+
+ final AndroidVersion hash = AndroidTargetHash
+ .getVersionFromHash(scope.getGlobalScope().getExtension().getCompileSdkVersion());
+ Integer compileSdkLevel = (hash == null ? null : hash.getApiLevel());
+ if (compileSdkLevel == null || (0 <= compileSdkLevel && compileSdkLevel <= 20)) {
+ javaVersionToUse = JavaVersion.VERSION_1_6;
+ } else {
+ javaVersionToUse = JavaVersion.VERSION_1_7;
+ }
+
+ JavaVersion jdkVersion = JavaVersion
+ .toVersion(System.getProperty("java.specification.version"));
+ if (jdkVersion.compareTo(javaVersionToUse) < 0) {
+// logger.info(
+// "Default language level for 'compileSdkVersion $compileSdkLevel' is " +
+// "$javaVersionToUse, but the JDK used is $jdkVersion, so the JDK " +
+// "language level will be used.")
+ javaVersionToUse = jdkVersion;
+ }
+
+ compileOptions.setDefaultJavaVersion(javaVersionToUse);
+
+ ConventionMappingHelper
+ .map(compileTask, "sourceCompatibility", new Closure<String>(this, this) {
+ public String doCall(Object it) {
+ return compileOptions.getSourceCompatibility().toString();
+ }
+
+ public String doCall() {
+ return doCall(null);
+ }
+
+ });
+ ConventionMappingHelper
+ .map(compileTask, "targetCompatibility", new Closure<String>(this, this) {
+ public String doCall(Object it) {
+ return compileOptions.getTargetCompatibility().toString();
+ }
+
+ public String doCall() {
+ return doCall(null);
+ }
+
+ });
+ }
+
+ private static <Value extends String> Value setBootClasspath(
+ org.gradle.api.tasks.compile.CompileOptions propOwner, Value bootClasspath) {
+ propOwner.setBootClasspath(bootClasspath);
+ return bootClasspath;
+ }
+}
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/factory/ProGuardTaskConfigAction.java b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/factory/ProGuardTaskConfigAction.java
new file mode 100644
index 0000000..bb366d8
--- /dev/null
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/factory/ProGuardTaskConfigAction.java
@@ -0,0 +1,98 @@
+package com.android.build.gradle.tasks.factory;
+
+import static com.android.builder.model.AndroidProject.FD_INTERMEDIATES;
+
+import com.android.build.gradle.internal.TaskManager;
+import com.android.build.gradle.internal.scope.TaskConfigAction;
+import com.android.build.gradle.internal.scope.VariantScope;
+import com.android.utils.StringHelper;
+import com.google.common.base.Preconditions;
+
+import org.codehaus.groovy.runtime.StringGroovyMethods;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+import groovy.lang.Closure;
+import proguard.ParseException;
+import proguard.gradle.ProGuardTask;
+
+/**
+ * Configuration Action for a ProGuardTask task.
+ */
+public class ProGuardTaskConfigAction implements TaskConfigAction<ProGuardTask> {
+
+ private VariantScope scope;
+
+ private Closure<List<File>> inputFiles;
+
+ public ProGuardTaskConfigAction(VariantScope scope, TaskManager.PostCompilationData pcData) {
+ this.scope = scope;
+ this.inputFiles = pcData.getInputFiles();
+ }
+
+ @Override
+ public String getName() {
+ return scope.getTaskName("shrink", "MultiDexComponents");
+ }
+
+ @Override
+ public Class<ProGuardTask> getType() {
+ return ProGuardTask.class;
+ }
+
+ @Override
+ public void execute(ProGuardTask proguardComponentsTask) {
+ proguardComponentsTask.dontobfuscate();
+ proguardComponentsTask.dontoptimize();
+ proguardComponentsTask.dontpreverify();
+ proguardComponentsTask.dontwarn();
+ proguardComponentsTask.forceprocessing();
+
+ try {
+ proguardComponentsTask.configuration(scope.getManifestKeepListFile());
+
+ proguardComponentsTask.libraryjars(new Closure<File>(this, this) {
+ public File doCall(Object it) {
+ Preconditions.checkNotNull(
+ scope.getGlobalScope().getAndroidBuilder().getTargetInfo());
+ File shrinkedAndroid = new File(
+ scope.getGlobalScope().getAndroidBuilder().getTargetInfo()
+ .getBuildTools()
+ .getLocation(),
+ "lib" + File.separatorChar + "shrinkedAndroid.jar");
+
+ // TODO remove in 1.0
+ // STOPSHIP
+ if (!shrinkedAndroid.isFile()) {
+ shrinkedAndroid = new File(
+ scope.getGlobalScope().getAndroidBuilder().getTargetInfo()
+ .getBuildTools().getLocation(),
+ "multidex" + File.separatorChar + "shrinkedAndroid.jar");
+ }
+
+ return shrinkedAndroid;
+ }
+
+ public File doCall() {
+ return doCall(null);
+ }
+
+ });
+
+ proguardComponentsTask.injars(inputFiles.call().iterator().next());
+
+ proguardComponentsTask.outjars(scope.getProguardComponentsJarFile());
+
+ proguardComponentsTask.printconfiguration(
+ scope.getGlobalScope().getBuildDir() + "/" + FD_INTERMEDIATES
+ + "/multi-dex/" + scope.getVariantConfiguration().getDirName()
+ + "/components.flags");
+ } catch (ParseException e) {
+ throw new RuntimeException(e);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/factory/ProcessJavaResConfigAction.groovy b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/factory/ProcessJavaResConfigAction.groovy
new file mode 100644
index 0000000..d6cbc0f
--- /dev/null
+++ b/build-system/gradle-core/src/main/groovy/com/android/build/gradle/tasks/factory/ProcessJavaResConfigAction.groovy
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2015 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.build.gradle.tasks.factory
+
+import com.android.build.gradle.api.AndroidSourceSet
+import com.android.build.gradle.internal.scope.ConventionMappingHelper
+import com.android.build.gradle.internal.scope.TaskConfigAction
+import com.android.build.gradle.internal.scope.VariantScope
+import com.android.builder.core.BuilderConstants
+import com.android.builder.core.VariantType
+import com.android.builder.model.AndroidProject
+import com.android.builder.model.SourceProvider
+import org.gradle.api.tasks.Copy
+
+import static com.android.builder.core.VariantType.ANDROID_TEST
+import static com.android.builder.model.AndroidProject.FD_INTERMEDIATES
+
+/**
+ * Configuration Action for a ProcessJavaRes task.
+ */
+class ProcessJavaResConfigAction implements TaskConfigAction<Copy> {
+
+ VariantScope scope;
+
+ ProcessJavaResConfigAction(VariantScope scope) {
+ this.scope = scope
+ }
+
+ @Override
+ String getName() {
+ return scope.getTaskName("process", "JavaRes");
+ }
+
+ @Override
+ Class<Copy> getType() {
+ return Copy.class
+ }
+
+ @Override
+ void execute(Copy processResources) {
+ scope.variantData.processJavaResourcesTask = processResources
+
+ // set the input
+ processResources.from(((AndroidSourceSet) scope.variantConfiguration.defaultSourceSet).resources.
+ getSourceFiles())
+
+ if (scope.variantConfiguration.type != ANDROID_TEST) {
+ processResources.from(
+ ((AndroidSourceSet) scope.variantConfiguration.buildTypeSourceSet).resources.
+ getSourceFiles())
+ }
+ if (scope.variantConfiguration.hasFlavors()) {
+ for (SourceProvider flavorSourceSet : scope.variantConfiguration.flavorSourceProviders) {
+ processResources.
+ from(((AndroidSourceSet) flavorSourceSet).resources.getSourceFiles())
+ }
+ }
+
+ ConventionMappingHelper.map(processResources, "destinationDir") {
+ scope.getJavaResourcesDestinationDir()
+ }
+
+ }
+}
diff --git a/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/model/BaseComponentModelPlugin.groovy b/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/model/BaseComponentModelPlugin.groovy
index 5f93c51..ef9857b 100644
--- a/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/model/BaseComponentModelPlugin.groovy
+++ b/build-system/gradle-experimental/src/main/groovy/com/android/build/gradle/model/BaseComponentModelPlugin.groovy
@@ -39,6 +39,7 @@
import com.android.build.gradle.internal.model.ModelBuilder
import com.android.build.gradle.internal.process.GradleJavaProcessExecutor
import com.android.build.gradle.internal.process.GradleProcessExecutor
+import com.android.build.gradle.internal.profile.RecordingBuildListener
import com.android.build.gradle.internal.tasks.DependencyReportTask
import com.android.build.gradle.internal.tasks.SigningReportTask
import com.android.build.gradle.internal.variant.VariantFactory
@@ -49,6 +50,10 @@
import com.android.builder.core.BuilderConstants
import com.android.builder.internal.compiler.JackConversionCache
import com.android.builder.internal.compiler.PreDexCache
+import com.android.builder.profile.ExecutionType
+import com.android.builder.profile.ProcessRecorderFactory
+import com.android.builder.profile.Recorder
+import com.android.builder.profile.ThreadRecorder
import com.android.builder.sdk.TargetInfo
import com.android.ide.common.internal.ExecutorSingleton
import com.android.ide.common.process.LoggedProcessOutputHandler
@@ -109,6 +114,10 @@
*/
@Override
public void apply(Project project) {
+ ProcessRecorderFactory.initialize(new LoggerWrapper(project.logger), project.rootProject.
+ file("profiler" + System.currentTimeMillis() + ".json"))
+ project.gradle.addListener(new RecordingBuildListener(ThreadRecorder.get()));
+
project.apply plugin: AndroidComponentModelPlugin
project.apply plugin: JavaBasePlugin
@@ -132,7 +141,6 @@
"default-mapping",
"Metadata for published APKs")
-
project.tasks.getByName("assemble").description =
"Assembles all variants of all applications and secondary packages."
@@ -376,8 +384,6 @@
}
}
- taskManager.createLintCompileTask();
-
// TODO: determine how to provide functionalities of variant API objects.
}
@@ -388,12 +394,20 @@
BinaryContainer binaries,
AndroidComponentSpec spec,
TaskManager taskManager) {
+
VariantManager variantManager = (spec as DefaultAndroidComponentSpec).variantManager
binaries.withType(AndroidBinary) { androidBinary ->
- DefaultAndroidBinary binary = androidBinary as DefaultAndroidBinary
- variantManager.createTasksForVariantData(
- new TaskCollectionBuilderAdaptor(tasks),
- binary.variantData)
+ ThreadRecorder.get().record(ExecutionType.VARIANT_MANAGER_CREATE_TASKS_FOR_VARIANT,
+ new Recorder.Block<Void>() {
+ @Override
+ public Void call() throws Exception {
+ DefaultAndroidBinary binary = androidBinary as DefaultAndroidBinary
+ variantManager.createTasksForVariantData(
+ new TaskCollectionBuilderAdaptor(tasks),
+ binary.variantData)
+ return null;
+ }
+ });
}
}
@@ -407,11 +421,6 @@
AndroidComponentSpec spec) {
VariantManager variantManager = (spec as DefaultAndroidComponentSpec).variantManager
- // create the lint tasks.
- taskManager.createLintTasks(
- new TaskCollectionBuilderAdaptor(tasks),
- variantManager.variantDataList);
-
// create the test tasks.
taskManager.createTopLevelTestTasks (
new TaskCollectionBuilderAdaptor(tasks),
diff --git a/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/common/fixture/app/VariantBuildScriptGenerator.java b/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/common/fixture/app/VariantBuildScriptGenerator.java
index 1d926c2..7cf61e6dc 100644
--- a/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/common/fixture/app/VariantBuildScriptGenerator.java
+++ b/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/common/fixture/app/VariantBuildScriptGenerator.java
@@ -15,7 +15,7 @@
*/
public class VariantBuildScriptGenerator {
- public static final Integer LARGE_NUMBER = 15;
+ public static final Integer LARGE_NUMBER = 20;
public static final Integer MEDIUM_NUMBER = 5;
diff --git a/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/component/BasicNdkComponentTest.groovy b/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/component/BasicNdkComponentTest.groovy
index e5f2ca5..154a7bb 100644
--- a/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/component/BasicNdkComponentTest.groovy
+++ b/build-system/integration-test/src/test/groovy/com/android/build/gradle/integration/component/BasicNdkComponentTest.groovy
@@ -27,6 +27,8 @@
import java.util.zip.ZipFile
+import static com.android.build.gradle.integration.common.truth.TruthHelper.assertThatApk
+import static com.android.build.gradle.integration.common.truth.TruthHelper.assertThatZip
import static org.junit.Assert.assertNotNull
/**
@@ -78,11 +80,11 @@
project.execute("assembleRelease");
// Verify .so are built for all platform.
- ZipFile apk = new ZipFile(project.getApk("release", "unsigned"));
- assertNotNull(apk.getEntry("lib/x86/libhello-jni.so"));
- assertNotNull(apk.getEntry("lib/mips/libhello-jni.so"));
- assertNotNull(apk.getEntry("lib/armeabi/libhello-jni.so"));
- assertNotNull(apk.getEntry("lib/armeabi-v7a/libhello-jni.so"));
+ File apk = project.getApk("release", "unsigned");
+ assertThatZip(apk).contains("lib/x86/libhello-jni.so");
+ assertThatZip(apk).contains("lib/mips/libhello-jni.so");
+ assertThatZip(apk).contains("lib/armeabi/libhello-jni.so");
+ assertThatZip(apk).contains("lib/armeabi-v7a/libhello-jni.so");
}
@Test
@@ -90,19 +92,19 @@
project.execute("assembleDebug");
// Verify .so are built for all platform.
- ZipFile apk = new ZipFile(project.getApk("debug"));
- assertNotNull(apk.getEntry("lib/x86/libhello-jni.so"));
- assertNotNull(apk.getEntry("lib/x86/gdbserver"));
- assertNotNull(apk.getEntry("lib/x86/gdb.setup"));
- assertNotNull(apk.getEntry("lib/mips/libhello-jni.so"));
- assertNotNull(apk.getEntry("lib/mips/gdbserver"));
- assertNotNull(apk.getEntry("lib/mips/gdb.setup"));
- assertNotNull(apk.getEntry("lib/armeabi/libhello-jni.so"));
- assertNotNull(apk.getEntry("lib/armeabi/gdbserver"));
- assertNotNull(apk.getEntry("lib/armeabi/gdb.setup"));
- assertNotNull(apk.getEntry("lib/armeabi-v7a/libhello-jni.so"));
- assertNotNull(apk.getEntry("lib/armeabi-v7a/gdbserver"));
- assertNotNull(apk.getEntry("lib/armeabi-v7a/gdb.setup"));
+ File apk = project.getApk("debug");
+ assertThatZip(apk).contains("lib/x86/libhello-jni.so");
+ assertThatZip(apk).contains("lib/x86/gdbserver");
+ assertThatZip(apk).contains("lib/x86/gdb.setup");
+ assertThatZip(apk).contains("lib/mips/libhello-jni.so");
+ assertThatZip(apk).contains("lib/mips/gdbserver");
+ assertThatZip(apk).contains("lib/mips/gdb.setup");
+ assertThatZip(apk).contains("lib/armeabi/libhello-jni.so");
+ assertThatZip(apk).contains("lib/armeabi/gdbserver");
+ assertThatZip(apk).contains("lib/armeabi/gdb.setup");
+ assertThatZip(apk).contains("lib/armeabi-v7a/libhello-jni.so");
+ assertThatZip(apk).contains("lib/armeabi-v7a/gdbserver");
+ assertThatZip(apk).contains("lib/armeabi-v7a/gdb.setup");
}
@Test
diff --git a/build-system/profile/src/main/java/com/android/builder/profile/ExecutionType.java b/build-system/profile/src/main/java/com/android/builder/profile/ExecutionType.java
index e6a6d07..2b495ae 100644
--- a/build-system/profile/src/main/java/com/android/builder/profile/ExecutionType.java
+++ b/build-system/profile/src/main/java/com/android/builder/profile/ExecutionType.java
@@ -56,6 +56,8 @@
APP_TASK_MANAGER_CREATE_SPLIT_TASK(1010),
APP_TASK_MANAGER_CREATE_PACKAGING_TASK(1011),
APP_TASK_MANAGER_CREATE_PREPROCESS_RESOURCES_TASK(1012),
+ APP_TASK_MANAGER_CREATE_BACKPORT_RESOURCES_TASK(1013),
+ APP_TASK_MANAGER_CREATE_LINT_TASK(1014),
// LibraryTaskManager per variant tasks.
LIB_TASK_MANAGER_CREATE_MERGE_MANIFEST_TASK(2000),
@@ -75,6 +77,7 @@
LIB_TASK_MANAGER_CREATE_PROGUARD_TASK(2014),
LIB_TASK_MANAGER_CREATE_PACKAGE_LOCAL_JAR(2015),
LIB_TASK_MANAGER_CREATE_BACKPORT_RESOURCES_TASK(2016),
+ LIB_TASK_MANAGER_CREATE_LINT_TASK(2017),
// TASK_EXECUTION
GENERIC_TASK_EXECUTION(3000),