diff options
98 files changed, 2268 insertions, 447 deletions
diff --git a/builder-model/src/main/java/com/android/builder/model/AaptOptions.java b/builder-model/src/main/java/com/android/builder/model/AaptOptions.java index 86192e0..4cb9b36 100644 --- a/builder-model/src/main/java/com/android/builder/model/AaptOptions.java +++ b/builder-model/src/main/java/com/android/builder/model/AaptOptions.java @@ -16,7 +16,7 @@ package com.android.builder.model; -import java.util.List; +import java.util.Collection; /** * Options for aapt. @@ -30,5 +30,5 @@ public interface AaptOptions { /** * Returns the list of values for the -0 (disabled compression) option, or null */ - List<String> getNoCompress(); + Collection<String> getNoCompress(); } diff --git a/builder-model/src/main/java/com/android/builder/model/ArtifactInfo.java b/builder-model/src/main/java/com/android/builder/model/AndroidArtifact.java index 5d2ba6d..3cfd2f2 100644 --- a/builder-model/src/main/java/com/android/builder/model/ArtifactInfo.java +++ b/builder-model/src/main/java/com/android/builder/model/AndroidArtifact.java @@ -20,12 +20,12 @@ import com.android.annotations.NonNull; import com.android.annotations.Nullable; import java.io.File; -import java.util.List; +import java.util.Collection; /** - * The information for a generated artifact. + * The information for a generated Android artifact. */ -public interface ArtifactInfo { +public interface AndroidArtifact extends BaseArtifact { /** * Returns the output file for this artifact. Depending on whether the project is an app @@ -73,20 +73,6 @@ public interface ArtifactInfo { String getSourceGenTaskName(); /** - * @return the name of the task used to compile Java code. - */ - @NonNull - String getJavaCompileTaskName(); - - /** - * Returns the name of the task used to generate the artifact. - * - * @return the name of the task. - */ - @NonNull - String getAssembleTaskName(); - - /** * The generated manifest for this variant's artifact. */ @NonNull @@ -99,7 +85,7 @@ public interface ArtifactInfo { * @return a list of folders. */ @NonNull - List<File> getGeneratedSourceFolders(); + Collection<File> getGeneratedSourceFolders(); /** * Returns all the resource folders that are generated. This is typically the renderscript @@ -108,22 +94,5 @@ public interface ArtifactInfo { * @return a list of folder. */ @NonNull - List<File> getGeneratedResourceFolders(); - - /** - * Returns the folder containing the class files. This is the output of the java compilation. - * - * @return a folder. - */ - @NonNull - File getClassesFolder(); - - /** - * Returns the resolved dependencies for this artifact. This is a composite of all the - * dependencies for that artifact: default config + build type + flavor(s).s - * - * @return The dependencies. - */ - @NonNull - Dependencies getDependencies(); + Collection<File> getGeneratedResourceFolders(); } diff --git a/builder-model/src/main/java/com/android/builder/model/AndroidLibrary.java b/builder-model/src/main/java/com/android/builder/model/AndroidLibrary.java index 7d7a47f..a46cb7e 100644 --- a/builder-model/src/main/java/com/android/builder/model/AndroidLibrary.java +++ b/builder-model/src/main/java/com/android/builder/model/AndroidLibrary.java @@ -20,6 +20,7 @@ import com.android.annotations.NonNull; import com.android.annotations.Nullable; import java.io.File; +import java.util.Collection; import java.util.List; /** @@ -49,7 +50,7 @@ public interface AndroidLibrary { File getFolder(); /** - * Returns the direct dependency of this dependency. + * Returns the direct dependency of this dependency. The order is important. */ @NonNull List<? extends AndroidLibrary> getLibraryDependencies(); @@ -74,7 +75,7 @@ public interface AndroidLibrary { * @return a list of File. May be empty but not null. */ @NonNull - List<File> getLocalJars(); + Collection<File> getLocalJars(); /** * Returns the location of the res folder. diff --git a/builder-model/src/main/java/com/android/builder/model/AndroidProject.java b/builder-model/src/main/java/com/android/builder/model/AndroidProject.java index a63f16c..f1118f4 100644 --- a/builder-model/src/main/java/com/android/builder/model/AndroidProject.java +++ b/builder-model/src/main/java/com/android/builder/model/AndroidProject.java @@ -20,8 +20,6 @@ import com.android.annotations.NonNull; import java.io.File; import java.util.Collection; -import java.util.List; -import java.util.Map; /** * Entry point for the model of the Android Projects. This models a single module, whether @@ -30,6 +28,9 @@ import java.util.Map; public interface AndroidProject { String BUILD_MODEL_ONLY_SYSTEM_PROPERTY = "android.build.model.only"; + public static final String ARTIFACT_MAIN = "_main_"; + public static final String ARTIFACT_INSTRUMENT_TEST = "_instrument_test_"; + /** * Returns the model version. This is a string in the format X.Y.Z * @@ -61,34 +62,39 @@ public interface AndroidProject { ProductFlavorContainer getDefaultConfig(); /** - * Returns a map of all the {@link BuildType} in their container. The key is the build type - * name as returned by {@link BuildType#getName()} + * Returns a list of all the {@link BuildType} in their container. * - * @return a map of build type containers. + * @return a list of build type containers. */ @NonNull - Map<String, BuildTypeContainer> getBuildTypes(); + Collection<BuildTypeContainer> getBuildTypes(); /** - * Returns a map of all the {@link ProductFlavor} in their container. The key is the product - * flavor name as returned by {@link ProductFlavor#getName()} + * Returns a list of all the {@link ProductFlavor} in their container. * - * @return a map of product flavor containers. + * @return a list of product flavor containers. */ @NonNull - Map<String, ProductFlavorContainer> getProductFlavors(); + Collection<ProductFlavorContainer> getProductFlavors(); /** - * Returns a map of all the variants. The key is the variant name as returned by - * {@link Variant#getName()}. + * Returns a list of all the variants. + * + * This does not include test variant. Test variants are additional artifacts in their + * respective variant info. * - * This does not include test variant. Instead the variant and its component each contribute - * their test part. + * @return a list of the variants. + */ + @NonNull + Collection<Variant> getVariants(); + + /** + * Returns a list of extra artifacts meta data. This does not include the main artifact. * - * @return a map of the variants. + * @return a list of extra artifacts */ @NonNull - Map<String, Variant> getVariants(); + Collection<ArtifactMetaData> getExtraArtifacts(); /** * Returns the compilation target as a string. This is the full extended target hash string. @@ -106,23 +112,22 @@ public interface AndroidProject { * @return a list of jar files. */ @NonNull - List<String> getBootClasspath(); + Collection<String> getBootClasspath(); /** * Returns a list of folders or jar files that contains the framework source code. * @return a list of folders or jar files that contains the framework source code. */ @NonNull - List<File> getFrameworkSource(); + Collection<File> getFrameworkSources(); /** - * Returns a map of {@link SigningConfig}. The key is the signing config name as returned by - * {@link SigningConfig#getName()} + * Returns a list of {@link SigningConfig}. * * @return a map of signing config */ @NonNull - Map<String, SigningConfig> getSigningConfigs(); + Collection<SigningConfig> getSigningConfigs(); /** * Returns the aapt options. diff --git a/builder-model/src/main/java/com/android/builder/model/ArtifactMetaData.java b/builder-model/src/main/java/com/android/builder/model/ArtifactMetaData.java new file mode 100644 index 0000000..f1af029 --- /dev/null +++ b/builder-model/src/main/java/com/android/builder/model/ArtifactMetaData.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.builder.model; + +import com.android.annotations.NonNull; + +/** + * Meta Data for an Artifact. + */ +public interface ArtifactMetaData { + + public final static int TYPE_ANDROID = 1; + public final static int TYPE_JAVA = 2; + + @NonNull + String getName(); + + boolean isTest(); + + int getType(); +} diff --git a/builder-model/src/main/java/com/android/builder/model/BaseArtifact.java b/builder-model/src/main/java/com/android/builder/model/BaseArtifact.java new file mode 100644 index 0000000..fd1a7b7 --- /dev/null +++ b/builder-model/src/main/java/com/android/builder/model/BaseArtifact.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.builder.model; + +import com.android.annotations.NonNull; +import com.android.annotations.Nullable; + +import java.io.File; + +/** + * The base information for all generated artifacts + */ +public interface BaseArtifact { + + /** + * Name of the artifact. This should match {@link ArtifactMetaData#getName()}. + */ + @NonNull + String getName(); + + /** + * @return the name of the task used to compile Java code. + */ + @NonNull + String getJavaCompileTaskName(); + + /** + * Returns the name of the task used to generate the artifact. + * + * @return the name of the task. + */ + @NonNull + String getAssembleTaskName(); + + /** + * Returns the folder containing the class files. This is the output of the java compilation. + * + * @return a folder. + */ + @NonNull + File getClassesFolder(); + + /** + * Returns the resolved dependencies for this artifact. This is a composite of all the + * dependencies for that artifact: default config + build type + flavor(s).s + * + * @return The dependencies. + */ + @NonNull + Dependencies getDependencies(); + + /** + * A SourceProvider specific to the variant. This can be null if there is no flavors as + * the "variant" is equal to the build type. + * + * @return the variant specific source provider + */ + @Nullable + SourceProvider getVariantSourceProvider(); + + /** + * A SourceProvider specific to the flavor combination. + * + * For instance if there are 2 dimensions, then this would be Flavor1Flavor2, and would be + * common to all variant using these two flavors and any of the build type. + * + * This can be null if there is less than 2 flavors. + * + * @return the multi flavor specific source provider + */ + @Nullable + SourceProvider getMultiFlavorSourceProvider(); +} diff --git a/builder-model/src/main/java/com/android/builder/model/BaseConfig.java b/builder-model/src/main/java/com/android/builder/model/BaseConfig.java index 713b344..d4e22c1 100644 --- a/builder-model/src/main/java/com/android/builder/model/BaseConfig.java +++ b/builder-model/src/main/java/com/android/builder/model/BaseConfig.java @@ -19,7 +19,7 @@ package com.android.builder.model; import com.android.annotations.NonNull; import java.io.File; -import java.util.List; +import java.util.Collection; /** * Base config object for Build Type and Product flavor. @@ -31,7 +31,7 @@ public interface BaseConfig { * @return a non-null list of class fields (possibly empty) */ @NonNull - List<ClassField> getBuildConfigFields(); + Collection<ClassField> getBuildConfigFields(); /** * Returns the list of proguard rule files. @@ -39,7 +39,7 @@ public interface BaseConfig { * @return a non-null list of files. */ @NonNull - List<File> getProguardFiles(); + Collection<File> getProguardFiles(); /** * Returns the list of proguard rule files for consumers of the library to use. @@ -47,5 +47,5 @@ public interface BaseConfig { * @return a non-null list of files. */ @NonNull - List<File> getConsumerProguardFiles(); + Collection<File> getConsumerProguardFiles(); } diff --git a/builder-model/src/main/java/com/android/builder/model/BuildType.java b/builder-model/src/main/java/com/android/builder/model/BuildType.java index d846a90..9bdc6dc 100644 --- a/builder-model/src/main/java/com/android/builder/model/BuildType.java +++ b/builder-model/src/main/java/com/android/builder/model/BuildType.java @@ -18,7 +18,6 @@ package com.android.builder.model; import com.android.annotations.NonNull; import com.android.annotations.Nullable; -import com.android.builder.NdkConfig; /** * a Build Type. This is only the configuration of the build type. @@ -27,7 +26,7 @@ import com.android.builder.NdkConfig; * or in the artifact info. * * @see BuildTypeContainer - * @see ArtifactInfo#getDependencies() + * @see AndroidArtifact#getDependencies() */ public interface BuildType extends BaseConfig { @@ -70,7 +69,7 @@ public interface BuildType extends BaseConfig { /** * Returns the package name suffix applied to this build type. - * To get the final package name, use {@link ArtifactInfo#getPackageName()}. + * To get the final package name, use {@link AndroidArtifact#getPackageName()}. * * @return the package name suffix. */ diff --git a/builder-model/src/main/java/com/android/builder/model/BuildTypeContainer.java b/builder-model/src/main/java/com/android/builder/model/BuildTypeContainer.java index 4a0170d..87765f1 100644 --- a/builder-model/src/main/java/com/android/builder/model/BuildTypeContainer.java +++ b/builder-model/src/main/java/com/android/builder/model/BuildTypeContainer.java @@ -18,6 +18,8 @@ package com.android.builder.model; import com.android.annotations.NonNull; +import java.util.Collection; + /** * A Container of all the data related to {@link BuildType}. */ @@ -38,4 +40,12 @@ public interface BuildTypeContainer { */ @NonNull SourceProvider getSourceProvider(); + + /** + * Returns a list of ArtifactMetaData/SourceProvider association. + * + * @return a list of ArtifactMetaData/SourceProvider association. + */ + @NonNull + Collection<SourceProviderContainer> getExtraSourceProviders(); } diff --git a/builder-model/src/main/java/com/android/builder/model/Dependencies.java b/builder-model/src/main/java/com/android/builder/model/Dependencies.java index b5a27d1..f28b648 100644 --- a/builder-model/src/main/java/com/android/builder/model/Dependencies.java +++ b/builder-model/src/main/java/com/android/builder/model/Dependencies.java @@ -19,10 +19,11 @@ package com.android.builder.model; import com.android.annotations.NonNull; import java.io.File; +import java.util.Collection; import java.util.List; /** - * A set of dependencies for an {@link ArtifactInfo}. + * A set of dependencies for an {@link AndroidArtifact}. */ public interface Dependencies { @@ -41,7 +42,7 @@ public interface Dependencies { * @return the list of jar files. */ @NonNull - List<File> getJars(); + Collection<File> getJars(); /** * The list of project dependencies. This is only for non Android module dependencies (which @@ -50,5 +51,5 @@ public interface Dependencies { * @return the list of projects. */ @NonNull - List<String> getProjects(); + Collection<String> getProjects(); } diff --git a/builder-model/src/main/java/com/android/builder/model/JavaArtifact.java b/builder-model/src/main/java/com/android/builder/model/JavaArtifact.java new file mode 100644 index 0000000..02cba55 --- /dev/null +++ b/builder-model/src/main/java/com/android/builder/model/JavaArtifact.java @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.builder.model; + +/** + * The information for a generated Java artifact. + */ +public interface JavaArtifact extends BaseArtifact { + +} diff --git a/builder-model/src/main/java/com/android/builder/NdkConfig.java b/builder-model/src/main/java/com/android/builder/model/NdkConfig.java index fbebf49..c750001 100644 --- a/builder-model/src/main/java/com/android/builder/NdkConfig.java +++ b/builder-model/src/main/java/com/android/builder/model/NdkConfig.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package com.android.builder; +package com.android.builder.model; import com.android.annotations.Nullable; -import java.util.Set; +import java.util.Collection; /** * Base class for NDK config file. @@ -41,13 +41,13 @@ public interface NdkConfig { * The LD Libs */ @Nullable - public Set<String> getLdLibs(); + public Collection<String> getLdLibs(); /** * The ABI Filters */ @Nullable - public Set<String> getAbiFilters(); + public Collection<String> getAbiFilters(); @Nullable public String getStl(); diff --git a/builder-model/src/main/java/com/android/builder/model/ProductFlavor.java b/builder-model/src/main/java/com/android/builder/model/ProductFlavor.java index 9563136..6f8d4af 100644 --- a/builder-model/src/main/java/com/android/builder/model/ProductFlavor.java +++ b/builder-model/src/main/java/com/android/builder/model/ProductFlavor.java @@ -18,7 +18,6 @@ package com.android.builder.model; import com.android.annotations.NonNull; import com.android.annotations.Nullable; -import com.android.builder.NdkConfig; /** * a Product Flavor. This is only the configuration of the flavor. @@ -27,7 +26,7 @@ import com.android.builder.NdkConfig; * or in the artifact info. * * @see ProductFlavorContainer - * @see ArtifactInfo#getDependencies() + * @see BaseArtifact#getDependencies() */ public interface ProductFlavor extends BaseConfig { @@ -41,7 +40,7 @@ public interface ProductFlavor extends BaseConfig { /** * Returns the name of the product flavor. This is only the value set on this product flavor. - * To get the final package name, use {@link ArtifactInfo#getPackageName()}. + * To get the final package name, use {@link AndroidArtifact#getPackageName()}. * * @return the package name. */ @@ -95,7 +94,7 @@ public interface ProductFlavor extends BaseConfig { /** * Returns the test package name. This is only the value set on this product flavor. * To get the final value, use {@link Variant#getTestArtifactInfo()} and - * {@link ArtifactInfo#getPackageName()} + * {@link AndroidArtifact#getPackageName()} * * @return the test package name. */ diff --git a/builder-model/src/main/java/com/android/builder/model/ProductFlavorContainer.java b/builder-model/src/main/java/com/android/builder/model/ProductFlavorContainer.java index f8cc7ed..8643f9d 100644 --- a/builder-model/src/main/java/com/android/builder/model/ProductFlavorContainer.java +++ b/builder-model/src/main/java/com/android/builder/model/ProductFlavorContainer.java @@ -18,6 +18,8 @@ package com.android.builder.model; import com.android.annotations.NonNull; +import java.util.Collection; + /** * A Container of all the data related to {@link ProductFlavor}. */ @@ -40,10 +42,10 @@ public interface ProductFlavorContainer { SourceProvider getSourceProvider(); /** - * The associated test sources of the product flavor + * Returns a list of ArtifactMetaData/SourceProvider association. * - * @return the test source provider. + * @return a list of ArtifactMetaData/SourceProvider association. */ @NonNull - SourceProvider getTestSourceProvider(); + Collection<SourceProviderContainer> getExtraSourceProviders(); } diff --git a/builder-model/src/main/java/com/android/builder/model/SourceProvider.java b/builder-model/src/main/java/com/android/builder/model/SourceProvider.java index 7ed06ef..6d58e64 100644 --- a/builder-model/src/main/java/com/android/builder/model/SourceProvider.java +++ b/builder-model/src/main/java/com/android/builder/model/SourceProvider.java @@ -18,7 +18,7 @@ package com.android.builder.model; import com.android.annotations.NonNull; import java.io.File; -import java.util.Set; +import java.util.Collection; /** * Represent a SourceProvider for a given configuration. @@ -41,7 +41,7 @@ public interface SourceProvider { * @return a list of folders. They may not all exist. */ @NonNull - Set<File> getJavaDirectories(); + Collection<File> getJavaDirectories(); /** * Returns the java resources folders. @@ -49,7 +49,7 @@ public interface SourceProvider { * @return a list of folders. They may not all exist. */ @NonNull - Set<File> getResourcesDirectories(); + Collection<File> getResourcesDirectories(); /** * Returns the aidl source folders. @@ -57,7 +57,7 @@ public interface SourceProvider { * @return a list of folders. They may not all exist. */ @NonNull - Set<File> getAidlDirectories(); + Collection<File> getAidlDirectories(); /** * Returns the renderscript source folders. @@ -65,7 +65,7 @@ public interface SourceProvider { * @return a list of folders. They may not all exist. */ @NonNull - Set<File> getRenderscriptDirectories(); + Collection<File> getRenderscriptDirectories(); /** * Returns the jni source folders. @@ -73,7 +73,7 @@ public interface SourceProvider { * @return a list of folders. They may not all exist. */ @NonNull - Set<File> getJniDirectories(); + Collection<File> getJniDirectories(); /** * Returns the android resources folders. @@ -81,7 +81,7 @@ public interface SourceProvider { * @return a list of folders. They may not all exist. */ @NonNull - Set<File> getResDirectories(); + Collection<File> getResDirectories(); /** * Returns the android assets folders. @@ -89,5 +89,5 @@ public interface SourceProvider { * @return a list of folders. They may not all exist. */ @NonNull - Set<File> getAssetsDirectories(); + Collection<File> getAssetsDirectories(); } diff --git a/builder-model/src/main/java/com/android/builder/model/SourceProviderContainer.java b/builder-model/src/main/java/com/android/builder/model/SourceProviderContainer.java new file mode 100644 index 0000000..0ac8387 --- /dev/null +++ b/builder-model/src/main/java/com/android/builder/model/SourceProviderContainer.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.builder.model; + +import com.android.annotations.NonNull; + +/** + * An association of an {@link ArtifactMetaData}'s name and a {@link SourceProvider}. + */ +public interface SourceProviderContainer { + + /** + * Returns the name matching {@link ArtifactMetaData#getName()} + */ + @NonNull + String getArtifactName(); + + /** + * Returns the source provider + */ + @NonNull + SourceProvider getSourceProvider(); +} diff --git a/builder-model/src/main/java/com/android/builder/model/Variant.java b/builder-model/src/main/java/com/android/builder/model/Variant.java index 2f32c66..532901e 100644 --- a/builder-model/src/main/java/com/android/builder/model/Variant.java +++ b/builder-model/src/main/java/com/android/builder/model/Variant.java @@ -17,8 +17,8 @@ package com.android.builder.model; import com.android.annotations.NonNull; -import com.android.annotations.Nullable; +import java.util.Collection; import java.util.List; /** @@ -49,16 +49,13 @@ public interface Variant { * @return the artifact. */ @NonNull - ArtifactInfo getMainArtifactInfo(); + AndroidArtifact getMainArtifact(); - /** - * Returns the test artifact for this variant. This may be null if this particular variant - * is not configured to be tested. - * - * @return the test artifact. - */ - @Nullable - ArtifactInfo getTestArtifactInfo(); + @NonNull + Collection<AndroidArtifact> getExtraAndroidArtifacts(); + + @NonNull + Collection<JavaArtifact> getExtraJavaArtifacts(); /** * Returns the build type. All variants have a build type, so this is never null. @@ -91,13 +88,6 @@ public interface Variant { ProductFlavor getMergedFlavor(); /** - * The variant specific SourceProvider. - * @return a source provider or null - */ - @Nullable - SourceProvider getSourceProvider(); - - /** * Returns the resource configuration for this variant. * TODO implement this. * @@ -106,5 +96,5 @@ public interface Variant { * @return the resource configuration options. */ @NonNull - List<String> getResourceConfigurations(); + Collection<String> getResourceConfigurations(); } diff --git a/builder/src/main/java/com/android/builder/AndroidBuilder.java b/builder/src/main/java/com/android/builder/AndroidBuilder.java index 24ff0c8..ae94013 100644 --- a/builder/src/main/java/com/android/builder/AndroidBuilder.java +++ b/builder/src/main/java/com/android/builder/AndroidBuilder.java @@ -508,7 +508,7 @@ public class AndroidBuilder { List<File> manifests = Lists.newArrayList(); for (ManifestDependency library : directLibraries) { - List<? extends ManifestDependency> subLibraries = library.getManifestDependencies(); + Collection<? extends ManifestDependency> subLibraries = library.getManifestDependencies(); if (subLibraries.isEmpty()) { manifests.add(library.getManifest()); } else { @@ -665,7 +665,7 @@ public class AndroidBuilder { command.add(ignoreAssets); } - List<String> noCompressList = options.getNoCompress(); + Collection<String> noCompressList = options.getNoCompress(); if (noCompressList != null) { for (String noCompress : noCompressList) { command.add("-0"); diff --git a/builder/src/main/java/com/android/builder/DefaultBuildType.java b/builder/src/main/java/com/android/builder/DefaultBuildType.java index f9ed1be..63abf00 100644 --- a/builder/src/main/java/com/android/builder/DefaultBuildType.java +++ b/builder/src/main/java/com/android/builder/DefaultBuildType.java @@ -20,6 +20,7 @@ import com.android.annotations.NonNull; import com.android.annotations.Nullable; import com.android.builder.internal.BaseConfigImpl; import com.android.builder.model.BuildType; +import com.android.builder.model.NdkConfig; import com.android.builder.model.SigningConfig; import com.google.common.base.Objects; diff --git a/builder/src/main/java/com/android/builder/DefaultProductFlavor.java b/builder/src/main/java/com/android/builder/DefaultProductFlavor.java index e4f6e18..603f0d3 100644 --- a/builder/src/main/java/com/android/builder/DefaultProductFlavor.java +++ b/builder/src/main/java/com/android/builder/DefaultProductFlavor.java @@ -19,6 +19,7 @@ package com.android.builder; import com.android.annotations.NonNull; import com.android.annotations.Nullable; import com.android.builder.internal.BaseConfigImpl; +import com.android.builder.model.NdkConfig; import com.android.builder.model.ProductFlavor; import com.android.builder.model.SigningConfig; import com.google.common.base.Objects; diff --git a/builder/src/main/java/com/android/builder/VariantConfiguration.java b/builder/src/main/java/com/android/builder/VariantConfiguration.java index 7c5f6b1..4c861fe 100644 --- a/builder/src/main/java/com/android/builder/VariantConfiguration.java +++ b/builder/src/main/java/com/android/builder/VariantConfiguration.java @@ -25,6 +25,7 @@ import com.android.builder.dependency.LibraryDependency; import com.android.builder.internal.NdkConfigImpl; import com.android.builder.internal.StringHelper; import com.android.builder.model.ClassField; +import com.android.builder.model.NdkConfig; import com.android.builder.model.ProductFlavor; import com.android.builder.model.SigningConfig; import com.android.builder.model.SourceProvider; @@ -86,12 +87,14 @@ public class VariantConfiguration implements TestData { private final List<DefaultProductFlavor> mFlavorConfigs = Lists.newArrayList(); private final List<SourceProvider> mFlavorSourceProviders = Lists.newArrayList(); - /** - * Variant specific source provider, may be null - */ + /** Variant specific source provider, may be null */ @Nullable private SourceProvider mVariantSourceProvider; + /** MultiFlavors specific source provider, may be null */ + @Nullable + private SourceProvider mMultiFlavorSourceProvider; + @NonNull private final Type mType; /** Optional tested config in case type is Type#TEST */ @@ -377,7 +380,17 @@ public class VariantConfiguration implements TestData { */ public VariantConfiguration setVariantSourceProvider(@Nullable SourceProvider sourceProvider) { mVariantSourceProvider = sourceProvider; + return this; + } + /** + * Sets the variant-specific source provider. + * @param sourceProvider the source provider for the product flavor + * + * @return the config object + */ + public VariantConfiguration setMultiFlavorSourceProvider(@Nullable SourceProvider sourceProvider) { + mMultiFlavorSourceProvider = sourceProvider; return this; } @@ -390,6 +403,11 @@ public class VariantConfiguration implements TestData { return mVariantSourceProvider; } + @Nullable + public SourceProvider getMultiFlavorSourceProvider() { + return mMultiFlavorSourceProvider; + } + private void computeNdkConfig() { mMergedNdkConfig.reset(); @@ -491,8 +509,15 @@ public class VariantConfiguration implements TestData { return mFlavorConfigs; } + /** + * Returns the list of SourceProviders for the flavors. + * + * The list is ordered from higher priority to lower priority. + * + * @return the list of Source Providers for the flavors. Never null. + */ @NonNull - public Iterable<SourceProvider> getFlavorSourceSets() { + public List<SourceProvider> getFlavorSourceProviders() { return mFlavorSourceProviders; } @@ -545,10 +570,11 @@ public class VariantConfiguration implements TestData { LibraryDependency library = directDependencies.get(i); // get its libraries - List<LibraryDependency> dependencies = library.getDependencies(); + Collection<LibraryDependency> dependencies = library.getDependencies(); + List<LibraryDependency> depList = Lists.newArrayList(dependencies); // resolve the dependencies for those libraries - resolveIndirectLibraryDependencies(dependencies, outFlatDependencies); + resolveIndirectLibraryDependencies(depList, outFlatDependencies); // and add the current one (if needed) in front (higher priority) if (!outFlatDependencies.contains(library)) { @@ -838,6 +864,13 @@ public class VariantConfiguration implements TestData { } } + if (mMultiFlavorSourceProvider != null) { + File variantLocation = mMultiFlavorSourceProvider.getManifestFile(); + if (variantLocation.isFile()) { + inputs.add(variantLocation); + } + } + if (mBuildTypeSourceProvider != null) { File typeLocation = mBuildTypeSourceProvider.getManifestFile(); if (typeLocation.isFile()) { @@ -887,7 +920,7 @@ public class VariantConfiguration implements TestData { } } - Set<File> mainResDirs = mDefaultSourceProvider.getResDirectories(); + Collection<File> mainResDirs = mDefaultSourceProvider.getResDirectories(); ResourceSet resourceSet = new ResourceSet(BuilderConstants.MAIN); resourceSet.addSources(mainResDirs); @@ -900,7 +933,7 @@ public class VariantConfiguration implements TestData { for (int n = mFlavorSourceProviders.size() - 1; n >= 0 ; n--) { SourceProvider sourceProvider = mFlavorSourceProviders.get(n); - Set<File> flavorResDirs = sourceProvider.getResDirectories(); + Collection<File> flavorResDirs = sourceProvider.getResDirectories(); // we need the same of the flavor config, but it's in a different list. // This is fine as both list are parallel collections with the same number of items. resourceSet = new ResourceSet(mFlavorConfigs.get(n).getName()); @@ -910,15 +943,23 @@ public class VariantConfiguration implements TestData { // build type overrides the flavors if (mBuildTypeSourceProvider != null) { - Set<File> typeResDirs = mBuildTypeSourceProvider.getResDirectories(); + Collection<File> typeResDirs = mBuildTypeSourceProvider.getResDirectories(); resourceSet = new ResourceSet(mBuildType.getName()); resourceSet.addSources(typeResDirs); resourceSets.add(resourceSet); } + // multiflavor specific overrides flavor/build type + if (mMultiFlavorSourceProvider != null) { + Collection<File> variantResDirs = mMultiFlavorSourceProvider.getResDirectories(); + resourceSet = new ResourceSet(getFullName()); + resourceSet.addSources(variantResDirs); + resourceSets.add(resourceSet); + } + // variant specific overrides all if (mVariantSourceProvider != null) { - Set<File> variantResDirs = mVariantSourceProvider.getResDirectories(); + Collection<File> variantResDirs = mVariantSourceProvider.getResDirectories(); resourceSet = new ResourceSet(getFullName()); resourceSet.addSources(variantResDirs); resourceSets.add(resourceSet); @@ -954,7 +995,7 @@ public class VariantConfiguration implements TestData { } } - Set<File> mainResDirs = mDefaultSourceProvider.getAssetsDirectories(); + Collection<File> mainResDirs = mDefaultSourceProvider.getAssetsDirectories(); AssetSet assetSet = new AssetSet(BuilderConstants.MAIN); assetSet.addSources(mainResDirs); @@ -964,7 +1005,7 @@ public class VariantConfiguration implements TestData { for (int n = mFlavorSourceProviders.size() - 1; n >= 0 ; n--) { SourceProvider sourceProvider = mFlavorSourceProviders.get(n); - Set<File> flavorResDirs = sourceProvider.getAssetsDirectories(); + Collection<File> flavorResDirs = sourceProvider.getAssetsDirectories(); // we need the same of the flavor config, but it's in a different list. // This is fine as both list are parallel collections with the same number of items. assetSet = new AssetSet(mFlavorConfigs.get(n).getName()); @@ -974,15 +1015,23 @@ public class VariantConfiguration implements TestData { // build type overrides flavors if (mBuildTypeSourceProvider != null) { - Set<File> typeResDirs = mBuildTypeSourceProvider.getAssetsDirectories(); + Collection<File> typeResDirs = mBuildTypeSourceProvider.getAssetsDirectories(); assetSet = new AssetSet(mBuildType.getName()); assetSet.addSources(typeResDirs); assetSets.add(assetSet); } + // multiflavor specific overrides flavor/build type + if (mMultiFlavorSourceProvider != null) { + Collection<File> variantResDirs = mMultiFlavorSourceProvider.getAssetsDirectories(); + assetSet = new AssetSet(getFullName()); + assetSet.addSources(variantResDirs); + assetSets.add(assetSet); + } + // variant specific overrides all if (mVariantSourceProvider != null) { - Set<File> variantResDirs = mVariantSourceProvider.getAssetsDirectories(); + Collection<File> variantResDirs = mVariantSourceProvider.getAssetsDirectories(); assetSet = new AssetSet(getFullName()); assetSet.addSources(variantResDirs); assetSets.add(assetSet); @@ -1043,6 +1092,10 @@ public class VariantConfiguration implements TestData { } } + if (mMultiFlavorSourceProvider != null) { + sourceList.addAll(mMultiFlavorSourceProvider.getRenderscriptDirectories()); + } + if (mVariantSourceProvider != null) { sourceList.addAll(mVariantSourceProvider.getRenderscriptDirectories()); } @@ -1081,6 +1134,10 @@ public class VariantConfiguration implements TestData { } } + if (mMultiFlavorSourceProvider != null) { + sourceList.addAll(mMultiFlavorSourceProvider.getAidlDirectories()); + } + if (mVariantSourceProvider != null) { sourceList.addAll(mVariantSourceProvider.getAidlDirectories()); } @@ -1102,6 +1159,10 @@ public class VariantConfiguration implements TestData { } } + if (mMultiFlavorSourceProvider != null) { + sourceList.addAll(mMultiFlavorSourceProvider.getJniDirectories()); + } + if (mVariantSourceProvider != null) { sourceList.addAll(mVariantSourceProvider.getJniDirectories()); } diff --git a/builder/src/main/java/com/android/builder/dependency/LibraryDependency.java b/builder/src/main/java/com/android/builder/dependency/LibraryDependency.java index c143276..3649588 100644 --- a/builder/src/main/java/com/android/builder/dependency/LibraryDependency.java +++ b/builder/src/main/java/com/android/builder/dependency/LibraryDependency.java @@ -19,6 +19,7 @@ package com.android.builder.dependency; import com.android.annotations.NonNull; import com.android.builder.model.AndroidLibrary; +import java.util.Collection; import java.util.List; /** @@ -27,15 +28,15 @@ import java.util.List; public interface LibraryDependency extends AndroidLibrary, ManifestDependency, SymbolFileProvider { /** - * Returns the direct dependency of this dependency. + * Returns the direct dependency of this dependency. The order is important */ @NonNull List<LibraryDependency> getDependencies(); /** - * Returns the list of local Jar files that are included in the dependency. + * Returns the collection of local Jar files that are included in the dependency. * @return a list of JarDependency. May be empty but not null. */ @NonNull - List<JarDependency> getLocalDependencies(); + Collection<JarDependency> getLocalDependencies(); } diff --git a/builder/src/main/java/com/android/builder/internal/NdkConfigImpl.java b/builder/src/main/java/com/android/builder/internal/NdkConfigImpl.java index 153d702..b455a0a 100644 --- a/builder/src/main/java/com/android/builder/internal/NdkConfigImpl.java +++ b/builder/src/main/java/com/android/builder/internal/NdkConfigImpl.java @@ -18,7 +18,7 @@ package com.android.builder.internal; import com.android.annotations.NonNull; import com.android.annotations.Nullable; -import com.android.builder.NdkConfig; +import com.android.builder.model.NdkConfig; import com.google.common.collect.Sets; import java.util.Set; diff --git a/changelog.txt b/changelog.txt index b5809d6..3915ffe 100644 --- a/changelog.txt +++ b/changelog.txt @@ -5,8 +5,10 @@ (note the camelcase naming, with lower case for first letter). Its components (res, manifest, etc...) have higher priority than components from build type or flavors. - It also comes with dependency configuration, so you can do - flavorDebugCompile '...' + There is also a "flavor combination" source folder available when more than one + flavor dimension is used. + For instance src/flavor1Flavor2/ + Note that this is for all combinations of *all* dimensions. - Build config improvements and DSL changes. The previous DSL proprety: buildConfigLine "<value>" @@ -26,6 +28,8 @@ variant.registerJavaGeneratingTask(task, sourceFolder1, sourceFolders2,...) This automatically adds the dependency on the task, sets up the JavaCompile task inputs and propagates the folders to the model for IDE integration. +- API to add extra artifacts on variants. This will allow to register Java or Android artifacts, for instance + for alternative test artifacts. 0.6.3 - Fixed ClassNotFoundException:MergingException introduced in 0.6.2 diff --git a/gradle-model/src/test/java/com/android/build/gradle/model/AndroidProjectTest.java b/gradle-model/src/test/java/com/android/build/gradle/model/AndroidProjectTest.java index cee947a..dc44dc8 100644 --- a/gradle-model/src/test/java/com/android/build/gradle/model/AndroidProjectTest.java +++ b/gradle-model/src/test/java/com/android/build/gradle/model/AndroidProjectTest.java @@ -17,16 +17,21 @@ package com.android.build.gradle.model; import com.android.annotations.NonNull; +import com.android.annotations.Nullable; +import com.android.builder.internal.StringHelper; +import com.android.builder.model.AndroidArtifact; import com.android.builder.model.AndroidLibrary; import com.android.builder.model.AndroidProject; -import com.android.builder.model.ArtifactInfo; +import com.android.builder.model.ArtifactMetaData; import com.android.builder.model.BuildTypeContainer; import com.android.builder.model.Dependencies; +import com.android.builder.model.JavaArtifact; import com.android.builder.model.JavaCompileOptions; import com.android.builder.model.ProductFlavor; import com.android.builder.model.ProductFlavorContainer; import com.android.builder.model.SigningConfig; import com.android.builder.model.SourceProvider; +import com.android.builder.model.SourceProviderContainer; import com.android.builder.model.Variant; import com.android.builder.signing.KeystoreHelper; import com.android.prefs.AndroidLocation; @@ -42,10 +47,11 @@ import java.net.URISyntaxException; import java.net.URL; import java.security.CodeSource; import java.security.KeyStore; -import java.util.List; +import java.util.Collection; import java.util.Locale; import java.util.Map; -import java.util.Set; + +import static com.android.builder.model.AndroidProject.ARTIFACT_INSTRUMENT_TEST; public class AndroidProjectTest extends TestCase { @@ -168,17 +174,90 @@ public class AndroidProjectTest extends TestCase { AndroidProject model = projectData.model; File projectDir = projectData.projectDir; + testDefaultSourceSets(model, projectDir); + + // test the source provider for the artifacts + for (Variant variant : model.getVariants()) { + AndroidArtifact artifact = variant.getMainArtifact(); + assertNull(artifact.getVariantSourceProvider()); + assertNull(artifact.getMultiFlavorSourceProvider()); + } + } + + public void testBasicMultiFlavorsSourceProviders() throws Exception { + // Load the custom model for the project + ProjectData projectData = getModelForProject("basicMultiFlavors"); + + AndroidProject model = projectData.model; + File projectDir = projectData.projectDir; + + testDefaultSourceSets(model, projectDir); + + // test the source provider for the flavor + Collection<ProductFlavorContainer> productFlavors = model.getProductFlavors(); + assertEquals("Product Flavor Count", 4, productFlavors.size()); + + for (ProductFlavorContainer pfContainer : productFlavors) { + String name = pfContainer.getProductFlavor().getName(); + new SourceProviderTester( + model.getName(), + projectDir, + name, + pfContainer.getSourceProvider()) + .test(); + + assertEquals(1, pfContainer.getExtraSourceProviders().size()); + SourceProviderContainer container = getSourceProviderContainer( + pfContainer.getExtraSourceProviders(), ARTIFACT_INSTRUMENT_TEST); + assertNotNull(container); + + new SourceProviderTester( + model.getName(), + projectDir, + "instrumentTest" + StringHelper.capitalize(name), + container.getSourceProvider()) + .test(); + } + + // test the source provider for the artifacts + for (Variant variant : model.getVariants()) { + AndroidArtifact artifact = variant.getMainArtifact(); + assertNotNull(artifact.getVariantSourceProvider()); + assertNotNull(artifact.getMultiFlavorSourceProvider()); + } + } + + private void testDefaultSourceSets(@NonNull AndroidProject model, @NonNull File projectDir) { ProductFlavorContainer defaultConfig = model.getDefaultConfig(); + // test the main source provider new SourceProviderTester(model.getName(), projectDir, "main", defaultConfig.getSourceProvider()) .test(); + + // test the main instrumentTest source provider + SourceProviderContainer testSourceProviders = getSourceProviderContainer( + defaultConfig.getExtraSourceProviders(), ARTIFACT_INSTRUMENT_TEST); + assertNotNull("InstrumentTest source Providers null-check", testSourceProviders); + new SourceProviderTester(model.getName(), projectDir, - "instrumentTest", defaultConfig.getTestSourceProvider()) - .test(); + "instrumentTest", testSourceProviders.getSourceProvider()) + .test(); - Map<String, BuildTypeContainer> buildTypes = model.getBuildTypes(); + // test the source provider for the build types + Collection<BuildTypeContainer> buildTypes = model.getBuildTypes(); assertEquals("Build Type Count", 2, buildTypes.size()); + + for (BuildTypeContainer btContainer : model.getBuildTypes()) { + new SourceProviderTester( + model.getName(), + projectDir, + btContainer.getBuildType().getName(), + btContainer.getSourceProvider()) + .test(); + + assertEquals(0, btContainer.getExtraSourceProviders().size()); + } } public void testBasicVariantDetails() throws Exception { @@ -187,11 +266,11 @@ public class AndroidProjectTest extends TestCase { AndroidProject model = projectData.model; - Map<String, Variant> variants = model.getVariants(); + Collection<Variant> variants = model.getVariants(); assertEquals("Variant Count", 2 , variants.size()); // debug variant - Variant debugVariant = variants.get("debug"); + Variant debugVariant = getVariant(variants, "debug"); assertNotNull("debug Variant null-check", debugVariant); new ProductFlavorTester(debugVariant.getMergedFlavor(), "Debug Merged Flavor") .setVersionCode(12) @@ -201,9 +280,9 @@ public class AndroidProjectTest extends TestCase { .setTestInstrumentationRunner("android.test.InstrumentationTestRunner") .setTestHandleProfiling(Boolean.FALSE) .setTestFunctionalTest(null) - .test(); + .test(); - ArtifactInfo debugMainInfo = debugVariant.getMainArtifactInfo(); + AndroidArtifact debugMainInfo = debugVariant.getMainArtifact(); assertNotNull("Debug main info null-check", debugMainInfo); assertEquals("Debug package name", "com.android.tests.basic.debug", debugMainInfo.getPackageName()); @@ -212,8 +291,12 @@ public class AndroidProjectTest extends TestCase { assertEquals("Debug sourceGenTask", "generateDebugSources", debugMainInfo.getSourceGenTaskName()); assertEquals("Debug javaCompileTask", "compileDebugJava", debugMainInfo.getJavaCompileTaskName()); + Collection<AndroidArtifact> debugExtraAndroidArtifacts = debugVariant.getExtraAndroidArtifacts(); + + // this variant is tested. - ArtifactInfo debugTestInfo = debugVariant.getTestArtifactInfo(); + AndroidArtifact debugTestInfo = getAndroidArtifact(debugExtraAndroidArtifacts, + ARTIFACT_INSTRUMENT_TEST); assertNotNull("Test info null-check", debugTestInfo); assertEquals("Test package name", "com.android.tests.basic.debug.test", debugTestInfo.getPackageName()); @@ -224,10 +307,10 @@ public class AndroidProjectTest extends TestCase { assertEquals("Test javaCompileTask", "compileDebugTestJava", debugTestInfo.getJavaCompileTaskName()); // release variant, not tested. - Variant releaseVariant = variants.get("release"); + Variant releaseVariant = getVariant(variants, "release"); assertNotNull("release Variant null-check", releaseVariant); - ArtifactInfo relMainInfo = releaseVariant.getMainArtifactInfo(); + AndroidArtifact relMainInfo = releaseVariant.getMainArtifact(); assertNotNull("Release main info null-check", relMainInfo); assertEquals("Release package name", "com.android.tests.basic", relMainInfo.getPackageName()); @@ -236,7 +319,8 @@ public class AndroidProjectTest extends TestCase { assertEquals("Release sourceGenTask", "generateReleaseSources", relMainInfo.getSourceGenTaskName()); assertEquals("Release javaCompileTask", "compileReleaseJava", relMainInfo.getJavaCompileTaskName()); - ArtifactInfo relTestInfo = releaseVariant.getTestArtifactInfo(); + Collection<AndroidArtifact> releaseExtraAndroidArtifacts = releaseVariant.getExtraAndroidArtifacts(); + AndroidArtifact relTestInfo = getAndroidArtifact(releaseExtraAndroidArtifacts, ARTIFACT_INSTRUMENT_TEST); assertNull("Release test info null-check", relTestInfo); // check debug dependencies @@ -245,7 +329,7 @@ public class AndroidProjectTest extends TestCase { assertEquals(2, dependencies.getJars().size()); assertEquals(1, dependencies.getLibraries().size()); - AndroidLibrary lib = dependencies.getLibraries().get(0); + AndroidLibrary lib = dependencies.getLibraries().iterator().next(); assertNotNull(lib); assertNotNull(lib.getBundle()); assertNotNull(lib.getFolder()); @@ -259,12 +343,16 @@ public class AndroidProjectTest extends TestCase { AndroidProject model = projectData.model; - assertEquals("Number of signingConfig", 2, model.getSigningConfigs().size()); + Collection<SigningConfig> signingConfigs = model.getSigningConfigs(); + assertNotNull("SigningConfigs null-check", signingConfigs); + assertEquals("Number of signingConfig", 2, signingConfigs.size()); - SigningConfig debugSigningConfig = model.getSigningConfigs().get("debug"); + SigningConfig debugSigningConfig = getSigningConfig(signingConfigs, "debug"); + assertNotNull("debug signing config null-check", debugSigningConfig); new SigningConfigTester(debugSigningConfig, "debug", true).test(); - SigningConfig mySigningConfig = model.getSigningConfigs().get("myConfig"); + SigningConfig mySigningConfig = getSigningConfig(signingConfigs, "myConfig"); + assertNotNull("myConfig signing config null-check", mySigningConfig); new SigningConfigTester(mySigningConfig, "myConfig", true) .setStoreFile(new File(projectData.projectDir, "debug.keystore")) .test(); @@ -294,8 +382,12 @@ public class AndroidProjectTest extends TestCase { .setManifestFile("AndroidManifest.xml") .test(); + SourceProviderContainer testSourceProviderContainer = getSourceProviderContainer( + defaultConfig.getExtraSourceProviders(), ARTIFACT_INSTRUMENT_TEST); + assertNotNull("InstrumentTest source Providers null-check", testSourceProviderContainer); + new SourceProviderTester(model.getName(), projectDir, - "instrumentTest", defaultConfig.getTestSourceProvider()) + "instrumentTest", testSourceProviderContainer.getSourceProvider()) .setJavaDir("tests/java") .setResourcesDir("tests/resources") .setAidlDir("tests/aidl") @@ -317,13 +409,13 @@ public class AndroidProjectTest extends TestCase { assertNotNull("Model Object null-check", model); assertEquals("Model Name", "renamedApk", model.getName()); - Map<String, Variant> variants = model.getVariants(); + Collection<Variant> variants = model.getVariants(); assertEquals("Variant Count", 2 , variants.size()); File buildDir = new File(projectDir, "build"); - for (Variant variant : variants.values()) { - ArtifactInfo mainInfo = variant.getMainArtifactInfo(); + for (Variant variant : variants) { + AndroidArtifact mainInfo = variant.getMainArtifact(); assertNotNull( "Null-check on mainArtifactInfo for " + variant.getDisplayName(), mainInfo); @@ -350,17 +442,22 @@ public class AndroidProjectTest extends TestCase { new SourceProviderTester(model.getName(), projectDir, "main", defaultConfig.getSourceProvider()) .test(); + + SourceProviderContainer testSourceProviderContainer = getSourceProviderContainer( + defaultConfig.getExtraSourceProviders(), ARTIFACT_INSTRUMENT_TEST); + assertNotNull("InstrumentTest source Providers null-check", testSourceProviderContainer); + new SourceProviderTester(model.getName(), projectDir, - "instrumentTest", defaultConfig.getTestSourceProvider()) + "instrumentTest", testSourceProviderContainer.getSourceProvider()) .test(); - Map<String, BuildTypeContainer> buildTypes = model.getBuildTypes(); + Collection<BuildTypeContainer> buildTypes = model.getBuildTypes(); assertEquals("Build Type Count", 2, buildTypes.size()); - Map<String, Variant> variants = model.getVariants(); - assertEquals("Variant Count", 8 , variants.size()); + Collection<Variant> variants = model.getVariants(); + assertEquals("Variant Count", 8, variants.size()); - Variant f1faDebugVariant = variants.get("f1FaDebug"); + Variant f1faDebugVariant = getVariant(variants, "f1FaDebug"); assertNotNull("f1faDebug Variant null-check", f1faDebugVariant); new ProductFlavorTester(f1faDebugVariant.getMergedFlavor(), "F1faDebug Merged Flavor") .test(); @@ -377,14 +474,18 @@ public class AndroidProjectTest extends TestCase { ProjectData appModelData = map.get(":app"); assertNotNull("app module model null-check", appModelData); - Dependencies dependencies = appModelData.model.getVariants().get("debug").getMainArtifactInfo().getDependencies(); + Collection<Variant> variants = appModelData.model.getVariants(); + Variant debugVariant = getVariant(variants, "debug"); + assertNotNull("debug variant null-check", debugVariant); + + Dependencies dependencies = debugVariant.getMainArtifact().getDependencies(); assertNotNull(dependencies); - List<AndroidLibrary> libs = dependencies.getLibraries(); + Collection<AndroidLibrary> libs = dependencies.getLibraries(); assertNotNull(libs); assertEquals(1, libs.size()); - AndroidLibrary androidLibrary = libs.get(0); + AndroidLibrary androidLibrary = libs.iterator().next(); assertNotNull(androidLibrary); assertEquals("Dependency project path", ":lib", androidLibrary.getProject()); @@ -402,36 +503,37 @@ public class AndroidProjectTest extends TestCase { assertFalse("Library Project", model.isLibrary()); - Map<String, Variant> variants = model.getVariants(); + Collection<Variant> variants = model.getVariants(); + Collection<ProductFlavorContainer> productFlavors = model.getProductFlavors(); - ProductFlavorContainer flavor1 = model.getProductFlavors().get("flavor1"); + ProductFlavorContainer flavor1 = getProductFlavor(productFlavors, "flavor1"); assertNotNull(flavor1); - Variant flavor1Debug = variants.get("flavor1Debug"); + Variant flavor1Debug = getVariant(variants, "flavor1Debug"); assertNotNull(flavor1Debug); - Dependencies dependencies = flavor1Debug.getMainArtifactInfo().getDependencies(); + Dependencies dependencies = flavor1Debug.getMainArtifact().getDependencies(); assertNotNull(dependencies); - List<AndroidLibrary> libs = dependencies.getLibraries(); + Collection<AndroidLibrary> libs = dependencies.getLibraries(); assertNotNull(libs); assertEquals(1, libs.size()); - AndroidLibrary androidLibrary = libs.get(0); + AndroidLibrary androidLibrary = libs.iterator().next(); assertNotNull(androidLibrary); // TODO: right now we can only test the folder name efficiently assertEquals("FlavorlibLib1Unspecified.aar", androidLibrary.getFolder().getName()); - ProductFlavorContainer flavor2 = model.getProductFlavors().get("flavor2"); + ProductFlavorContainer flavor2 = getProductFlavor(productFlavors, "flavor2"); assertNotNull(flavor2); - Variant flavor2Debug = variants.get("flavor2Debug"); + Variant flavor2Debug = getVariant(variants, "flavor2Debug"); assertNotNull(flavor2Debug); - dependencies = flavor2Debug.getMainArtifactInfo().getDependencies(); + dependencies = flavor2Debug.getMainArtifact().getDependencies(); assertNotNull(dependencies); libs = dependencies.getLibraries(); assertNotNull(libs); assertEquals(1, libs.size()); - androidLibrary = libs.get(0); + androidLibrary = libs.iterator().next(); assertNotNull(androidLibrary); // TODO: right now we can only test the folder name efficiently assertEquals("FlavorlibLib2Unspecified.aar", androidLibrary.getFolder().getName()); @@ -444,24 +546,24 @@ public class AndroidProjectTest extends TestCase { assertNotNull("Module app null-check", baseLibModelData); AndroidProject model = baseLibModelData.model; - Map<String, Variant> variants = model.getVariants(); + Collection<Variant> variants = model.getVariants(); assertEquals("Variant count", 2, variants.size()); - Variant variant = variants.get("release"); + Variant variant = getVariant(variants, "release"); assertNotNull("release variant null-check", variant); - ArtifactInfo mainInfo = variant.getMainArtifactInfo(); + AndroidArtifact mainInfo = variant.getMainArtifact(); assertNotNull("Main Artifact null-check", mainInfo); Dependencies dependencies = mainInfo.getDependencies(); assertNotNull("Dependencies null-check", dependencies); - List<String> projects = dependencies.getProjects(); + Collection<String> projects = dependencies.getProjects(); assertNotNull("project dep list null-check", projects); assertEquals("project dep count", 1, projects.size()); - assertEquals("dep on :util check", ":util", projects.get(0)); + assertEquals("dep on :util check", ":util", projects.iterator().next()); - List<File> jars = dependencies.getJars(); + Collection<File> jars = dependencies.getJars(); assertNotNull("jar dep list null-check", jars); // TODO these are jars coming from ':util' They shouldn't be there. assertEquals("jar dep count", 2, jars.size()); @@ -476,15 +578,15 @@ public class AndroidProjectTest extends TestCase { File buildDir = new File(projectDir, "build"); - for (Variant variant : model.getVariants().values()) { + for (Variant variant : model.getVariants()) { - ArtifactInfo mainInfo = variant.getMainArtifactInfo(); + AndroidArtifact mainInfo = variant.getMainArtifact(); assertNotNull( "Null-check on mainArtifactInfo for " + variant.getDisplayName(), mainInfo); // get the generated source folders. - List<File> genFolder = mainInfo.getGeneratedSourceFolders(); + Collection<File> genFolder = mainInfo.getGeneratedSourceFolders(); // We're looking for a custom folder String folderStart = new File(buildDir, "customCode").getAbsolutePath() + File.separatorChar; @@ -500,6 +602,104 @@ public class AndroidProjectTest extends TestCase { } } + public void testArtifactApi() throws Exception { + // Load the custom model for the project + ProjectData projectData = getModelForProject("artifactApi"); + + AndroidProject model = projectData.model; + + // check the Artifact Meta Data + Collection<ArtifactMetaData> extraArtifacts = model.getExtraArtifacts(); + assertNotNull("Extra artifact collection null-check", extraArtifacts); + assertEquals("Extra artifact size check", 2, extraArtifacts.size()); + + assertNotNull("instrument test metadata null-check", + getArtifactMetaData(extraArtifacts, ARTIFACT_INSTRUMENT_TEST)); + + // get the custom one. + ArtifactMetaData extraArtifactMetaData = getArtifactMetaData(extraArtifacts, "__test__"); + assertNotNull("custom extra metadata null-check", extraArtifactMetaData); + assertFalse("custom extra meta data is Test check", extraArtifactMetaData.isTest()); + assertEquals("custom extra meta data type check", ArtifactMetaData.TYPE_JAVA, extraArtifactMetaData.getType()); + + // check the extra source provider on the build Types. + for (BuildTypeContainer btContainer : model.getBuildTypes()) { + String name = btContainer.getBuildType().getName(); + Collection<SourceProviderContainer> extraSourceProviderContainers = btContainer.getExtraSourceProviders(); + assertNotNull( + "Extra source provider containers for build type '" + name + "' null-check", + extraSourceProviderContainers); + assertEquals( + "Extra source provider containers for build type size '" + name + "' check", + 1, + extraSourceProviderContainers.size()); + + SourceProviderContainer sourceProviderContainer = extraSourceProviderContainers.iterator().next(); + assertNotNull( + "Extra artifact source provider for " + name + " null check", + sourceProviderContainer); + + assertEquals( + "Extra artifact source provider for " + name + " name check", + "__test__", + sourceProviderContainer.getArtifactName()); + + assertEquals( + "Extra artifact source provider for " + name + " value check", + "buildType:" + name, + sourceProviderContainer.getSourceProvider().getManifestFile().getPath()); + } + + // check the extra source provider on the product flavors. + for (ProductFlavorContainer pfContainer : model.getProductFlavors()) { + String name = pfContainer.getProductFlavor().getName(); + Collection<SourceProviderContainer> extraSourceProviderContainers = pfContainer.getExtraSourceProviders(); + assertNotNull( + "Extra source provider container for product flavor '" + name + "' null-check", + extraSourceProviderContainers); + assertEquals( + "Extra artifact source provider container for product flavor size '" + name + "' check", + 2, + extraSourceProviderContainers.size()); + + assertNotNull( + "Extra source provider container for product flavor '" + name + "': instTest check", + getSourceProviderContainer(extraSourceProviderContainers, ARTIFACT_INSTRUMENT_TEST)); + + + SourceProviderContainer sourceProviderContainer = getSourceProviderContainer( + extraSourceProviderContainers, "__test__"); + assertNotNull( + "Custom source provider container for " + name + " null check", + sourceProviderContainer); + + assertEquals( + "Custom artifact source provider for " + name + " name check", + "__test__", + sourceProviderContainer.getArtifactName()); + + assertEquals( + "Extra artifact source provider for " + name + " value check", + "productFlavor:" + name, + sourceProviderContainer.getSourceProvider().getManifestFile().getPath()); + } + + // check the extra artifacts on the variants + for (Variant variant : model.getVariants()) { + String name = variant.getName(); + Collection<JavaArtifact> javaArtifacts = variant.getExtraJavaArtifacts(); + assertEquals(1, javaArtifacts.size()); + JavaArtifact javaArtifact = javaArtifacts.iterator().next(); + assertEquals("__test__", javaArtifact.getName()); + assertEquals("assemble:" + name, javaArtifact.getAssembleTaskName()); + assertEquals("compile:" + name, javaArtifact.getJavaCompileTaskName()); + assertEquals(new File("classesFolder:" + name), javaArtifact.getClassesFolder()); + + SourceProvider variantSourceProvider = javaArtifact.getVariantSourceProvider(); + assertNotNull(variantSourceProvider); + assertEquals("provider:" + name, variantSourceProvider.getManifestFile().getPath()); + } + } /** * Returns the SDK folder as built from the Android source tree. @@ -553,6 +753,95 @@ public class AndroidProjectTest extends TestCase { return new File(rootDir, "tests"); } + @Nullable + private static Variant getVariant( + @NonNull Collection<Variant> items, + @NonNull String name) { + for (Variant item : items) { + if (name.equals(item.getName())) { + return item; + } + } + + return null; + } + + @Nullable + private static ProductFlavorContainer getProductFlavor( + @NonNull Collection<ProductFlavorContainer> items, + @NonNull String name) { + for (ProductFlavorContainer item : items) { + assertNotNull("ProductFlavorContainer list item null-check:" + name, item); + assertNotNull("ProductFlavorContainer.getProductFlavor() list item null-check: " + name, item.getProductFlavor()); + assertNotNull("ProductFlavorContainer.getProductFlavor().getName() list item null-check: " + name, item.getProductFlavor().getName()); + if (name.equals(item.getProductFlavor().getName())) { + return item; + } + } + + return null; + } + + @Nullable + private static ArtifactMetaData getArtifactMetaData( + @NonNull Collection<ArtifactMetaData> items, + @NonNull String name) { + for (ArtifactMetaData item : items) { + assertNotNull("ArtifactMetaData list item null-check:" + name, item); + assertNotNull("ArtifactMetaData.getName() list item null-check: " + name, item.getName()); + if (name.equals(item.getName())) { + return item; + } + } + + return null; + } + + @Nullable + private static AndroidArtifact getAndroidArtifact( + @NonNull Collection<AndroidArtifact> items, + @NonNull String name) { + for (AndroidArtifact item : items) { + assertNotNull("AndroidArtifact list item null-check:" + name, item); + assertNotNull("AndroidArtifact.getName() list item null-check: " + name, item.getName()); + if (name.equals(item.getName())) { + return item; + } + } + + return null; + } + + @Nullable + private static SigningConfig getSigningConfig( + @NonNull Collection<SigningConfig> items, + @NonNull String name) { + for (SigningConfig item : items) { + assertNotNull("SigningConfig list item null-check:" + name, item); + assertNotNull("SigningConfig.getName() list item null-check: " + name, item.getName()); + if (name.equals(item.getName())) { + return item; + } + } + + return null; + } + + @Nullable + private static SourceProviderContainer getSourceProviderContainer( + @NonNull Collection<SourceProviderContainer> items, + @NonNull String name) { + for (SourceProviderContainer item : items) { + assertNotNull("SourceProviderContainer list item null-check:" + name, item); + assertNotNull("SourceProviderContainer.getName() list item null-check: " + name, item.getArtifactName()); + if (name.equals(item.getArtifactName())) { + return item; + } + } + + return null; + } + private static final class ProductFlavorTester { @NonNull private final ProductFlavor productFlavor; @NonNull private final String name; @@ -716,20 +1005,23 @@ public class AndroidProjectTest extends TestCase { } void test() { - testSinglePathSet("java", javaDir, sourceProvider.getJavaDirectories()); - testSinglePathSet("resources", resourcesDir, sourceProvider.getResourcesDirectories()); - testSinglePathSet("res", resDir, sourceProvider.getResDirectories()); - testSinglePathSet("assets", assetsDir, sourceProvider.getAssetsDirectories()); - testSinglePathSet("aidl", aidlDir, sourceProvider.getAidlDirectories()); - testSinglePathSet("rs", renderscriptDir, sourceProvider.getRenderscriptDirectories()); - testSinglePathSet("jni", jniDir, sourceProvider.getJniDirectories()); + testSinglePathCollection("java", javaDir, sourceProvider.getJavaDirectories()); + testSinglePathCollection("resources", resourcesDir, sourceProvider.getResourcesDirectories()); + testSinglePathCollection("res", resDir, sourceProvider.getResDirectories()); + testSinglePathCollection("assets", assetsDir, sourceProvider.getAssetsDirectories()); + testSinglePathCollection("aidl", aidlDir, sourceProvider.getAidlDirectories()); + testSinglePathCollection("rs", renderscriptDir, sourceProvider.getRenderscriptDirectories()); + testSinglePathCollection("jni", jniDir, sourceProvider.getJniDirectories()); assertEquals("AndroidManifest", new File(projectDir, manifestFile).getAbsolutePath(), sourceProvider.getManifestFile().getAbsolutePath()); } - private void testSinglePathSet(String setName, String referencePath, Set<File> pathSet) { + private void testSinglePathCollection( + @NonNull String setName, + @NonNull String referencePath, + @NonNull Collection<File> pathSet) { assertEquals(1, pathSet.size()); assertEquals(projectName + ": " + configName + "/" + setName, new File(projectDir, referencePath).getAbsolutePath(), @@ -751,7 +1043,7 @@ public class AndroidProjectTest extends TestCase { } void test() { - ArtifactInfo artifact = variant.getMainArtifactInfo(); + AndroidArtifact artifact = variant.getMainArtifact(); assertNotNull("Main Artifact null-check", artifact); String variantName = variant.getName(); @@ -759,7 +1051,7 @@ public class AndroidProjectTest extends TestCase { File apk = new File(build, "apk/" + outputFileName); assertEquals(variantName + " output", apk, artifact.getOutputFile()); - List<File> sourceFolders = artifact.getGeneratedSourceFolders(); + Collection<File> sourceFolders = artifact.getGeneratedSourceFolders(); assertEquals("Gen src Folder count", 4, sourceFolders.size()); File manifest = artifact.getGeneratedManifest(); diff --git a/gradle/src/build-test/groovy/com/android/build/gradle/ManualBuildTest.java b/gradle/src/build-test/groovy/com/android/build/gradle/ManualBuildTest.java index 423107a..6512f0d 100644 --- a/gradle/src/build-test/groovy/com/android/build/gradle/ManualBuildTest.java +++ b/gradle/src/build-test/groovy/com/android/build/gradle/ManualBuildTest.java @@ -32,23 +32,55 @@ import java.io.IOException; */ public class ManualBuildTest extends BuildTest { + private final static int RED = 0xFFFF0000; + private final static int GREEN = 0xFF00FF00; + private final static int BLUE = 0xFF0000FF; + public void testOverlay1Content() throws Exception { File project = buildProject("overlay1", BasePlugin.GRADLE_MIN_VERSION); File drawableOutput = new File(project, "build/res/all/debug/drawable"); - checkImageColor(drawableOutput, "no_overlay.png", (int) 0xFF00FF00); - checkImageColor(drawableOutput, "type_overlay.png", (int) 0xFF00FF00); + checkImageColor(drawableOutput, "no_overlay.png", GREEN); + checkImageColor(drawableOutput, "type_overlay.png", GREEN); } public void testOverlay2Content() throws Exception { File project = buildProject("overlay2", BasePlugin.GRADLE_MIN_VERSION); File drawableOutput = new File(project, "build/res/all/one/debug/drawable"); - checkImageColor(drawableOutput, "no_overlay.png", (int) 0xFF00FF00); - checkImageColor(drawableOutput, "type_overlay.png", (int) 0xFF00FF00); - checkImageColor(drawableOutput, "flavor_overlay.png", (int) 0xFF00FF00); - checkImageColor(drawableOutput, "type_flavor_overlay.png", (int) 0xFF00FF00); + checkImageColor(drawableOutput, "no_overlay.png", GREEN); + checkImageColor(drawableOutput, "type_overlay.png", GREEN); + checkImageColor(drawableOutput, "flavor_overlay.png", GREEN); + checkImageColor(drawableOutput, "type_flavor_overlay.png", GREEN); + checkImageColor(drawableOutput, "variant_type_flavor_overlay.png", GREEN); + } + + public void testOverlay3Content() throws Exception { + File project = buildProject("overlay3", BasePlugin.GRADLE_MIN_VERSION); + File drawableOutput = new File(project, "build/res/all/freebeta/debug/drawable"); + + checkImageColor(drawableOutput, "no_overlay.png", GREEN); + checkImageColor(drawableOutput, "debug_overlay.png", GREEN); + checkImageColor(drawableOutput, "beta_overlay.png", GREEN); + checkImageColor(drawableOutput, "free_beta_debug_overlay.png", GREEN); + checkImageColor(drawableOutput, "free_normal_overlay.png", RED); + + drawableOutput = new File(project, "build/res/all/freenormal/debug/drawable"); + + checkImageColor(drawableOutput, "no_overlay.png", GREEN); + checkImageColor(drawableOutput, "debug_overlay.png", GREEN); + checkImageColor(drawableOutput, "beta_overlay.png", RED); + checkImageColor(drawableOutput, "free_beta_debug_overlay.png", RED); + checkImageColor(drawableOutput, "free_normal_overlay.png", GREEN); + + drawableOutput = new File(project, "build/res/all/paidbeta/debug/drawable"); + + checkImageColor(drawableOutput, "no_overlay.png", GREEN); + checkImageColor(drawableOutput, "debug_overlay.png", GREEN); + checkImageColor(drawableOutput, "beta_overlay.png", GREEN); + checkImageColor(drawableOutput, "free_beta_debug_overlay.png", RED); + checkImageColor(drawableOutput, "free_normal_overlay.png", RED); } public void testRepo() { diff --git a/gradle/src/main/groovy/com/android/build/gradle/AppPlugin.groovy b/gradle/src/main/groovy/com/android/build/gradle/AppPlugin.groovy index 33db4c3..0cc4e35 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/AppPlugin.groovy +++ b/gradle/src/main/groovy/com/android/build/gradle/AppPlugin.groovy @@ -20,7 +20,6 @@ import com.android.annotations.Nullable import com.android.build.gradle.api.BaseVariant import com.android.build.gradle.internal.BuildTypeData import com.android.build.gradle.internal.ConfigurationProvider -import com.android.build.gradle.internal.ConfigurationProviderImpl import com.android.build.gradle.internal.ProductFlavorData import com.android.build.gradle.internal.api.ApplicationVariantImpl import com.android.build.gradle.internal.api.DefaultAndroidSourceSet @@ -451,9 +450,17 @@ class AppPlugin extends com.android.build.gradle.BasePlugin implements Plugin<Pr // create the variant and get its internal storage object. ApplicationVariantData appVariantData = new ApplicationVariantData(variantConfig) - DefaultAndroidSourceSet sourceSet = (DefaultAndroidSourceSet) extension.sourceSetsContainer.maybeCreate(variantConfig.fullName) - variantConfig.setVariantSourceProvider(sourceSet) - variantProviders.add(new ConfigurationProviderImpl(project, sourceSet)) + DefaultAndroidSourceSet variantSourceSet = (DefaultAndroidSourceSet) extension.sourceSetsContainer.maybeCreate(variantConfig.fullName) + variantConfig.setVariantSourceProvider(variantSourceSet) + // TODO: hmm this won't work + //variantProviders.add(new ConfigurationProviderImpl(project, variantSourceSet)) + + if (flavorDataList.size() > 1) { + DefaultAndroidSourceSet multiFlavorSourceSet = (DefaultAndroidSourceSet) extension.sourceSetsContainer.maybeCreate(variantConfig.flavorName) + variantConfig.setMultiFlavorSourceProvider(multiFlavorSourceSet) + // TODO: hmm this won't work + //variantProviders.add(new ConfigurationProviderImpl(project, multiFlavorSourceSet)) + } VariantDependencies variantDep = VariantDependencies.compute( project, appVariantData.variantConfiguration.fullName, diff --git a/gradle/src/main/groovy/com/android/build/gradle/BaseExtension.groovy b/gradle/src/main/groovy/com/android/build/gradle/BaseExtension.groovy index 889a70a..974fe16 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/BaseExtension.groovy +++ b/gradle/src/main/groovy/com/android/build/gradle/BaseExtension.groovy @@ -17,9 +17,12 @@ package com.android.build.gradle import com.android.SdkConstants import com.android.annotations.NonNull +import com.android.annotations.Nullable import com.android.build.gradle.api.AndroidSourceSet +import com.android.build.gradle.api.BaseVariant import com.android.build.gradle.api.TestVariant import com.android.build.gradle.internal.CompileOptions +import com.android.build.gradle.internal.SourceSetSourceProviderWrapper import com.android.build.gradle.internal.dsl.AaptOptionsImpl import com.android.build.gradle.internal.dsl.AndroidSourceSetFactory import com.android.build.gradle.internal.dsl.DexOptionsImpl @@ -27,6 +30,9 @@ import com.android.build.gradle.internal.dsl.ProductFlavorDsl import com.android.build.gradle.internal.test.TestOptions import com.android.builder.BuilderConstants import com.android.builder.DefaultProductFlavor +import com.android.builder.model.BuildType +import com.android.builder.model.ProductFlavor +import com.android.builder.model.SourceProvider import com.android.builder.testing.api.DeviceProvider import com.android.builder.testing.api.TestServer import com.android.sdklib.repository.FullRevision @@ -38,8 +44,8 @@ import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.ConfigurationContainer import org.gradle.api.internal.DefaultDomainObjectSet import org.gradle.api.internal.project.ProjectInternal +import org.gradle.api.tasks.SourceSet import org.gradle.internal.reflect.Instantiator - /** * Base android extension for all android plugins. */ @@ -201,6 +207,49 @@ public abstract class BaseExtension { testVariantList.add(testVariant) } + public void registerArtifactType(@NonNull String name, + boolean isTest, + int artifactType) { + plugin.registerArtifactType(name, isTest, artifactType) + } + + public void registerBuildTypeSourceProvider( + @NonNull String name, + @NonNull BuildType buildType, + @NonNull SourceProvider sourceProvider) { + plugin.registerBuildTypeSourceProvider(name, buildType, sourceProvider) + } + + public void registerProductFlavorSourceProvider( + @NonNull String name, + @NonNull ProductFlavor productFlavor, + @NonNull SourceProvider sourceProvider) { + plugin.registerProductFlavorSourceProvider(name, productFlavor, sourceProvider) + } + + public void registerJavaArtifact( + @NonNull String name, + @NonNull BaseVariant variant, + @NonNull String assembleTaskName, + @NonNull String javaCompileTaskName, + @NonNull File classesFolder, + @Nullable SourceProvider sourceProvider) { + plugin.registerJavaArtifact(name, variant, assembleTaskName, javaCompileTaskName, + classesFolder, sourceProvider) + } + + public void registerMultiFlavorSourceProvider( + @NonNull String name, + @NonNull String flavorName, + @NonNull SourceProvider sourceProvider) { + plugin.registerMultiFlavorSourceProvider(name, flavorName, sourceProvider) + } + + @NonNull + public SourceProvider wrapJavaSourceSet(@NonNull SourceSet sourceSet) { + return new SourceSetSourceProviderWrapper(sourceSet) + } + public String getCompileSdkVersion() { return target } diff --git a/gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy b/gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy index ab56022..18d43c9 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy +++ b/gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy @@ -18,6 +18,7 @@ package com.android.build.gradle import com.android.annotations.NonNull import com.android.annotations.Nullable import com.android.build.gradle.api.AndroidSourceSet +import com.android.build.gradle.api.BaseVariant import com.android.build.gradle.internal.BadPluginException import com.android.build.gradle.internal.LoggerWrapper import com.android.build.gradle.internal.ProductFlavorData @@ -29,6 +30,8 @@ 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.SigningConfigDsl +import com.android.build.gradle.internal.model.ArtifactMetaDataImpl +import com.android.build.gradle.internal.model.JavaArtifactImpl import com.android.build.gradle.internal.model.ModelBuilder import com.android.build.gradle.internal.tasks.AndroidReportTask import com.android.build.gradle.internal.tasks.DependencyReportTask @@ -46,6 +49,7 @@ import com.android.build.gradle.internal.test.report.ReportType import com.android.build.gradle.internal.variant.ApkVariantData import com.android.build.gradle.internal.variant.ApplicationVariantData import com.android.build.gradle.internal.variant.BaseVariantData +import com.android.build.gradle.internal.variant.DefaultSourceProviderContainer import com.android.build.gradle.internal.variant.LibraryVariantData import com.android.build.gradle.internal.variant.TestVariantData import com.android.build.gradle.internal.variant.TestedVariantData @@ -69,15 +73,21 @@ import com.android.builder.SdkParser import com.android.builder.VariantConfiguration import com.android.builder.dependency.JarDependency import com.android.builder.dependency.LibraryDependency +import com.android.builder.model.AndroidArtifact import com.android.builder.model.AndroidProject +import com.android.builder.model.ArtifactMetaData +import com.android.builder.model.BuildType +import com.android.builder.model.JavaArtifact import com.android.builder.model.ProductFlavor import com.android.builder.model.SigningConfig import com.android.builder.model.SourceProvider +import com.android.builder.model.SourceProviderContainer import com.android.builder.testing.ConnectedDeviceProvider import com.android.builder.testing.api.DeviceProvider import com.android.builder.testing.api.TestServer import com.android.utils.ILogger import com.google.common.collect.ArrayListMultimap +import com.google.common.collect.ListMultimap import com.google.common.collect.Lists import com.google.common.collect.Maps import com.google.common.collect.Multimap @@ -665,7 +675,7 @@ public abstract class BasePlugin { ((AndroidSourceSet) variantConfiguration.buildTypeSourceSet).resources) } if (variantConfiguration.hasFlavors()) { - for (SourceProvider flavorSourceSet : variantConfiguration.flavorSourceSets) { + for (SourceProvider flavorSourceSet : variantConfiguration.flavorSourceProviders) { processResources.from(((AndroidSourceSet) flavorSourceSet).resources) } } @@ -720,8 +730,8 @@ public abstract class BasePlugin { sourceList.add(((AndroidSourceSet) config.buildTypeSourceSet).java) } if (config.hasFlavors()) { - for (SourceProvider flavorSourceSet : config.flavorSourceSets) { - sourceList.add(((AndroidSourceSet) flavorSourceSet).java) + for (SourceProvider flavorSourceProvider : config.flavorSourceProviders) { + sourceList.add(((AndroidSourceSet) flavorSourceProvider).java) } } compileTask.source = sourceList.toArray() @@ -889,7 +899,7 @@ public abstract class BasePlugin { for (int i = 0 ; i < count ; i++) { final BaseVariantData baseVariantData = variantDataList.get(i) String variantName = baseVariantData.variantConfiguration.fullName - Task lintCheck = project.tasks.create("lint" + variantName, Lint) + Lint lintCheck = project.tasks.create("lint" + variantName, Lint) lintCheck.dependsOn baseVariantData.javaCompileTask, lintCompile lint.dependsOn lintCheck lintCheck.setPlugin(this) @@ -897,11 +907,11 @@ public abstract class BasePlugin { String outputName = "$project.buildDir/lint/" + variantName VariantConfiguration config = baseVariantData.variantConfiguration List<LibraryDependency> depList = config.getAllLibraries() - List<Set<File>> javaSource = Lists.newArrayList() - List<Set<File>> resourceSource = Lists.newArrayList() + List<Collection<File>> javaSource = Lists.newArrayList() + List<Collection<File>> resourceSource = Lists.newArrayList() // set the java and res source of this variant's flavors - Iterator<SourceProvider> flavorSources = config.flavorSourceSets.iterator() + Iterator<SourceProvider> flavorSources = config.flavorSourceProviders.iterator() SourceProvider source while (flavorSources.hasNext()) { source = flavorSources.next() @@ -913,8 +923,15 @@ public abstract class BasePlugin { if (config.getType() != VariantConfiguration.Type.TEST) { javaSource.add(config.buildTypeSourceSet.javaDirectories) } - if (config.variantSourceProvider != null) { - javaSource.add(config.variantSourceProvider.javaDirectories) + SourceProvider sourceProvider = config.variantSourceProvider + if (sourceProvider != null) { + javaSource.add(sourceProvider.javaDirectories) + resourceSource.add(sourceProvider.resDirectories) + } + sourceProvider = config.multiFlavorSourceProvider + if (sourceProvider != null) { + javaSource.add(sourceProvider.javaDirectories) + resourceSource.add(sourceProvider.resDirectories) } resourceSource.add(config.defaultSourceSet.resDirectories) @@ -1563,6 +1580,112 @@ public abstract class BasePlugin { "generate${variantData.variantConfiguration.fullName.capitalize()}Sources") } + + private final Map<String, ArtifactMetaData> extraArtifactMap = Maps.newHashMap() + private final ListMultimap<String, AndroidArtifact> extraAndroidArtifacts = ArrayListMultimap.create() + private final ListMultimap<String, JavaArtifact> extraJavaArtifacts = ArrayListMultimap.create() + private final ListMultimap<String, SourceProviderContainer> extraVariantSourceProviders = ArrayListMultimap.create() + private final ListMultimap<String, SourceProviderContainer> extraBuildTypeSourceProviders = ArrayListMultimap.create() + private final ListMultimap<String, SourceProviderContainer> extraProductFlavorSourceProviders = ArrayListMultimap.create() + private final ListMultimap<String, SourceProviderContainer> extraMultiFlavorSourceProviders = ArrayListMultimap.create() + + + public Collection<ArtifactMetaData> getExtraArtifacts() { + return extraArtifactMap.values() + } + + public Collection<AndroidArtifact> getExtraAndroidArtifacts(@NonNull String variantName) { + return extraAndroidArtifacts.get(variantName) + } + + public Collection<JavaArtifact> getExtraJavaArtifacts(@NonNull String variantName) { + return extraJavaArtifacts.get(variantName) + } + + public Collection<SourceProviderContainer> getExtraVariantSourceProviders(@NonNull String variantName) { + return extraVariantSourceProviders.get(variantName) + } + + public Collection<SourceProviderContainer> getExtraFlavorSourceProviders(@NonNull String flavorName) { + return extraProductFlavorSourceProviders.get(flavorName) + } + + public Collection<SourceProviderContainer> getExtraBuildTypeSourceProviders(@NonNull String buildTypeName) { + return extraBuildTypeSourceProviders.get(buildTypeName) + } + + public void registerArtifactType(@NonNull String name, + boolean isTest, + int artifactType) { + + if (extraArtifactMap.get(name) != null) { + throw new IllegalArgumentException("Artifact with name $name already registered.") + } + + extraArtifactMap.put(name, new ArtifactMetaDataImpl(name, isTest, artifactType)) + } + + public void registerBuildTypeSourceProvider(@NonNull String name, + @NonNull BuildType buildType, + @NonNull SourceProvider sourceProvider) { + if (extraArtifactMap.get(name) == null) { + throw new IllegalArgumentException( + "Artifact with name $name is not yet registered. Use registerArtifactType()") + } + + extraBuildTypeSourceProviders.put(buildType.name, + new DefaultSourceProviderContainer(name, sourceProvider)) + + } + + public void registerProductFlavorSourceProvider(@NonNull String name, + @NonNull ProductFlavor productFlavor, + @NonNull SourceProvider sourceProvider) { + if (extraArtifactMap.get(name) == null) { + throw new IllegalArgumentException( + "Artifact with name $name is not yet registered. Use registerArtifactType()") + } + + extraProductFlavorSourceProviders.put(productFlavor.name, + new DefaultSourceProviderContainer(name, sourceProvider)) + + } + + public void registerMultiFlavorSourceProvider(@NonNull String name, + @NonNull String flavorName, + @NonNull SourceProvider sourceProvider) { + if (extraArtifactMap.get(name) == null) { + throw new IllegalArgumentException( + "Artifact with name $name is not yet registered. Use registerArtifactType()") + } + + extraMultiFlavorSourceProviders.put(flavorName, + new DefaultSourceProviderContainer(name, sourceProvider)) + } + + public void registerJavaArtifact( + @NonNull String name, + @NonNull BaseVariant variant, + @NonNull String assembleTaskName, + @NonNull String javaCompileTaskName, + @NonNull File classesFolder, + @Nullable SourceProvider sourceProvider) { + ArtifactMetaData artifactMetaData = extraArtifactMap.get(name) + if (artifactMetaData == null) { + throw new IllegalArgumentException( + "Artifact with name $name is not yet registered. Use registerArtifactType()") + } + if (artifactMetaData.type != ArtifactMetaData.TYPE_JAVA) { + throw new IllegalArgumentException( + "Artifact with name $name is not of type JAVA") + } + + JavaArtifact artifact = new JavaArtifactImpl( + name, assembleTaskName, javaCompileTaskName, classesFolder, + null, sourceProvider, null) + extraJavaArtifacts.put(variant.name, artifact) + } + //---------------------------------------------------------------------------------------------- //------------------------------ START DEPENDENCY STUFF ---------------------------------------- //---------------------------------------------------------------------------------------------- @@ -1854,17 +1977,21 @@ public abstract class BasePlugin { } private static String getLocalVersion() { - Class clazz = BasePlugin.class - String className = clazz.getSimpleName() + ".class" - String classPath = clazz.getResource(className).toString() - if (!classPath.startsWith("jar")) { - // Class not from JAR, unlikely - return null - } - String manifestPath = classPath.substring(0, classPath.lastIndexOf("!") + 1) + - "/META-INF/MANIFEST.MF"; - Manifest manifest = new Manifest(new URL(manifestPath).openStream()); - Attributes attr = manifest.getMainAttributes(); - return attr.getValue("Plugin-Version"); + try { + Class clazz = BasePlugin.class + String className = clazz.getSimpleName() + ".class" + String classPath = clazz.getResource(className).toString() + if (!classPath.startsWith("jar")) { + // Class not from JAR, unlikely + return null + } + String manifestPath = classPath.substring(0, classPath.lastIndexOf("!") + 1) + + "/META-INF/MANIFEST.MF"; + Manifest manifest = new Manifest(new URL(manifestPath).openStream()); + Attributes attr = manifest.getMainAttributes(); + return attr.getValue("Plugin-Version"); + } catch (Throwable t) { + return null; + } } } diff --git a/gradle/src/main/groovy/com/android/build/gradle/api/BaseVariant.java b/gradle/src/main/groovy/com/android/build/gradle/api/BaseVariant.java index 297121d..4357456 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/api/BaseVariant.java +++ b/gradle/src/main/groovy/com/android/build/gradle/api/BaseVariant.java @@ -71,6 +71,14 @@ public interface BaseVariant { String getBaseName(); /** + * Returns the flavor name of the variant. This is a concatenation of all the + * applied flavors + * @return the name of the flavors, or an empty string if there is not flavors. + */ + @NonNull + String getFlavorName(); + + /** * Returns the {@link com.android.builder.DefaultBuildType} for this build variant. */ @NonNull diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/AndroidAsciiReportRenderer.java b/gradle/src/main/groovy/com/android/build/gradle/internal/AndroidAsciiReportRenderer.java index 25ea1ca..6704129 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/internal/AndroidAsciiReportRenderer.java +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/AndroidAsciiReportRenderer.java @@ -31,6 +31,7 @@ import org.gradle.logging.StyledTextOutput; import org.gradle.util.GUtil; import java.io.IOException; +import java.util.Collection; import java.util.List; import static org.gradle.logging.StyledTextOutput.Style.Description; @@ -132,15 +133,16 @@ public class AndroidAsciiReportRenderer extends TextReportRenderer { } private void renderChildren(@NonNull List<LibraryDependency> libraries, - @Nullable List<JarDependency> localJars) { + @Nullable Collection<JarDependency> localJars) { renderer.startChildren(); if (localJars != null) { final boolean emptyChildren = libraries.isEmpty(); final int count = localJars.size(); - for (int i = 0; i < count; i++) { - JarDependency jarDependency = localJars.get(i); + int i = 0; + for (JarDependency jarDependency : localJars) { render(jarDependency, emptyChildren && i == count - 1); + i++; } } diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/SourceSetSourceProviderWrapper.java b/gradle/src/main/groovy/com/android/build/gradle/internal/SourceSetSourceProviderWrapper.java new file mode 100644 index 0000000..0cc3f7c --- /dev/null +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/SourceSetSourceProviderWrapper.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2013 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.internal; + +import com.android.annotations.NonNull; +import com.android.builder.model.SourceProvider; +import org.gradle.api.tasks.SourceSet; + +import java.io.File; +import java.util.Collection; +import java.util.Collections; + +/** + * An implementation of SourceProvider that's wrapper around a Java SourceSet. + * This is useful for the case where we store SourceProviders but don't want to + * query the content of the SourceSet at the moment the SourceProvider is created. + */ +public class SourceSetSourceProviderWrapper implements SourceProvider { + + @NonNull + private final SourceSet sourceSet; + + public SourceSetSourceProviderWrapper(@NonNull SourceSet sourceSet) { + + this.sourceSet = sourceSet; + } + + @NonNull + @Override + public File getManifestFile() { + throw new IllegalAccessError("Shouldn't access manifest from SourceSetSourceProviderWrapper"); + } + + @NonNull + @Override + public Collection<File> getJavaDirectories() { + return sourceSet.getAllJava().getSrcDirs(); + } + + @NonNull + @Override + public Collection<File> getResourcesDirectories() { + return sourceSet.getResources().getSrcDirs(); + } + + @NonNull + @Override + public Collection<File> getAidlDirectories() { + return Collections.emptyList(); + } + + @NonNull + @Override + public Collection<File> getRenderscriptDirectories() { + return Collections.emptyList(); + } + + @NonNull + @Override + public Collection<File> getJniDirectories() { + return Collections.emptyList(); + } + + @NonNull + @Override + public Collection<File> getResDirectories() { + return Collections.emptyList(); + } + + @NonNull + @Override + public Collection<File> getAssetsDirectories() { + return Collections.emptyList(); + } +} diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/api/BaseVariantImpl.java b/gradle/src/main/groovy/com/android/build/gradle/internal/api/BaseVariantImpl.java index 1e99d91..894fe8a 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/internal/api/BaseVariantImpl.java +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/api/BaseVariantImpl.java @@ -64,6 +64,12 @@ abstract class BaseVariantImpl implements BaseVariant { return getVariantData().getVariantConfiguration().getBaseName(); } + @NonNull + @Override + public String getFlavorName() { + return getVariantData().getVariantConfiguration().getFlavorName(); + } + @Override @NonNull public DefaultBuildType getBuildType() { diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/AaptOptionsImpl.groovy b/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/AaptOptionsImpl.groovy index 449a43f..d50371e 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/AaptOptionsImpl.groovy +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/AaptOptionsImpl.groovy @@ -45,7 +45,7 @@ public class AaptOptionsImpl implements AaptOptions { } @Override - List<String> getNoCompress() { + Collection<String> getNoCompress() { return noCompressList } diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/BuildTypeDsl.groovy b/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/BuildTypeDsl.groovy index a4770b6..6b51bc4 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/BuildTypeDsl.groovy +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/BuildTypeDsl.groovy @@ -21,7 +21,7 @@ import com.android.annotations.VisibleForTesting import com.android.builder.AndroidBuilder import com.android.builder.BuilderConstants import com.android.builder.DefaultBuildType -import com.android.builder.NdkConfig +import com.android.builder.model.NdkConfig import com.android.builder.model.SigningConfig import org.gradle.api.Action import org.gradle.api.internal.file.FileResolver diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/NdkConfigDsl.java b/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/NdkConfigDsl.java index 64f704a..87b6dcd 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/NdkConfigDsl.java +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/NdkConfigDsl.java @@ -18,7 +18,7 @@ package com.android.build.gradle.internal.dsl; import com.android.annotations.NonNull; import com.android.annotations.Nullable; -import com.android.builder.NdkConfig; +import com.android.builder.model.NdkConfig; import com.google.common.collect.Sets; import org.gradle.api.tasks.Input; import org.gradle.api.tasks.Optional; diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/ProductFlavorDsl.groovy b/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/ProductFlavorDsl.groovy index 1645a03..cda61b0 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/ProductFlavorDsl.groovy +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/ProductFlavorDsl.groovy @@ -15,11 +15,12 @@ */ package com.android.build.gradle.internal.dsl + import com.android.annotations.NonNull import com.android.annotations.Nullable import com.android.builder.AndroidBuilder import com.android.builder.DefaultProductFlavor -import com.android.builder.NdkConfig +import com.android.builder.model.NdkConfig import org.gradle.api.Action import org.gradle.api.internal.file.FileResolver import org.gradle.internal.reflect.Instantiator diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/model/ArtifactInfoImpl.java b/gradle/src/main/groovy/com/android/build/gradle/internal/model/AndroidArtifactImpl.java index d7bb7f9..f27a055 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/internal/model/ArtifactInfoImpl.java +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/model/AndroidArtifactImpl.java @@ -18,17 +18,19 @@ package com.android.build.gradle.internal.model; import com.android.annotations.NonNull; import com.android.annotations.Nullable; -import com.android.builder.model.ArtifactInfo; +import com.android.builder.model.AndroidArtifact; import com.android.builder.model.Dependencies; +import com.android.builder.model.SourceProvider; import java.io.File; import java.io.Serializable; import java.util.List; /** - * Implementation of ArtifactInfo that is serializable + * Implementation of AndroidArtifact that is serializable */ -public class ArtifactInfoImpl implements ArtifactInfo, Serializable { +public class AndroidArtifactImpl extends BaseArtifactImpl implements AndroidArtifact, Serializable { + private static final long serialVersionUID = 1L; @NonNull private final File outputFile; @@ -36,49 +38,42 @@ public class ArtifactInfoImpl implements ArtifactInfo, Serializable { @Nullable private final String signingConfigName; @NonNull - private final String assembleTaskName; - @NonNull private final String packageName; @NonNull private final String sourceGenTaskName; @NonNull - private final String javaCompileTaskName; - @NonNull private final File generatedManifest; @NonNull private final List<File> generatedSourceFolders; @NonNull private final List<File> generatedResourceFolders; - @NonNull - private final File classesFolder; - @NonNull - private final Dependencies dependencies; + AndroidArtifactImpl(@NonNull String name, + @NonNull String assembleTaskName, + @NonNull File outputFile, + boolean isSigned, + @Nullable String signingConfigName, + @NonNull String packageName, + @NonNull String sourceGenTaskName, + @NonNull String javaCompileTaskName, + @NonNull File generatedManifest, + @NonNull List<File> generatedSourceFolders, + @NonNull List<File> generatedResourceFolders, + @NonNull File classesFolder, + @NonNull Dependencies dependencies, + @Nullable SourceProvider variantSourceProvider, + @Nullable SourceProvider multiFlavorSourceProviders) { + super(name, assembleTaskName, javaCompileTaskName, classesFolder, dependencies, + variantSourceProvider, multiFlavorSourceProviders); - ArtifactInfoImpl(@NonNull String assembleTaskName, - @NonNull File outputFile, - boolean isSigned, - @Nullable String signingConfigName, - @NonNull String packageName, - @NonNull String sourceGenTaskName, - @NonNull String javaCompileTaskName, - @NonNull File generatedManifest, - @NonNull List<File> generatedSourceFolders, - @NonNull List<File> generatedResourceFolders, - @NonNull File classesFolder, - @NonNull Dependencies dependencies) { - this.assembleTaskName = assembleTaskName; this.outputFile = outputFile; this.isSigned = isSigned; this.signingConfigName = signingConfigName; this.packageName = packageName; this.sourceGenTaskName = sourceGenTaskName; - this.javaCompileTaskName = javaCompileTaskName; this.generatedManifest = generatedManifest; this.generatedSourceFolders = generatedSourceFolders; this.generatedResourceFolders = generatedResourceFolders; - this.classesFolder = classesFolder; - this.dependencies = dependencies; } @NonNull @@ -112,18 +107,6 @@ public class ArtifactInfoImpl implements ArtifactInfo, Serializable { @NonNull @Override - public String getJavaCompileTaskName() { - return javaCompileTaskName; - } - - @NonNull - @Override - public String getAssembleTaskName() { - return assembleTaskName; - } - - @NonNull - @Override public File getGeneratedManifest() { return generatedManifest; } @@ -139,16 +122,4 @@ public class ArtifactInfoImpl implements ArtifactInfo, Serializable { public List<File> getGeneratedResourceFolders() { return generatedResourceFolders; } - - @NonNull - @Override - public File getClassesFolder() { - return classesFolder; - } - - @NonNull - @Override - public Dependencies getDependencies() { - return dependencies; - } } diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/model/AndroidLibraryImpl.java b/gradle/src/main/groovy/com/android/build/gradle/internal/model/AndroidLibraryImpl.java index b3fc9d1..8635ce8 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/internal/model/AndroidLibraryImpl.java +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/model/AndroidLibraryImpl.java @@ -23,6 +23,7 @@ import com.android.builder.model.AndroidLibrary; import java.io.File; import java.io.Serializable; +import java.util.Collection; import java.util.List; public class AndroidLibraryImpl implements AndroidLibrary, Serializable { @@ -39,7 +40,7 @@ public class AndroidLibraryImpl implements AndroidLibrary, Serializable { @NonNull private final File jarFile; @NonNull - private final List<File> localJars; + private final Collection<File> localJars; @NonNull private final File resFolder; @NonNull @@ -115,7 +116,7 @@ public class AndroidLibraryImpl implements AndroidLibrary, Serializable { @NonNull @Override - public List<File> getLocalJars() { + public Collection<File> getLocalJars() { return localJars; } diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/model/ArtifactMetaDataImpl.java b/gradle/src/main/groovy/com/android/build/gradle/internal/model/ArtifactMetaDataImpl.java new file mode 100644 index 0000000..8f33c2d --- /dev/null +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/model/ArtifactMetaDataImpl.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2013 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.internal.model; + +import com.android.annotations.NonNull; +import com.android.builder.model.ArtifactMetaData; + +import java.io.Serializable; + +/** + * Implementation of ArtifactMetaData that is serializable + */ +public class ArtifactMetaDataImpl implements ArtifactMetaData, Serializable { + private static final long serialVersionUID = 1L; + + @NonNull + private final String name; + private final boolean isTest; + private final int type; + + public ArtifactMetaDataImpl(@NonNull String name, boolean isTest, int type) { + this.name = name; + this.isTest = isTest; + this.type = type; + } + + @NonNull + @Override + public String getName() { + return name; + } + + @Override + public boolean isTest() { + return isTest; + } + + @Override + public int getType() { + return type; + } +} diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/model/BaseArtifactImpl.java b/gradle/src/main/groovy/com/android/build/gradle/internal/model/BaseArtifactImpl.java new file mode 100644 index 0000000..65c0c87 --- /dev/null +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/model/BaseArtifactImpl.java @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2013 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.internal.model; + +import com.android.annotations.NonNull; +import com.android.annotations.Nullable; +import com.android.builder.model.BaseArtifact; +import com.android.builder.model.Dependencies; +import com.android.builder.model.SourceProvider; + +import java.io.File; +import java.io.Serializable; + +/** + * Implementation of BaseArtifact that is serializable + */ +class BaseArtifactImpl implements BaseArtifact, Serializable { + private static final long serialVersionUID = 1L; + + private final String name; + @NonNull + private final String assembleTaskName; + @NonNull + private final String javaCompileTaskName; + @NonNull + private final File classesFolder; + @NonNull + private final Dependencies dependencies; + @Nullable + private final SourceProvider variantSourceProvider; + @Nullable + private final SourceProvider multiFlavorSourceProviders; + + + BaseArtifactImpl(@NonNull String name, + @NonNull String assembleTaskName, + @NonNull String javaCompileTaskName, + @NonNull File classesFolder, + @NonNull Dependencies dependencies, + @Nullable SourceProvider variantSourceProvider, + @Nullable SourceProvider multiFlavorSourceProviders) { + this.name = name; + this.assembleTaskName = assembleTaskName; + this.javaCompileTaskName = javaCompileTaskName; + this.classesFolder = classesFolder; + this.dependencies = dependencies; + this.variantSourceProvider = variantSourceProvider; + this.multiFlavorSourceProviders = multiFlavorSourceProviders; + } + + @NonNull + @Override + public String getName() { + return name; + } + + @NonNull + @Override + public String getJavaCompileTaskName() { + return javaCompileTaskName; + } + + @NonNull + @Override + public String getAssembleTaskName() { + return assembleTaskName; + } + + @NonNull + @Override + public File getClassesFolder() { + return classesFolder; + } + + @NonNull + @Override + public Dependencies getDependencies() { + return dependencies; + } + + @Nullable + @Override + public SourceProvider getVariantSourceProvider() { + return variantSourceProvider; + } + + @Nullable + @Override + public SourceProvider getMultiFlavorSourceProvider() { + return multiFlavorSourceProviders; + } +} diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/model/BuildTypeContainerImpl.java b/gradle/src/main/groovy/com/android/build/gradle/internal/model/BuildTypeContainerImpl.java index db8dc17..a4c302f 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/internal/model/BuildTypeContainerImpl.java +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/model/BuildTypeContainerImpl.java @@ -17,11 +17,14 @@ package com.android.build.gradle.internal.model; import com.android.annotations.NonNull; -import com.android.builder.model.BuildTypeContainer; +import com.android.build.gradle.internal.BuildTypeData; import com.android.builder.model.BuildType; +import com.android.builder.model.BuildTypeContainer; import com.android.builder.model.SourceProvider; +import com.android.builder.model.SourceProviderContainer; import java.io.Serializable; +import java.util.Collection; class BuildTypeContainerImpl implements BuildTypeContainer, Serializable { private static final long serialVersionUID = 1L; @@ -30,11 +33,35 @@ class BuildTypeContainerImpl implements BuildTypeContainer, Serializable { private final BuildType buildType; @NonNull private final SourceProvider sourceProvider; + @NonNull + private final Collection<SourceProviderContainer> extraSourceProviders; - BuildTypeContainerImpl(@NonNull BuildTypeImpl buildType, - @NonNull SourceProviderImpl sourceProvider) { + /** + * Create a BuildTypeContainer from a BuildTypeData + * + * @param buildTypeData the build type data + * @param sourceProviderContainers collection of extra source providers + * + * @return a non-null BuildTypeContainer + */ + @NonNull + static BuildTypeContainer createBTC( + @NonNull BuildTypeData buildTypeData, + @NonNull Collection<SourceProviderContainer> sourceProviderContainers) { + + return new BuildTypeContainerImpl( + BuildTypeImpl.cloneBuildType(buildTypeData.getBuildType()), + SourceProviderImpl.cloneProvider(buildTypeData.getSourceSet()), + SourceProviderContainerImpl.cloneCollection(sourceProviderContainers)); + } + + private BuildTypeContainerImpl( + @NonNull BuildTypeImpl buildType, + @NonNull SourceProviderImpl sourceProvider, + @NonNull Collection<SourceProviderContainer> extraSourceProviders) { this.buildType = buildType; this.sourceProvider = sourceProvider; + this.extraSourceProviders = extraSourceProviders; } @Override @@ -48,4 +75,10 @@ class BuildTypeContainerImpl implements BuildTypeContainer, Serializable { public SourceProvider getSourceProvider() { return sourceProvider; } + + @NonNull + @Override + public Collection<SourceProviderContainer> getExtraSourceProviders() { + return extraSourceProviders; + } } diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/model/BuildTypeImpl.java b/gradle/src/main/groovy/com/android/build/gradle/internal/model/BuildTypeImpl.java index ccb1e8b..e3f5cdc 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/internal/model/BuildTypeImpl.java +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/model/BuildTypeImpl.java @@ -18,9 +18,9 @@ package com.android.build.gradle.internal.model; import com.android.annotations.NonNull; import com.android.annotations.Nullable; -import com.android.builder.NdkConfig; import com.android.builder.model.BuildType; import com.android.builder.model.ClassField; +import com.android.builder.model.NdkConfig; import java.io.File; import java.io.Serializable; diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/model/DefaultAndroidProject.java b/gradle/src/main/groovy/com/android/build/gradle/internal/model/DefaultAndroidProject.java index 39e184d..fab28d1 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/internal/model/DefaultAndroidProject.java +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/model/DefaultAndroidProject.java @@ -18,20 +18,19 @@ package com.android.build.gradle.internal.model; import com.android.annotations.NonNull; import com.android.build.gradle.internal.CompileOptions; +import com.android.builder.model.AaptOptions; import com.android.builder.model.AndroidProject; +import com.android.builder.model.ArtifactMetaData; import com.android.builder.model.BuildTypeContainer; import com.android.builder.model.JavaCompileOptions; import com.android.builder.model.ProductFlavorContainer; -import com.android.builder.model.Variant; -import com.android.builder.model.AaptOptions; import com.android.builder.model.SigningConfig; -import com.google.common.collect.Maps; +import com.android.builder.model.Variant; +import com.google.common.collect.Lists; import java.io.File; import java.io.Serializable; import java.util.Collection; -import java.util.List; -import java.util.Map; /** * Implementation of the AndroidProject model object. @@ -46,28 +45,32 @@ class DefaultAndroidProject implements AndroidProject, Serializable { @NonNull private final String compileTarget; @NonNull - private final List<String> bootClasspath; + private final Collection<String> bootClasspath; @NonNull - private final List<File> frameworkSource; + private final Collection<File> frameworkSource; @NonNull - private final Map<String, SigningConfig> signingConfigs; + private final Collection<SigningConfig> signingConfigs; + @NonNull + private final Collection<ArtifactMetaData> extraArtifacts; @NonNull private final Collection<String> unresolvedDependencies; @NonNull private final JavaCompileOptions javaCompileOptions; private final boolean isLibrary; - private final Map<String, BuildTypeContainer> buildTypes = Maps.newHashMap(); - private final Map<String, ProductFlavorContainer> productFlavors = Maps.newHashMap(); - private final Map<String, Variant> variants = Maps.newHashMap(); + private final Collection<BuildTypeContainer> buildTypes = Lists.newArrayList(); + private final Collection<ProductFlavorContainer> productFlavors = Lists.newArrayList(); + private final Collection<Variant> variants = Lists.newArrayList(); private ProductFlavorContainer defaultConfig; DefaultAndroidProject(@NonNull String modelVersion, - @NonNull String name, @NonNull String compileTarget, - @NonNull List<String> bootClasspath, - @NonNull List<File> frameworkSource, - @NonNull Map<String, SigningConfig> signingConfigs, + @NonNull String name, + @NonNull String compileTarget, + @NonNull Collection<String> bootClasspath, + @NonNull Collection<File> frameworkSource, + @NonNull Collection<SigningConfig> signingConfigs, + @NonNull Collection<ArtifactMetaData> extraArtifacts, @NonNull Collection<String> unresolvedDependencies, @NonNull CompileOptions compileOptions, boolean isLibrary) { @@ -77,6 +80,7 @@ class DefaultAndroidProject implements AndroidProject, Serializable { this.bootClasspath = bootClasspath; this.frameworkSource = frameworkSource; this.signingConfigs = signingConfigs; + this.extraArtifacts = extraArtifacts; this.unresolvedDependencies = unresolvedDependencies; javaCompileOptions = new DefaultJavaCompileOptions(compileOptions); this.isLibrary = isLibrary; @@ -90,26 +94,25 @@ class DefaultAndroidProject implements AndroidProject, Serializable { @NonNull DefaultAndroidProject addBuildType(@NonNull BuildTypeContainer buildTypeContainer) { - buildTypes.put(buildTypeContainer.getBuildType().getName(), buildTypeContainer); + buildTypes.add(buildTypeContainer); return this; } @NonNull DefaultAndroidProject addProductFlavors( @NonNull ProductFlavorContainer productFlavorContainer) { - productFlavors.put(productFlavorContainer.getProductFlavor().getName(), - productFlavorContainer); + productFlavors.add(productFlavorContainer); return this; } @NonNull DefaultAndroidProject addVariant(@NonNull VariantImpl variant) { - variants.put(variant.getName(), variant); + variants.add(variant); return this; } - @NonNull @Override + @NonNull public String getModelVersion() { return modelVersion; } @@ -120,72 +123,79 @@ class DefaultAndroidProject implements AndroidProject, Serializable { return name; } - @NonNull @Override + @NonNull public ProductFlavorContainer getDefaultConfig() { return defaultConfig; } - @NonNull @Override - public Map<String, BuildTypeContainer> getBuildTypes() { + @NonNull + public Collection<BuildTypeContainer> getBuildTypes() { return buildTypes; } - @NonNull @Override - public Map<String, ProductFlavorContainer> getProductFlavors() { + @NonNull + public Collection<ProductFlavorContainer> getProductFlavors() { return productFlavors; } - @NonNull @Override - public Map<String, Variant> getVariants() { + @NonNull + public Collection<Variant> getVariants() { return variants; } + @NonNull + @Override + public Collection<ArtifactMetaData> getExtraArtifacts() { + return extraArtifacts; + } + @Override public boolean isLibrary() { return isLibrary; } - @NonNull @Override + @NonNull public String getCompileTarget() { return compileTarget; } - @NonNull @Override - public List<String> getBootClasspath() { + @NonNull + public Collection<String> getBootClasspath() { return bootClasspath; } @Override - public List<File> getFrameworkSource() { + @NonNull + public Collection<File> getFrameworkSources() { return frameworkSource; } - @NonNull @Override - public Map<String,SigningConfig> getSigningConfigs() { + @NonNull + public Collection<SigningConfig> getSigningConfigs() { return signingConfigs; } - @NonNull @Override + @NonNull public AaptOptions getAaptOptions() { return null; } - @NonNull @Override + @NonNull public Collection<String> getUnresolvedDependencies() { return unresolvedDependencies; } - @NonNull @Override + @NonNull public JavaCompileOptions getJavaCompileOptions() { return javaCompileOptions; } diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/model/JavaArtifactImpl.java b/gradle/src/main/groovy/com/android/build/gradle/internal/model/JavaArtifactImpl.java new file mode 100644 index 0000000..4c7584c --- /dev/null +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/model/JavaArtifactImpl.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2013 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.internal.model; + +import com.android.annotations.NonNull; +import com.android.annotations.Nullable; +import com.android.builder.model.Dependencies; +import com.android.builder.model.JavaArtifact; +import com.android.builder.model.SourceProvider; + +import java.io.File; +import java.io.Serializable; + +/** + * Implementation of JavaArtifact that is serializable + */ +public class JavaArtifactImpl extends BaseArtifactImpl implements JavaArtifact, Serializable { + private static final long serialVersionUID = 1L; + + public static JavaArtifactImpl clone(@NonNull JavaArtifact javaArtifact) { + return new JavaArtifactImpl( + javaArtifact.getName(), + javaArtifact.getAssembleTaskName(), + javaArtifact.getJavaCompileTaskName(), + javaArtifact.getClassesFolder(), + javaArtifact.getDependencies(), // TODO:FixME + SourceProviderImpl.cloneProvider(javaArtifact.getVariantSourceProvider()), + SourceProviderImpl.cloneProvider(javaArtifact.getMultiFlavorSourceProvider())); + } + + public JavaArtifactImpl(@NonNull String name, + @NonNull String assembleTaskName, + @NonNull String javaCompileTaskName, + @NonNull File classesFolder, + @NonNull Dependencies dependencies, + @Nullable SourceProvider variantSourceProvider, + @Nullable SourceProvider multiFlavorSourceProviders) { + super(name, assembleTaskName, javaCompileTaskName, classesFolder, dependencies, + variantSourceProvider, multiFlavorSourceProviders); + } +} diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/model/ModelBuilder.groovy b/gradle/src/main/groovy/com/android/build/gradle/internal/model/ModelBuilder.groovy index c3ede88..9bf6c46 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/internal/model/ModelBuilder.groovy +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/model/ModelBuilder.groovy @@ -26,23 +26,27 @@ import com.android.build.gradle.internal.variant.ApplicationVariantData import com.android.build.gradle.internal.variant.BaseVariantData import com.android.build.gradle.internal.variant.LibraryVariantData import com.android.build.gradle.internal.variant.TestVariantData -import com.android.builder.model.AndroidProject -import com.android.builder.model.ArtifactInfo -import com.android.builder.model.BuildTypeContainer -import com.android.builder.model.ProductFlavorContainer import com.android.builder.DefaultProductFlavor import com.android.builder.SdkParser import com.android.builder.VariantConfiguration +import com.android.builder.model.AndroidArtifact +import com.android.builder.model.AndroidProject +import com.android.builder.model.ArtifactMetaData +import com.android.builder.model.JavaArtifact import com.android.builder.model.SigningConfig import com.android.builder.model.SourceProvider +import com.android.builder.model.SourceProviderContainer import com.google.common.collect.Lists -import com.google.common.collect.Maps import org.gradle.api.Project import org.gradle.api.plugins.UnknownPluginException import org.gradle.tooling.provider.model.ToolingModelBuilder import java.util.jar.Attributes import java.util.jar.Manifest + +import static com.android.builder.model.AndroidProject.ARTIFACT_INSTRUMENT_TEST +import static com.android.builder.model.AndroidProject.ARTIFACT_MAIN + /** * Builder for the custom Android model. */ @@ -81,6 +85,15 @@ public class ModelBuilder implements ToolingModelBuilder { List<File> frameworkSource = Collections.emptyList(); String compileTarget = sdkParser.target.hashString() + // list of extra artifacts + List<ArtifactMetaData> artifactMetaDataList = Lists.newArrayList(basePlugin.extraArtifacts) + // plus the instrumentation test one. + artifactMetaDataList.add( + new ArtifactMetaDataImpl( + ARTIFACT_INSTRUMENT_TEST, + true /*isTest*/, + ArtifactMetaData.TYPE_ANDROID)); + //noinspection GroovyVariableNotAssigned DefaultAndroidProject androidProject = new DefaultAndroidProject( getModelVersion(), @@ -89,29 +102,40 @@ public class ModelBuilder implements ToolingModelBuilder { bootClasspath, frameworkSource, cloneSigningConfigs(signingConfigs), + artifactMetaDataList, basePlugin.unresolvedDependencies, basePlugin.extension.compileOptions, libPlugin != null) - .setDefaultConfig(createPFC(basePlugin.defaultConfigData)) + .setDefaultConfig(ProductFlavorContainerImpl.createPFC( + basePlugin.defaultConfigData, + basePlugin.getExtraFlavorSourceProviders(basePlugin.defaultConfigData.productFlavor.name))) if (appPlugin != null) { for (BuildTypeData btData : appPlugin.buildTypes.values()) { - androidProject.addBuildType(createBTC(btData)) + androidProject.addBuildType(BuildTypeContainerImpl.createBTC( + btData, + basePlugin.getExtraBuildTypeSourceProviders(btData.buildType.name))) } for (ProductFlavorData pfData : appPlugin.productFlavors.values()) { - androidProject.addProductFlavors(createPFC(pfData)) + androidProject.addProductFlavors(ProductFlavorContainerImpl.createPFC( + pfData, + basePlugin.getExtraFlavorSourceProviders(pfData.productFlavor.name))) } } else if (libPlugin != null) { - androidProject.addBuildType(createBTC(libPlugin.debugBuildTypeData)) - .addBuildType(createBTC(libPlugin.releaseBuildTypeData)) + androidProject.addBuildType(BuildTypeContainerImpl.createBTC( + libPlugin.debugBuildTypeData, + basePlugin.getExtraBuildTypeSourceProviders(libPlugin.debugBuildTypeData.buildType.name))) + .addBuildType(BuildTypeContainerImpl.createBTC( + libPlugin.releaseBuildTypeData, + basePlugin.getExtraBuildTypeSourceProviders(libPlugin.releaseBuildTypeData.buildType.name))) } Set<Project> gradleProjects = project.getRootProject().getAllprojects(); for (BaseVariantData variantData : basePlugin.variantDataList) { if (!(variantData instanceof TestVariantData)) { - androidProject.addVariant(createVariant(variantData, gradleProjects)) + androidProject.addVariant(createVariant(variantData, basePlugin, gradleProjects)) } } @@ -141,6 +165,7 @@ public class ModelBuilder implements ToolingModelBuilder { @NonNull private static VariantImpl createVariant(@NonNull BaseVariantData variantData, + @NonNull BasePlugin basePlugin, @NonNull Set<Project> gradleProjects) { TestVariantData testVariantData = null if (variantData instanceof ApplicationVariantData || @@ -148,30 +173,43 @@ public class ModelBuilder implements ToolingModelBuilder { testVariantData = variantData.testVariantData } - ArtifactInfo mainArtifact = createArtifactInfo(variantData, gradleProjects) - ArtifactInfo testArtifact = testVariantData != null ? - createArtifactInfo(testVariantData, gradleProjects) : null + AndroidArtifact mainArtifact = createArtifactInfo( + ARTIFACT_MAIN, variantData, basePlugin, gradleProjects) + + String variantName = variantData.variantConfiguration.fullName + + // extra Android Artifacts + AndroidArtifact testArtifact = testVariantData != null ? + createArtifactInfo(ARTIFACT_INSTRUMENT_TEST, testVariantData, basePlugin, gradleProjects) : null - SourceProvider sp = variantData.variantConfiguration.getVariantSourceProvider(); - if (sp != null) { - sp = SourceProviderImpl.cloneProvider(sp); + List<AndroidArtifact> extraAndroidArtifacts = Lists.newArrayList( + basePlugin.getExtraAndroidArtifacts(variantName)) + if (testArtifact != null) { + extraAndroidArtifacts.add(testArtifact) } + // extra Java Artifacts + List<JavaArtifact> extraJavaArtifacts = Lists.newArrayList( + basePlugin.getExtraJavaArtifacts(variantName)) + VariantImpl variant = new VariantImpl( - variantData.variantConfiguration.fullName, + variantName, variantData.variantConfiguration.baseName, variantData.variantConfiguration.buildType.name, getProductFlavorNames(variantData), ProductFlavorImpl.cloneFlavor(variantData.variantConfiguration.mergedFlavor), mainArtifact, - testArtifact, - sp) + extraAndroidArtifacts, + extraJavaArtifacts) return variant } - private static ArtifactInfo createArtifactInfo(@NonNull BaseVariantData variantData, - @NonNull Set<Project> gradleProjects) { + private static AndroidArtifact createArtifactInfo( + @NonNull String name, + @NonNull BaseVariantData variantData, + @NonNull BasePlugin basePlugin, + @NonNull Set<Project> gradleProjects) { VariantConfiguration vC = variantData.variantConfiguration SigningConfig signingConfig = vC.signingConfig @@ -180,7 +218,26 @@ public class ModelBuilder implements ToolingModelBuilder { signingConfigName = signingConfig.name } - return new ArtifactInfoImpl( + SourceProvider variantSourceProvider = null; + SourceProvider multiFlavorSourceProvider = null; + + if (ARTIFACT_MAIN.equals(name)) { + variantSourceProvider = variantData.variantConfiguration.variantSourceProvider + multiFlavorSourceProvider = variantData.variantConfiguration.multiFlavorSourceProvider + } else { + SourceProviderContainer container = getSourceProviderContainer( + basePlugin.getExtraVariantSourceProviders(variantData.getVariantConfiguration().getFullName()), + name) + if (container != null) { + variantSourceProvider = container.sourceProvider + } + } + + variantSourceProvider = variantSourceProvider != null ? SourceProviderImpl.cloneProvider(variantSourceProvider) : null + multiFlavorSourceProvider = multiFlavorSourceProvider != null ? SourceProviderImpl.cloneProvider(multiFlavorSourceProvider) : null + + return new AndroidArtifactImpl( + name, variantData.assembleTask.name, variantData.outputFile, vC.isSigningReady(), @@ -192,8 +249,9 @@ public class ModelBuilder implements ToolingModelBuilder { getGeneratedSourceFolders(variantData), getGeneratedResourceFolders(variantData), variantData.javaCompileTask.destinationDir, - DependenciesImpl.cloneDependencies(variantData.variantDependency, gradleProjects) - ) + DependenciesImpl.cloneDependencies(variantData.variantDependency, gradleProjects), + variantSourceProvider, + multiFlavorSourceProvider) } @NonNull @@ -237,54 +295,29 @@ public class ModelBuilder implements ToolingModelBuilder { return Collections.singletonList(variantData.renderscriptCompileTask.resOutputDir) } - /** - * Create a ProductFlavorContainer from a ProductFlavorData - * @param productFlavorData the product flavor data - * @return a non-null ProductFlavorContainer - */ - @NonNull - private static ProductFlavorContainer createPFC(@NonNull ProductFlavorData productFlavorData) { - return new ProductFlavorContainerImpl( - ProductFlavorImpl.cloneFlavor(productFlavorData.productFlavor), - SourceProviderImpl.cloneProvider((SourceProvider) productFlavorData.sourceSet), - SourceProviderImpl.cloneProvider((SourceProvider) productFlavorData.testSourceSet)) - } - - /** - * Create a BuildTypeContainer from a BuildTypeData - * @param buildTypeData the build type data - * @return a non-null BuildTypeContainer - */ @NonNull - private static BuildTypeContainer createBTC(@NonNull BuildTypeData buildTypeData) { - return new BuildTypeContainerImpl( - BuildTypeImpl.cloneBuildType(buildTypeData.buildType), - SourceProviderImpl.cloneProvider((SourceProvider) buildTypeData.sourceSet)) - } - - @NonNull - private static Map<String, SigningConfig> cloneSigningConfigs( + private static Collection<SigningConfig> cloneSigningConfigs( @NonNull Collection<SigningConfig> signingConfigs) { - Map<String, SigningConfig> results = Maps.newHashMapWithExpectedSize(signingConfigs.size()) + Collection<SigningConfig> results = Lists.newArrayListWithCapacity(signingConfigs.size()) for (SigningConfig signingConfig : signingConfigs) { - SigningConfig clonedSigningConfig = createSigningConfig(signingConfig) - results.put(clonedSigningConfig.name, clonedSigningConfig) + results.add(SigningConfigImpl.createSigningConfig(signingConfig)) } return results } - @NonNull - private static SigningConfig createSigningConfig(@NonNull SigningConfig signingConfig) { - return new SigningConfigImpl( - signingConfig.getName(), - signingConfig.getStoreFile(), - signingConfig.getStorePassword(), - signingConfig.getKeyAlias(), - signingConfig.getKeyPassword(), - signingConfig.getStoreType(), - signingConfig.isSigningReady()) + @Nullable + private static SourceProviderContainer getSourceProviderContainer( + @NonNull Collection<SourceProviderContainer> items, + @NonNull String name) { + for (SourceProviderContainer item : items) { + if (name.equals(item.getArtifactName())) { + return item; + } + } + + return null; } /** diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/model/ProductFlavorContainerImpl.java b/gradle/src/main/groovy/com/android/build/gradle/internal/model/ProductFlavorContainerImpl.java index dac38e6..92fa794 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/internal/model/ProductFlavorContainerImpl.java +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/model/ProductFlavorContainerImpl.java @@ -17,11 +17,16 @@ package com.android.build.gradle.internal.model; import com.android.annotations.NonNull; -import com.android.builder.model.ProductFlavorContainer; +import com.android.build.gradle.internal.ProductFlavorData; +import com.android.builder.model.AndroidProject; import com.android.builder.model.ProductFlavor; +import com.android.builder.model.ProductFlavorContainer; import com.android.builder.model.SourceProvider; +import com.android.builder.model.SourceProviderContainer; import java.io.Serializable; +import java.util.Collection; +import java.util.List; /** */ @@ -33,15 +38,43 @@ class ProductFlavorContainerImpl implements ProductFlavorContainer, Serializable @NonNull private final SourceProvider sourceProvider; @NonNull - private final SourceProvider testSourceProvider; + private final Collection<SourceProviderContainer> extraSourceProviders; + + /** + * Create a ProductFlavorContainer from a ProductFlavorData + * + * @param productFlavorData the product flavor data + * @param sourceProviderContainers collection of extra source providers + * + * @return a non-null ProductFlavorContainer + */ + @NonNull + static ProductFlavorContainer createPFC( + @NonNull ProductFlavorData productFlavorData, + @NonNull Collection<SourceProviderContainer> sourceProviderContainers) { + + List<SourceProviderContainer> clonedContainer = SourceProviderContainerImpl.cloneCollection(sourceProviderContainers); + + // instrument test Source Provider + SourceProviderContainer testASP = SourceProviderContainerImpl.create( + AndroidProject.ARTIFACT_INSTRUMENT_TEST, productFlavorData.getTestSourceSet()); + + clonedContainer.add(testASP); + + return new ProductFlavorContainerImpl( + ProductFlavorImpl.cloneFlavor(productFlavorData.getProductFlavor()), + SourceProviderImpl.cloneProvider(productFlavorData.getSourceSet()), + clonedContainer); + } - ProductFlavorContainerImpl(@NonNull ProductFlavorImpl productFlavor, - @NonNull SourceProviderImpl sourceProvider, - @NonNull SourceProviderImpl testSourceProvider) { + private ProductFlavorContainerImpl( + @NonNull ProductFlavorImpl productFlavor, + @NonNull SourceProviderImpl sourceProvider, + @NonNull Collection<SourceProviderContainer> extraSourceProviders) { this.productFlavor = productFlavor; this.sourceProvider = sourceProvider; - this.testSourceProvider = testSourceProvider; + this.extraSourceProviders = extraSourceProviders; } @NonNull @@ -58,7 +91,7 @@ class ProductFlavorContainerImpl implements ProductFlavorContainer, Serializable @NonNull @Override - public SourceProvider getTestSourceProvider() { - return testSourceProvider; + public Collection<SourceProviderContainer> getExtraSourceProviders() { + return extraSourceProviders; } } diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/model/ProductFlavorImpl.java b/gradle/src/main/groovy/com/android/build/gradle/internal/model/ProductFlavorImpl.java index 8380ae3..cc7aad6 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/internal/model/ProductFlavorImpl.java +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/model/ProductFlavorImpl.java @@ -18,8 +18,8 @@ package com.android.build.gradle.internal.model; import com.android.annotations.NonNull; import com.android.annotations.Nullable; -import com.android.builder.NdkConfig; import com.android.builder.model.ClassField; +import com.android.builder.model.NdkConfig; import com.android.builder.model.ProductFlavor; import java.io.File; @@ -182,5 +182,4 @@ class ProductFlavorImpl implements ProductFlavor, Serializable { ", mTestFunctionalTest='" + mTestFunctionalTest + '\'' + '}'; } - } diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/model/SigningConfigImpl.java b/gradle/src/main/groovy/com/android/build/gradle/internal/model/SigningConfigImpl.java index 06e219c..19c867c 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/internal/model/SigningConfigImpl.java +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/model/SigningConfigImpl.java @@ -44,7 +44,19 @@ class SigningConfigImpl implements SigningConfig, Serializable { private final String storeType; private final boolean signingReady; - SigningConfigImpl(@NonNull String name, + @NonNull + static SigningConfig createSigningConfig(@NonNull SigningConfig signingConfig) { + return new SigningConfigImpl( + signingConfig.getName(), + signingConfig.getStoreFile(), + signingConfig.getStorePassword(), + signingConfig.getKeyAlias(), + signingConfig.getKeyPassword(), + signingConfig.getStoreType(), + signingConfig.isSigningReady()); + } + + private SigningConfigImpl(@NonNull String name, @Nullable File storeFile, @Nullable String storePassword, @Nullable String keyAlias, diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/model/SourceProviderContainerImpl.java b/gradle/src/main/groovy/com/android/build/gradle/internal/model/SourceProviderContainerImpl.java new file mode 100644 index 0000000..fe41180 --- /dev/null +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/model/SourceProviderContainerImpl.java @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2013 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.internal.model; + +import com.android.annotations.NonNull; +import com.android.builder.model.SourceProvider; +import com.android.builder.model.SourceProviderContainer; +import com.google.common.collect.Lists; + +import java.io.Serializable; +import java.util.Collection; +import java.util.List; + +/** + * Implementation of SourceProviderContainer that is serializable and is meant to be used + * in the model sent to the tooling API. + * + * It also provides convenient methods to create an instance, cloning the original + * SourceProvider. + * + * When the source Provider is cloned, its values are queried and then statically stored. + * Any further change through the DSL will not be impact. Therefore instances of this class + * should only be used when the model is built. + * + * To create more dynamic isntances of SourceProviderContainer, use + * {@link com.android.build.gradle.internal.variant.DefaultSourceProviderContainer} + */ +class SourceProviderContainerImpl implements SourceProviderContainer, Serializable { + private static final long serialVersionUID = 1L; + + @NonNull + private final String name; + @NonNull + private final SourceProvider sourceProvider; + + /** + * Create a {@link SourceProviderContainer} that is serializable to + * use in the model sent through the tooling API. + * + * @param sourceProviderContainer the source provider + * + * @return a non-null SourceProviderContainer + */ + @NonNull + static SourceProviderContainer clone( + @NonNull SourceProviderContainer sourceProviderContainer) { + return create( + sourceProviderContainer.getArtifactName(), + sourceProviderContainer.getSourceProvider()); + } + + @NonNull + static List<SourceProviderContainer> cloneCollection(@NonNull Collection<SourceProviderContainer> containers) { + List<SourceProviderContainer> clones = Lists.newArrayListWithCapacity(containers.size()); + + for (SourceProviderContainer container : containers) { + clones.add(clone(container)); + } + + return clones; + } + + @NonNull + static SourceProviderContainer create( + @NonNull String name, + @NonNull SourceProvider sourceProvider) { + return new SourceProviderContainerImpl(name, + SourceProviderImpl.cloneProvider(sourceProvider)); + } + + private SourceProviderContainerImpl(@NonNull String name, + @NonNull SourceProvider sourceProvider) { + this.name = name; + this.sourceProvider = sourceProvider; + } + + @NonNull + @Override + public String getArtifactName() { + return name; + } + + @NonNull + @Override + public SourceProvider getSourceProvider() { + return sourceProvider; + } +} diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/model/SourceProviderImpl.java b/gradle/src/main/groovy/com/android/build/gradle/internal/model/SourceProviderImpl.java index 7d0293b..de02737 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/internal/model/SourceProviderImpl.java +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/model/SourceProviderImpl.java @@ -18,10 +18,11 @@ package com.android.build.gradle.internal.model; import com.android.annotations.NonNull; import com.android.builder.model.SourceProvider; +import com.google.common.collect.Lists; import java.io.File; import java.io.Serializable; -import java.util.Set; +import java.util.Collection; /** * Implementation of SourceProvider that is serializable. Objects used in the DSL cannot be @@ -31,13 +32,13 @@ class SourceProviderImpl implements SourceProvider, Serializable { private static final long serialVersionUID = 1L; private File manifestFile; - private Set<File> javaDirs; - private Set<File> resourcesDirs; - private Set<File> aidlDirs; - private Set<File> rsDirs; - private Set<File> jniDirs; - private Set<File> resDirs; - private Set<File> assetsDirs; + private Collection<File> javaDirs; + private Collection<File> resourcesDirs; + private Collection<File> aidlDirs; + private Collection<File> rsDirs; + private Collection<File> jniDirs; + private Collection<File> resDirs; + private Collection<File> assetsDirs; @NonNull static SourceProviderImpl cloneProvider(SourceProvider sourceProvider) { @@ -55,6 +56,17 @@ class SourceProviderImpl implements SourceProvider, Serializable { return sourceProviderClone; } + @NonNull + static Collection<SourceProvider> cloneCollection( + @NonNull Collection<SourceProvider> sourceProviders) { + Collection<SourceProvider> results = Lists.newArrayListWithCapacity(sourceProviders.size()); + for (SourceProvider sourceProvider : sourceProviders) { + results.add(SourceProviderImpl.cloneProvider(sourceProvider)); + } + + return results; + } + private SourceProviderImpl() { } @@ -66,43 +78,43 @@ class SourceProviderImpl implements SourceProvider, Serializable { @NonNull @Override - public Set<File> getJavaDirectories() { + public Collection<File> getJavaDirectories() { return javaDirs; } @NonNull @Override - public Set<File> getResourcesDirectories() { + public Collection<File> getResourcesDirectories() { return resourcesDirs; } @NonNull @Override - public Set<File> getAidlDirectories() { + public Collection<File> getAidlDirectories() { return aidlDirs; } @NonNull @Override - public Set<File> getRenderscriptDirectories() { + public Collection<File> getRenderscriptDirectories() { return rsDirs; } @NonNull @Override - public Set<File> getJniDirectories() { + public Collection<File> getJniDirectories() { return jniDirs; } @NonNull @Override - public Set<File> getResDirectories() { + public Collection<File> getResDirectories() { return resDirs; } @NonNull @Override - public Set<File> getAssetsDirectories() { + public Collection<File> getAssetsDirectories() { return assetsDirs; } diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/model/VariantImpl.java b/gradle/src/main/groovy/com/android/build/gradle/internal/model/VariantImpl.java index 2baef84..c15f480 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/internal/model/VariantImpl.java +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/model/VariantImpl.java @@ -17,13 +17,13 @@ package com.android.build.gradle.internal.model; import com.android.annotations.NonNull; -import com.android.annotations.Nullable; -import com.android.builder.model.ArtifactInfo; -import com.android.builder.model.SourceProvider; -import com.android.builder.model.Variant; +import com.android.builder.model.AndroidArtifact; +import com.android.builder.model.JavaArtifact; import com.android.builder.model.ProductFlavor; +import com.android.builder.model.Variant; import java.io.Serializable; +import java.util.Collection; import java.util.Collections; import java.util.List; @@ -44,28 +44,28 @@ class VariantImpl implements Variant, Serializable { @NonNull private final ProductFlavor mergedFlavor; @NonNull - private final ArtifactInfo mainArtifactInfo; - @Nullable - private final ArtifactInfo testArtifactInfo; - @Nullable - private final SourceProvider variantSourceProvider; + private final AndroidArtifact mainArtifactInfo; + @NonNull + private final Collection<AndroidArtifact> extraAndroidArtifacts; + @NonNull + private final Collection<JavaArtifact> extraJavaArtifacts; - VariantImpl(@NonNull String name, - @NonNull String displayName, - @NonNull String buildTypeName, - @NonNull List<String> productFlavorNames, - @NonNull ProductFlavorImpl mergedFlavor, - @NonNull ArtifactInfo mainArtifactInfo, - @Nullable ArtifactInfo testArtifactInfo, - @Nullable SourceProvider variantSourceProvider) { + VariantImpl(@NonNull String name, + @NonNull String displayName, + @NonNull String buildTypeName, + @NonNull List<String> productFlavorNames, + @NonNull ProductFlavorImpl mergedFlavor, + @NonNull AndroidArtifact mainArtifactInfo, + @NonNull Collection<AndroidArtifact> extraAndroidArtifacts, + @NonNull Collection<JavaArtifact> extraJavaArtifacts) { this.name = name; this.displayName = displayName; this.buildTypeName = buildTypeName; this.productFlavorNames = productFlavorNames; this.mergedFlavor = mergedFlavor; this.mainArtifactInfo = mainArtifactInfo; - this.testArtifactInfo = testArtifactInfo; - this.variantSourceProvider = variantSourceProvider; + this.extraAndroidArtifacts = extraAndroidArtifacts; + this.extraJavaArtifacts = extraJavaArtifacts; } @Override @@ -100,25 +100,25 @@ class VariantImpl implements Variant, Serializable { @NonNull @Override - public ArtifactInfo getMainArtifactInfo() { + public AndroidArtifact getMainArtifact() { return mainArtifactInfo; } - @Nullable + @NonNull @Override - public ArtifactInfo getTestArtifactInfo() { - return testArtifactInfo; + public Collection<AndroidArtifact> getExtraAndroidArtifacts() { + return extraAndroidArtifacts; } - @Override @NonNull - public List<String> getResourceConfigurations() { - return Collections.emptyList(); + @Override + public Collection<JavaArtifact> getExtraJavaArtifacts() { + return extraJavaArtifacts; } @Override - @Nullable - public SourceProvider getSourceProvider() { - return variantSourceProvider; + @NonNull + public List<String> getResourceConfigurations() { + return Collections.emptyList(); } } diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/tasks/NdkTask.groovy b/gradle/src/main/groovy/com/android/build/gradle/internal/tasks/NdkTask.groovy index 05c56d8..ba48552 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/internal/tasks/NdkTask.groovy +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/tasks/NdkTask.groovy @@ -15,7 +15,8 @@ */ package com.android.build.gradle.internal.tasks -import com.android.builder.NdkConfig + +import com.android.builder.model.NdkConfig import org.gradle.api.tasks.Input import org.gradle.api.tasks.Optional diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/variant/DefaultSourceProviderContainer.java b/gradle/src/main/groovy/com/android/build/gradle/internal/variant/DefaultSourceProviderContainer.java new file mode 100644 index 0000000..06f2e5f --- /dev/null +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/variant/DefaultSourceProviderContainer.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2013 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.internal.variant; + +import com.android.annotations.NonNull; +import com.android.builder.model.SourceProvider; +import com.android.builder.model.SourceProviderContainer; + +/** + * Default implementation of a SourceProviderContainer that wraps an existing instance of a + * SourceProvider. + */ +public class DefaultSourceProviderContainer implements SourceProviderContainer { + + @NonNull + private final String name; + @NonNull + private final SourceProvider sourceProvider; + + public DefaultSourceProviderContainer(@NonNull String name, + @NonNull SourceProvider sourceProvider) { + this.name = name; + this.sourceProvider = sourceProvider; + } + + @NonNull + @Override + public String getArtifactName() { + return name; + } + + @NonNull + @Override + public SourceProvider getSourceProvider() { + return sourceProvider; + } +} diff --git a/gradle/src/main/groovy/com/android/build/gradle/tasks/Lint.groovy b/gradle/src/main/groovy/com/android/build/gradle/tasks/Lint.groovy index 2c756ce..e9e38b5 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/tasks/Lint.groovy +++ b/gradle/src/main/groovy/com/android/build/gradle/tasks/Lint.groovy @@ -37,9 +37,9 @@ public class Lint extends DefaultTask { @Nullable private File mConfigFile @Nullable private File mHtmlOutput @Nullable private File mXmlOutput - @Nullable private List<Set<File>> mSourceSets + @Nullable private List<Collection<File>> mSourceSets @Nullable private String mClassPath - @Nullable private List<Set<File>> mResourceSets + @Nullable private List<Collection<File>> mResourceSets private boolean mQuiet public void setPlugin(@NonNull BasePlugin plugin) { @@ -74,7 +74,7 @@ public class Lint extends DefaultTask { * * @param sourceSets files to be added to sources. */ - public void setSources(@NonNull List<Set<File>> sourceSets) { + public void setSources(@NonNull List<Collection<File>> sourceSets) { mSourceSets = sourceSets } @@ -164,7 +164,7 @@ public class Lint extends DefaultTask { // Flags: sources, resources, classes - for (Set<File> args : mSourceSets) { + for (Collection<File> args : mSourceSets) { for (File input : args) { if (input.exists()) { List<File> sources = flags.getSourcesOverride() @@ -190,7 +190,7 @@ public class Lint extends DefaultTask { classes.add(input); } - for (Set<File> args : mResourceSets) { + for (Collection<File> args : mResourceSets) { for (File input : args) { if (input.exists()) { List<File> resources = flags.getResourcesOverride() diff --git a/gradle/src/main/groovy/com/android/build/gradle/tasks/NdkCompile.groovy b/gradle/src/main/groovy/com/android/build/gradle/tasks/NdkCompile.groovy index d2a34d5..4526371 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/tasks/NdkCompile.groovy +++ b/gradle/src/main/groovy/com/android/build/gradle/tasks/NdkCompile.groovy @@ -18,7 +18,7 @@ package com.android.build.gradle.tasks import com.android.annotations.NonNull import com.android.build.gradle.internal.tasks.NdkTask -import com.android.builder.NdkConfig +import com.android.builder.model.NdkConfig import com.android.sdklib.IAndroidTarget import com.google.common.base.Charsets import com.google.common.base.Joiner diff --git a/tests/artifactApi/build.gradle b/tests/artifactApi/build.gradle new file mode 100644 index 0000000..be18382 --- /dev/null +++ b/tests/artifactApi/build.gradle @@ -0,0 +1,105 @@ +buildscript { + repositories { + maven { url '../../../../out/host/gradle/repo' } + } + dependencies { + classpath 'com.android.tools.build:gradle:0.7.0-SNAPSHOT' + } +} + +apply plugin: 'android' + +import com.android.builder.model.ArtifactMetaData +import com.android.builder.model.SourceProvider + +android.registerArtifactType("__test__", false, ArtifactMetaData.TYPE_JAVA) + +android.buildTypes.all { type -> + project.android.registerBuildTypeSourceProvider("__test__", type, getProvider("buildType:$type.name")) +} + +android.productFlavors.all { flavor -> + project.android.registerProductFlavorSourceProvider("__test__", flavor, getProvider("productFlavor:$flavor.name")) +} + +android.applicationVariants.all { variant -> + project.android.registerJavaArtifact( + "__test__", + variant, + "assemble:$variant.name", + "compile:$variant.name", + new File("classesFolder:$variant.name"), + getProvider("provider:$variant.name")) +} + +android { + compileSdkVersion 15 + buildToolsVersion "18.0.1" + + flavorGroups "pricing", "releaseType" + + productFlavors { + + beta { + flavorGroup "releaseType" + } + + normal { + flavorGroup "releaseType" + } + + free { + flavorGroup "pricing" + } + + paid { + flavorGroup "pricing" + } + } +} + +public class SourceProviderImpl implements SourceProvider, Serializable { + private static final long serialVersionUID = 1L; + + private final String name; + + SourceProviderImpl(String name) { + this.name = name + } + + File getManifestFile() { + return new File(name) + } + + Collection<File> getJavaDirectories() { + return Collections.emptyList() + } + + Collection<File> getResourcesDirectories() { + return Collections.emptyList() + } + + Collection<File> getAidlDirectories() { + return Collections.emptyList() + } + + Collection<File> getRenderscriptDirectories() { + return Collections.emptyList() + } + + Collection<File> getJniDirectories() { + return Collections.emptyList() + } + + Collection<File> getResDirectories() { + return Collections.emptyList() + } + + Collection<File> getAssetsDirectories() { + return Collections.emptyList() + } +} + +SourceProvider getProvider(String name) { + return new SourceProviderImpl(name) +}
\ No newline at end of file diff --git a/tests/artifactApi/src/main/AndroidManifest.xml b/tests/artifactApi/src/main/AndroidManifest.xml new file mode 100644 index 0000000..1c35a5b --- /dev/null +++ b/tests/artifactApi/src/main/AndroidManifest.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.tests.overlay2"> + <application android:label="@string/app_name" android:icon="@drawable/icon"> + <activity android:name=".Main" + android:label="@string/app_name"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/tests/artifactApi/src/main/java/com/android/tests/overlay2/Main.java b/tests/artifactApi/src/main/java/com/android/tests/overlay2/Main.java new file mode 100644 index 0000000..e8a0a83 --- /dev/null +++ b/tests/artifactApi/src/main/java/com/android/tests/overlay2/Main.java @@ -0,0 +1,15 @@ +package com.android.tests.overlay2; + +import android.app.Activity; +import android.os.Bundle; + +public class Main extends Activity +{ + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + setContentView(R.layout.main); + } +} diff --git a/tests/artifactApi/src/main/res/drawable/icon.png b/tests/artifactApi/src/main/res/drawable/icon.png Binary files differnew file mode 100644 index 0000000..a07c69f --- /dev/null +++ b/tests/artifactApi/src/main/res/drawable/icon.png diff --git a/tests/artifactApi/src/main/res/drawable/no_overlay.png b/tests/artifactApi/src/main/res/drawable/no_overlay.png Binary files differnew file mode 100644 index 0000000..47e1adf --- /dev/null +++ b/tests/artifactApi/src/main/res/drawable/no_overlay.png diff --git a/tests/artifactApi/src/main/res/layout/main.xml b/tests/artifactApi/src/main/res/layout/main.xml new file mode 100644 index 0000000..6cd0549 --- /dev/null +++ b/tests/artifactApi/src/main/res/layout/main.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + > + <ImageView + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:src="@drawable/no_overlay" + android:id="@+id/no_overlay" /> +</LinearLayout> + diff --git a/tests/artifactApi/src/main/res/values/strings.xml b/tests/artifactApi/src/main/res/values/strings.xml new file mode 100644 index 0000000..d1420e7 --- /dev/null +++ b/tests/artifactApi/src/main/res/values/strings.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="app_name">_Test-Overlay2</string> +</resources> diff --git a/tests/basicMultiFlavors/build.gradle b/tests/basicMultiFlavors/build.gradle new file mode 100644 index 0000000..d4bce43 --- /dev/null +++ b/tests/basicMultiFlavors/build.gradle @@ -0,0 +1,35 @@ +buildscript { + repositories { + maven { url '../../../../out/host/gradle/repo' } + } + dependencies { + classpath 'com.android.tools.build:gradle:0.7.0-SNAPSHOT' + } +} +apply plugin: 'android' + +android { + compileSdkVersion 15 + buildToolsVersion "18.0.1" + + flavorGroups "pricing", "releaseType" + + productFlavors { + + beta { + flavorGroup "releaseType" + } + + normal { + flavorGroup "releaseType" + } + + free { + flavorGroup "pricing" + } + + paid { + flavorGroup "pricing" + } + } +}
\ No newline at end of file diff --git a/tests/basicMultiFlavors/src/f1/res/values/strings.xml b/tests/basicMultiFlavors/src/f1/res/values/strings.xml new file mode 100644 index 0000000..7154c04 --- /dev/null +++ b/tests/basicMultiFlavors/src/f1/res/values/strings.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="app_name">_Test-Flavored-f1</string> + <string name="text">F1 text</string> +</resources> diff --git a/tests/basicMultiFlavors/src/f1Staging/res/values/strings.xml b/tests/basicMultiFlavors/src/f1Staging/res/values/strings.xml new file mode 100644 index 0000000..782422e --- /dev/null +++ b/tests/basicMultiFlavors/src/f1Staging/res/values/strings.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="text">F1-Staging text</string> +</resources> diff --git a/tests/basicMultiFlavors/src/f2/AndroidManifest.xml b/tests/basicMultiFlavors/src/f2/AndroidManifest.xml new file mode 100644 index 0000000..ce0bb8d --- /dev/null +++ b/tests/basicMultiFlavors/src/f2/AndroidManifest.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package=""> + <application> + <activity android:name="com.android.tests.flavored.OtherActivity" + android:label="@string/other_activity"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/tests/basicMultiFlavors/src/f2/java/com/android/tests/flavored/OtherActivity.java b/tests/basicMultiFlavors/src/f2/java/com/android/tests/flavored/OtherActivity.java new file mode 100644 index 0000000..6ffac9c --- /dev/null +++ b/tests/basicMultiFlavors/src/f2/java/com/android/tests/flavored/OtherActivity.java @@ -0,0 +1,15 @@ +package com.android.tests.flavored; + +import android.app.Activity; +import android.os.Bundle; + +public class OtherActivity extends Activity +{ + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + setContentView(R.layout.main2); + } +} diff --git a/tests/basicMultiFlavors/src/f2/res/layout/main2.xml b/tests/basicMultiFlavors/src/f2/res/layout/main2.xml new file mode 100644 index 0000000..90c3c43 --- /dev/null +++ b/tests/basicMultiFlavors/src/f2/res/layout/main2.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + > +<TextView + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:text="Test App - Flavored - f2" + android:id="@+id/text2" + /> +</LinearLayout> + diff --git a/tests/basicMultiFlavors/src/f2/res/values/strings.xml b/tests/basicMultiFlavors/src/f2/res/values/strings.xml new file mode 100644 index 0000000..bb53fd4 --- /dev/null +++ b/tests/basicMultiFlavors/src/f2/res/values/strings.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="app_name">_Test-Flavored-f2</string> + <string name="other_activity">_Test-f2-act2</string> +</resources> diff --git a/tests/basicMultiFlavors/src/main/AndroidManifest.xml b/tests/basicMultiFlavors/src/main/AndroidManifest.xml new file mode 100644 index 0000000..0d1c338 --- /dev/null +++ b/tests/basicMultiFlavors/src/main/AndroidManifest.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.tests.flavored"> + <application android:label="@string/app_name" android:icon="@drawable/icon"> + <activity android:name=".Main" + android:label="@string/app_name"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/tests/basicMultiFlavors/src/main/java/com/android/tests/flavored/Main.java b/tests/basicMultiFlavors/src/main/java/com/android/tests/flavored/Main.java new file mode 100644 index 0000000..26debd3 --- /dev/null +++ b/tests/basicMultiFlavors/src/main/java/com/android/tests/flavored/Main.java @@ -0,0 +1,15 @@ +package com.android.tests.flavored; + +import android.app.Activity; +import android.os.Bundle; + +public class Main extends Activity +{ + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + setContentView(R.layout.main); + } +} diff --git a/tests/basicMultiFlavors/src/main/res/drawable/icon.png b/tests/basicMultiFlavors/src/main/res/drawable/icon.png Binary files differnew file mode 100644 index 0000000..a07c69f --- /dev/null +++ b/tests/basicMultiFlavors/src/main/res/drawable/icon.png diff --git a/tests/basicMultiFlavors/src/main/res/layout/main.xml b/tests/basicMultiFlavors/src/main/res/layout/main.xml new file mode 100644 index 0000000..9d4e976 --- /dev/null +++ b/tests/basicMultiFlavors/src/main/res/layout/main.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + > +<TextView + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:text="@string/text" + android:id="@+id/text" + /> +</LinearLayout> + diff --git a/tests/basicMultiFlavors/src/main/res/values/strings.xml b/tests/basicMultiFlavors/src/main/res/values/strings.xml new file mode 100644 index 0000000..46d8260 --- /dev/null +++ b/tests/basicMultiFlavors/src/main/res/values/strings.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="app_name">###</string> + <string name="text">default text</string> +</resources> diff --git a/tests/overlay2/src/debug/res/drawable/variant_type_flavor_overlay.png b/tests/overlay2/src/debug/res/drawable/variant_type_flavor_overlay.png Binary files differnew file mode 100644 index 0000000..0e89381 --- /dev/null +++ b/tests/overlay2/src/debug/res/drawable/variant_type_flavor_overlay.png diff --git a/tests/overlay2/src/instrumentTest/java/com/android/tests/overlay2/MainTest.java b/tests/overlay2/src/instrumentTest/java/com/android/tests/overlay2/MainTest.java index 263cb76..364640d 100644 --- a/tests/overlay2/src/instrumentTest/java/com/android/tests/overlay2/MainTest.java +++ b/tests/overlay2/src/instrumentTest/java/com/android/tests/overlay2/MainTest.java @@ -15,6 +15,7 @@ public class MainTest extends ActivityInstrumentationTestCase2<Main> { private ImageView mTypeOverlayIV; private ImageView mFlavorOverlayIV; private ImageView mTypeFlavorOverlayIV; + private ImageView mVariantTypeFlavorOverlayIV; /** * Creates an {@link ActivityInstrumentationTestCase2} that tests the {@link Main} activity. @@ -33,6 +34,7 @@ public class MainTest extends ActivityInstrumentationTestCase2<Main> { mTypeOverlayIV = (ImageView) a.findViewById(R.id.type_overlay); mFlavorOverlayIV = (ImageView) a.findViewById(R.id.flavor_overlay); mTypeFlavorOverlayIV = (ImageView) a.findViewById(R.id.type_flavor_overlay); + mVariantTypeFlavorOverlayIV = (ImageView) a.findViewById(R.id.variant_type_flavor_overlay); } /** @@ -47,6 +49,7 @@ public class MainTest extends ActivityInstrumentationTestCase2<Main> { assertNotNull(mTypeOverlayIV); assertNotNull(mFlavorOverlayIV); assertNotNull(mTypeFlavorOverlayIV); + assertNotNull(mVariantTypeFlavorOverlayIV); } public void testNoOverlay() { @@ -64,6 +67,10 @@ public class MainTest extends ActivityInstrumentationTestCase2<Main> { public void testTypeFlavorOverlay() { pixelLooker(mTypeFlavorOverlayIV, GREEN); } + + public void testVariantTypeFlavorOverlay() { + pixelLooker(mVariantTypeFlavorOverlayIV, GREEN); + } private void pixelLooker(ImageView iv, int expectedColor) { BitmapDrawable d = (BitmapDrawable) iv.getDrawable(); diff --git a/tests/overlay2/src/main/res/drawable/variant_type_flavor_overlay.png b/tests/overlay2/src/main/res/drawable/variant_type_flavor_overlay.png Binary files differnew file mode 100644 index 0000000..b55e544 --- /dev/null +++ b/tests/overlay2/src/main/res/drawable/variant_type_flavor_overlay.png diff --git a/tests/overlay2/src/main/res/layout/main.xml b/tests/overlay2/src/main/res/layout/main.xml index 433f390..408c1f4 100644 --- a/tests/overlay2/src/main/res/layout/main.xml +++ b/tests/overlay2/src/main/res/layout/main.xml @@ -24,5 +24,10 @@ android:layout_height="wrap_content" android:src="@drawable/type_flavor_overlay" android:id="@+id/type_flavor_overlay" /> + <ImageView + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:src="@drawable/variant_type_flavor_overlay" + android:id="@+id/variant_type_flavor_overlay" /> </LinearLayout> diff --git a/tests/overlay2/src/one/res/drawable/type_flavor_overlay.png b/tests/overlay2/src/one/res/drawable/type_flavor_overlay.png Binary files differindex b55e544..0e89381 100644 --- a/tests/overlay2/src/one/res/drawable/type_flavor_overlay.png +++ b/tests/overlay2/src/one/res/drawable/type_flavor_overlay.png diff --git a/tests/overlay2/src/one/res/drawable/variant_type_flavor_overlay.png b/tests/overlay2/src/one/res/drawable/variant_type_flavor_overlay.png Binary files differnew file mode 100644 index 0000000..0e89381 --- /dev/null +++ b/tests/overlay2/src/one/res/drawable/variant_type_flavor_overlay.png diff --git a/tests/overlay2/src/oneDebug/res/drawable/variant_type_flavor_overlay.png b/tests/overlay2/src/oneDebug/res/drawable/variant_type_flavor_overlay.png Binary files differnew file mode 100644 index 0000000..47e1adf --- /dev/null +++ b/tests/overlay2/src/oneDebug/res/drawable/variant_type_flavor_overlay.png diff --git a/tests/overlay3/build.gradle b/tests/overlay3/build.gradle new file mode 100644 index 0000000..a0c7179 --- /dev/null +++ b/tests/overlay3/build.gradle @@ -0,0 +1,43 @@ +buildscript { + repositories { + maven { url '../../../../out/host/gradle/repo' } + } + dependencies { + classpath 'com.android.tools.build:gradle:0.7.0-SNAPSHOT' + } +} + +apply plugin: 'android' + +android { + compileSdkVersion 15 + buildToolsVersion "18.0.1" + + flavorGroups "pricing", "releaseType" + + sourceSets { + beta.setRoot('movedSrc/beta') + debug.setRoot('movedSrc/debug') + freeBetaDebug.setRoot('movedSrc/freeBetaDebug') + freeNormal.setRoot('movedSrc/freeNormal') + } + + productFlavors { + + beta { + flavorGroup "releaseType" + } + + normal { + flavorGroup "releaseType" + } + + free { + flavorGroup "pricing" + } + + paid { + flavorGroup "pricing" + } + } +}
\ No newline at end of file diff --git a/tests/overlay3/movedSrc/beta/res/drawable/beta_overlay.png b/tests/overlay3/movedSrc/beta/res/drawable/beta_overlay.png Binary files differnew file mode 100644 index 0000000..47e1adf --- /dev/null +++ b/tests/overlay3/movedSrc/beta/res/drawable/beta_overlay.png diff --git a/tests/overlay3/movedSrc/debug/res/drawable/debug_overlay.png b/tests/overlay3/movedSrc/debug/res/drawable/debug_overlay.png Binary files differnew file mode 100644 index 0000000..47e1adf --- /dev/null +++ b/tests/overlay3/movedSrc/debug/res/drawable/debug_overlay.png diff --git a/tests/overlay3/movedSrc/freeBetaDebug/res/drawable/free_beta_debug_overlay.png b/tests/overlay3/movedSrc/freeBetaDebug/res/drawable/free_beta_debug_overlay.png Binary files differnew file mode 100644 index 0000000..47e1adf --- /dev/null +++ b/tests/overlay3/movedSrc/freeBetaDebug/res/drawable/free_beta_debug_overlay.png diff --git a/tests/overlay3/movedSrc/freeNormal/res/drawable/free_normal_overlay.png b/tests/overlay3/movedSrc/freeNormal/res/drawable/free_normal_overlay.png Binary files differnew file mode 100644 index 0000000..47e1adf --- /dev/null +++ b/tests/overlay3/movedSrc/freeNormal/res/drawable/free_normal_overlay.png diff --git a/tests/overlay3/src/instrumentTest/java/com/android/tests/overlay2/MainTest.java b/tests/overlay3/src/instrumentTest/java/com/android/tests/overlay2/MainTest.java new file mode 100644 index 0000000..a4d6da1 --- /dev/null +++ b/tests/overlay3/src/instrumentTest/java/com/android/tests/overlay2/MainTest.java @@ -0,0 +1,98 @@ +package com.android.tests.overlay2; + +import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; +import android.test.ActivityInstrumentationTestCase2; +import android.test.suitebuilder.annotation.MediumTest; +import android.widget.ImageView; + + +public class MainTest extends ActivityInstrumentationTestCase2<Main> { + + private final static int RED = 0xFFFF0000; + private final static int GREEN = 0xFF00FF00; + + private ImageView mNoOverlayIV; + private ImageView mDebugOverlayIV; + private ImageView mBetaOverlayIV; + private ImageView mFreeNormalOverlayIV; + private ImageView mFreeBetaDebugOverlayIV; + + /** + * Creates an {@link ActivityInstrumentationTestCase2} that tests the {@link Main} activity. + */ + public MainTest() { + super(Main.class); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + final Main a = getActivity(); + // ensure a valid handle to the activity has been returned + assertNotNull(a); + mNoOverlayIV = (ImageView) a.findViewById(R.id.no_overlay); + mDebugOverlayIV = (ImageView) a.findViewById(R.id.debug_overlay); + mBetaOverlayIV = (ImageView) a.findViewById(R.id.beta_overlay); + mFreeNormalOverlayIV = (ImageView) a.findViewById(R.id.free_normal_overlay); + mFreeBetaDebugOverlayIV = (ImageView) a.findViewById(R.id.free_beta_debug_overlay); + } + + /** + * The name 'test preconditions' is a convention to signal that if this + * test doesn't pass, the test case was not set up properly and it might + * explain any and all failures in other tests. This is not guaranteed + * to run before other tests, as junit uses reflection to find the tests. + */ + @MediumTest + public void testPreconditions() { + assertNotNull(mNoOverlayIV); + assertNotNull(mDebugOverlayIV); + assertNotNull(mFreeBetaDebugOverlayIV); + assertNotNull(mFreeNormalOverlayIV); + assertNotNull(mFreeBetaDebugOverlayIV); + } + + public void testNoOverlay() { + pixelLooker(mNoOverlayIV, GREEN); + } + + public void testDebugOverlay() { + if ("debug".equals(BuildConfig.BUILD_TYPE)) { + pixelLooker(mDebugOverlayIV, GREEN); + } else { + pixelLooker(mDebugOverlayIV, RED); + } + } + + public void testBetaOverlay() { + if ("beta".equals(BuildConfig.FLAVOR2)) { + pixelLooker(mBetaOverlayIV, GREEN); + } else { + pixelLooker(mBetaOverlayIV, RED); + } + } + + public void testFreeNormalOverlay() { + if ("freeNormal".equals(BuildConfig.FLAVOR)) { + pixelLooker(mFreeNormalOverlayIV, GREEN); + } else { + pixelLooker(mFreeNormalOverlayIV, RED); + } + } + + public void testFreeBetaDebugOverlay() { + if ("freeBeta".equals(BuildConfig.FLAVOR) && "debug".equals(BuildConfig.BUILD_TYPE)) { + pixelLooker(mFreeBetaDebugOverlayIV, GREEN); + } else { + pixelLooker(mFreeBetaDebugOverlayIV, RED); + } + } + + private void pixelLooker(ImageView iv, int expectedColor) { + BitmapDrawable d = (BitmapDrawable) iv.getDrawable(); + Bitmap bitmap = d.getBitmap(); + assertEquals(expectedColor, bitmap.getPixel(0, 0)); + } +} + diff --git a/tests/overlay3/src/main/AndroidManifest.xml b/tests/overlay3/src/main/AndroidManifest.xml new file mode 100644 index 0000000..1c35a5b --- /dev/null +++ b/tests/overlay3/src/main/AndroidManifest.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.tests.overlay2"> + <application android:label="@string/app_name" android:icon="@drawable/icon"> + <activity android:name=".Main" + android:label="@string/app_name"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/tests/overlay3/src/main/java/com/android/tests/overlay2/Main.java b/tests/overlay3/src/main/java/com/android/tests/overlay2/Main.java new file mode 100644 index 0000000..e8a0a83 --- /dev/null +++ b/tests/overlay3/src/main/java/com/android/tests/overlay2/Main.java @@ -0,0 +1,15 @@ +package com.android.tests.overlay2; + +import android.app.Activity; +import android.os.Bundle; + +public class Main extends Activity +{ + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + setContentView(R.layout.main); + } +} diff --git a/tests/overlay3/src/main/res/drawable/beta_overlay.png b/tests/overlay3/src/main/res/drawable/beta_overlay.png Binary files differnew file mode 100644 index 0000000..b55e544 --- /dev/null +++ b/tests/overlay3/src/main/res/drawable/beta_overlay.png diff --git a/tests/overlay3/src/main/res/drawable/debug_overlay.png b/tests/overlay3/src/main/res/drawable/debug_overlay.png Binary files differnew file mode 100644 index 0000000..b55e544 --- /dev/null +++ b/tests/overlay3/src/main/res/drawable/debug_overlay.png diff --git a/tests/overlay3/src/main/res/drawable/free_beta_debug_overlay.png b/tests/overlay3/src/main/res/drawable/free_beta_debug_overlay.png Binary files differnew file mode 100644 index 0000000..b55e544 --- /dev/null +++ b/tests/overlay3/src/main/res/drawable/free_beta_debug_overlay.png diff --git a/tests/overlay3/src/main/res/drawable/free_normal_overlay.png b/tests/overlay3/src/main/res/drawable/free_normal_overlay.png Binary files differnew file mode 100644 index 0000000..b55e544 --- /dev/null +++ b/tests/overlay3/src/main/res/drawable/free_normal_overlay.png diff --git a/tests/overlay3/src/main/res/drawable/icon.png b/tests/overlay3/src/main/res/drawable/icon.png Binary files differnew file mode 100644 index 0000000..a07c69f --- /dev/null +++ b/tests/overlay3/src/main/res/drawable/icon.png diff --git a/tests/overlay3/src/main/res/drawable/no_overlay.png b/tests/overlay3/src/main/res/drawable/no_overlay.png Binary files differnew file mode 100644 index 0000000..47e1adf --- /dev/null +++ b/tests/overlay3/src/main/res/drawable/no_overlay.png diff --git a/tests/overlay3/src/main/res/layout/main.xml b/tests/overlay3/src/main/res/layout/main.xml new file mode 100644 index 0000000..1046827 --- /dev/null +++ b/tests/overlay3/src/main/res/layout/main.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + > + <ImageView + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:src="@drawable/no_overlay" + android:id="@+id/no_overlay" /> + <ImageView + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:src="@drawable/debug_overlay" + android:id="@+id/debug_overlay" /> + <ImageView + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:src="@drawable/beta_overlay" + android:id="@+id/beta_overlay" /> + <ImageView + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:src="@drawable/free_normal_overlay" + android:id="@+id/free_normal_overlay" /> + <ImageView + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:src="@drawable/free_beta_debug_overlay" + android:id="@+id/free_beta_debug_overlay" /> +</LinearLayout> + diff --git a/tests/overlay3/src/main/res/values/strings.xml b/tests/overlay3/src/main/res/values/strings.xml new file mode 100644 index 0000000..d1420e7 --- /dev/null +++ b/tests/overlay3/src/main/res/values/strings.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="app_name">_Test-Overlay2</string> +</resources> |